Code
-- SwitchWig begun 9/21/14 by jeff101
-- goal is to semi-automate manual procedures like below:
-- ci=1 hi wig all + best of 4x(ci=0.1 lo wig all + ci=1 hi wig all)
-- ci=1 med wig all + best of 10x(ci=0.1 lo wig all + ci=1 med wig all)
-- would be better if could set the Wiggle Power inside this Recipe
-- last updated 9/22/14 536pm
function Main()
local nbands=band.GetCount()
local rtot=structure.GetCount()
local oldscore=current.GetScore()
recentbest.Save() -- resets the recentbest to the starting score
-- might be handy to restore recent best after running this Recipe
local oldci=behavior.GetClashImportance()
local cilo=0.1+0
local cihi=1+0
local iterslo=33+0
local itershi=33+0
local nlotries=7+0
local saveslot=68+0
local pflag=false
local mssg,ask,trynum,notenum,bestscore,newscore
print('Run of SwitchWig on '..puzzle.GetName()..'\nwith Puzzle ID '..puzzle.GetPuzzleID()..' at '..os.date()..':\n ')
print('Has '..rtot..' residues, '..nbands..' bands, Clashing Importance '..round2(oldci)..',\nand score '..trunc3(oldscore)..'.\n ')
mssg='This Recipe cycles through two values of the\nClashing Importance (lo ci and hi ci),'
mssg=mssg..'\nstarting and ending with hi ci. At each value of the\nClashing Importance,'
mssg=mssg..' it pauses to let the\nWiggle Power be changed, then it performs WiggleAll'
mssg=mssg..'\nfor the # of iterations (lo iters, hi iters) input below.'
mssg=mssg..'\nIt also Quicksaves and Quickloads from the\nsave slot # input below.'
print(mssg)
print(' ')
ask=dialog.CreateDialog('SwitchWig')
ask.Label0=dialog.AddLabel(' ')
ask.Label1=dialog.AddLabel(' ')
ask.Label2=dialog.AddLabel(mssg)
ask.Label3=dialog.AddLabel(' ')
ask.Label4=dialog.AddLabel(' ')
ask.Input1=dialog.AddSlider("lo ci: ",cilo,0,1,2)
ask.Input2=dialog.AddSlider("hi ci: ",cihi,0,1,2)
ask.Input3=dialog.AddSlider("lo iters: ",iterslo,1,200,0)
ask.Input4=dialog.AddSlider("hi iters: ",itershi,1,200,0)
ask.Input5=dialog.AddSlider("# of lo ci tries: ",nlotries,0,10,0)
ask.Input6=dialog.AddCheckbox("pause so can change Wiggle Power: ",pflag)
ask.Input7=dialog.AddSlider("save slot #: ",saveslot,1,100,0)
ask.OK = dialog.AddButton("OK", 1)
dialog.Show(ask)
cilo=ask.Input1.value+0
cihi=ask.Input2.value+0
iterslo=ask.Input3.value+0
itershi=ask.Input4.value+0
nlotries=ask.Input5.value+0
pflag=ask.Input6.value
saveslot=ask.Input7.value+0
print('Got the inputs lo ci='..cilo..', hi ci='..cihi..', lo iters='..iterslo..', hi iters='..itershi..',')
print('# of lo ci tries='..nlotries..', pause='..tostring(pflag)..', and save slot #='..saveslot..'.')
bestscore=current.GetScore()
save.Quicksave(saveslot)
print(' \nStarting with score '..trunc3(bestscore)..'.')
bestscore=doloop(cihi,1,itershi,bestscore,pflag,saveslot)
for trynum=1,nlotries do
bestscore=doloop(cilo,trynum,iterslo,bestscore,pflag,saveslot)
bestscore=doloop(cihi,trynum+1,itershi,bestscore,pflag,saveslot)
end -- for trynum
--
-- next restore best solution
save.Quickload(saveslot)
newscore=current.GetScore()
--
print(' \nRestoring Clashing Importance to '..round2(oldci)..' and score to '..trunc3(newscore)..'.')
if newscore~=bestscore then
print('ERROR: final score '..trunc3(newscore)..' and best score '..trunc3(bestscore)..' differ.')
end -- if newscore
behavior.SetClashImportance(oldci)
--
-- next part puts mssg into the Note for the lowest segment # with a blank Note
-- want all segment #'s above notenum to have blank Notes
mssg=string.format("(%s) %.3f + SwitchWig(ci=%.2f + %ix(ci=%.2f + ci=%.2f)) %.3f",user.GetPlayerName(),trunc3(oldscore),round2(cihi),nlotries,round2(cilo),round2(cihi),trunc3(newscore))
notenum=rtot
for trynum=rtot,1,-1 do
if structure.GetNote(trynum)~="" then break end
notenum=trynum
end
structure.SetNote(notenum,mssg)
--
print(' \nAll done at '..os.date()..' with\nClashing Importance '..round2(oldci)..' and score '..trunc3(newscore)..'.')
end -- Main()
function doloop(newci,trynum,iters,bestscore,pflag,saveslot)
local ask,mssg,newscore,time1,time2,minutes
if pflag==true then
mssg='Click OK when ready to do WiggleAll with\nClashing Importance set to '..newci..'.'
ask=dialog.CreateDialog('SwitchWig')
ask.Label1=dialog.AddLabel(' ')
ask.Label2=dialog.AddLabel(mssg)
ask.Label3=dialog.AddLabel(' ')
ask.OK = dialog.AddButton("OK", 1)
dialog.Show(ask)
end -- if pflag
behavior.SetClashImportance(newci)
time1=os.time() -- start timer
structure.WiggleAll(iters,true,true)
-- previous line did WiggleAll on both backbone and sidechain for iters iterations
time2=os.time() -- end timer
minutes=os.difftime(time2,time1)
local time = string.format("%i", minutes/60)..":"..string.format("%02i", minutes%60)
newscore=current.GetScore()
mssg=''
if newscore>bestscore then
mssg=' (*** new best score ***)'
end -- if newscore
print('('..trynum..') '..iters..' iters of WiggleAll w/ci='..round2(newci)..' gives '..trunc3(newscore)..' in '..time..' minutes'..mssg..'.')
-- goal below is to store the solution if its score (newscore) beats bestscore
if newscore>bestscore then
bestscore=newscore
save.Quicksave(saveslot)
end -- if newscore
return bestscore
end -- doloop(()
-- below rounds to 3 decimal places
function round3(numi)
local numo=round(numi*1000)/1000
return numo
end -- round3()
-- below rounds to 2 decimal places
function round2(numi)
local numo=round(numi*100)/100
return numo
end -- round2()
-- below rounds to 1 decimal place
function round1(numi)
local numo=round(numi*10)/10
return numo
end -- round1()
-- below rounds val to the nearest integer to get res
function round(val)
local res=math.floor(val)
if val-res>=0.5 then
res=res+1
end -- if val
return res
end -- round()
-- below rounds val down to the nearest thousandth and returns the result
function trunc3(val)
return val-(val % 0.001)
end -- trunc3()
Main()