Profile
- Name
- Wiggle Lock Check v 2.0
- ID
- 39029
- Shared with
- Public
- Parent
- None
- Children
- None
- Created on
- March 17, 2012 at 19:02 PM UTC
- Updated on
- March 17, 2012 at 19:02 PM UTC
- Description
Pulls each segment against known locked segments and checks for a small change in score. Now with dialog.
Best for
Code
--[[
* Wiggle Lock Check
* Original Author: Brow42 2/29/2012
* Version 1.0 -- Puzzle 522b
* This performs a test for 'wiggle lock' as suggested by Rav3n, but
* automated here. For each segment that you want to test, that
* should *not* be locked, it draws a strength 10 band to a segment that
* is *known* to be locked. After a wiggle, the score will be almost
* exactly identical to what the score would have been if no band
* had been made, if the segment is 'wiggle locked'. At the end, a list
* of wiggle locked segments is printed.
*
* Strength 10 bands can make wiggle run a long time, so you can manual
* cancel each wiggle with 'space' after about 2 seconds. If you cancel
* too soon, though, that segment will show up as wiggle locked.
*
* Version 1.1 3/15/2012
*
* Changed defaults for 529
*
* Version 2.0 3/17/2012
*
* Changed to use a dialog interface
--]]
-- ================================== Begin New Dialog Library Functions
-- Add a wall of text from a table
function dialog.AddLabels(d,msg) -- need to manually pass in # of existing autolabels
nlabels = #d._Order -- unique starting index
if type(msg) == 'string' then
msg = { msg }
end
for i = 1,#msg do
d['autolabel'..tostring(i+nlabels)] = dialog.AddLabel(msg[i])
end
end
-- Create but don't display a wall of text and 1 or 2 buttons
function dialog.CreateMessageBox(msg,title,buttontext1,buttontext0)
title = title or ''
local d = dialog.CreateDialog(title)
dialog.AddLabels(d,msg)
buttontext1 = buttontext1 or 'Ok'
d.button = dialog.AddButton(buttontext1,1)
if buttontext0 ~= nil then d.button0 = dialog.AddButton(buttontext0,0) end
return d
end
-- Display a dialog box
function dialog.ShowMessageBox(msg,title,buttontext1,buttontext0)
return dialog.Show(dialog.CreateMessageBox(msg,title,buttontext1,buttontext0))
end
function ErrorMessage(msg)
print('Error',msg)
dialog.ShowMessageBox(msg,'Error')
end
function ParseRangeString(str)
local n = structure.GetCount()
local tab, r = {}, {}
for i in string.gfind(str,'-?%d+') do
i = tonumber(i)
local j = math.abs(i)
if j < 1 or j > n then ErrorMessage(string.format('Segment id %d is out of range 1 - %d',j,n)) return false end
if i < 0 then
if #r == 0 then ErrorMessage('Unexpected 2nd half of range without first half') return false end
tab[#tab+1] = { r[1], -i }
r = {}
else
if #r > 0 then tab[#tab+1] = r end
r = { i }
end
end
if #r > 0 then tab[#tab+1] = r end
return true, tab
end
-- ================================== Begin Main (Dialog)
d = dialog.CreateMessageBox(
{ 'This creates a band between segments you specify',
'and a known-locked segment. If it moves the same as',
'when there is no band, it\'s wiggle-locked.',
'Puzzle should be relaxed. Watch output window.',
'Remeber, you can can cancel wiggles after 2 seconds.',
''
},
'Wiggle Lock Check 2.0','Check','Exit')
d.locked = dialog.AddTextbox('Locked Segment #:','')
dialog.AddLabels(d,{
'If score changes more than this, it\'s not locked.',
'Smaller is more accurate here, but puzzle must be',
'relaxed to less than this.',''} )
d.fuzz = dialog.AddTextbox('Max Change:','1.0')
dialog.AddLabels(d,'Enter segments to test as #s or #-# ranges')
d.range = dialog.AddTextbox('Test Segments:','')
repeat
rc = dialog.Show(d)
if rc == 0 then break end
rc2, ranges = ParseRangeString(d.range.value)
fuzz = tonumber(d.fuzz.value) or 0
bandseg = tonumber(d.locked.value) or 0
if fuzz <= 0 then ErrorMessage('Max Score Change should be a small positive number') rc2 = false end
if bandseg < 1 or bandseg > structure.GetCount() then ErrorMessage('Locked Segment # out of range') rc2 = false end
if #ranges == 0 then ErrorMessage('Missing list of segment (ranges) to test.') rc2 = false end
until rc2 == true
if rc == 0 then print('Recipe canceled.') return end
-- ================================== Begin Main (work)
str = 10.0
zerolist = {} -- list of locked segments printed at the end
score = current.GetScore()
print(puzzle.GetName())
print(string.format('Relaxing to %f...',fuzz/10))
band.DeleteAll()
while true do
structure.WiggleAll(1)
newscore = current.GetScore()
print('Relaxing:',newscore-score)
if math.abs(newscore-score) < fuzz /10 then break end
score = newscore
end
print('Remember, you can quit any wiggle after 2 seconds.')
save.Quicksave(100)
structure.WiggleAll(1)
delta_bandless = current.GetScore() - score
print('bandless',delta_bandless)
save.Quickload(100)
print()
print('Seg Change')
for iBlock = 1, #ranges do
teststart, testend = ranges[iBlock][1], ranges[iBlock][2] or ranges[iBlock][1]
if teststart > testend then teststart,testend = testend,teststart end
for iSeg = teststart,testend do
band.DeleteAll()
rc = band.AddBetweenSegments(iSeg,bandseg)
if rc == 0 then
print(string.format('Error making band %d - %d (too close?)',iSeg,bandseg))
else
band.SetStrength(rc,str)
band.SetGoalLength(rc,0.001)
structure.WiggleAll(1)
delta = current.GetScore() - score
if math.abs(delta) < fuzz then table.insert(zerolist,iSeg) end
-- this test is based on the fact that wiggle is deterministic
-- if delta == delta_bandless then table.insert(zerolist,iSeg) end
print(iSeg,delta)
end
save.Quickload(100)
end
end
if #zerolist > 0 then
table.sort(zerolist)
print('Locked Segs:',table.concat(zerolist,' '))
else
print('No locked segments found.')
end