Code
--v 3.3 Extended sliders for Sketchbook (BK)
--v 3.4 Added AFK.BounceWiggle.Risky. When failed interations end, takes credidBest and starts again.
-- This shoul give a succession of "second best selection from all iterations" when MinGain is huge.
-- I think it should be good for end Sketchbook game
-- Added quick steps in cleanup for use of undos, deleted long lasting original cleanup (deselects & unfreezes)
--v 3.4.1 fixed an error (stopping after first gain) due to mispelling of save.Quicksave (not save.QuickSave)
--v 3.5 Tandem version (sharing and loading from local computer)
--v 3.5.1 fixed min CI >0.1 (Zeroleak7), changed number of iterations for mutateIterations (1-4) and shakeIterations (1-2)
-- fixed topscore
--SLOTS
-- 98 = best score
-- 10-50 = jumps
-- 51-90 = creditbest scores
BestSlot= 98
JumpSlot=10
JumpCredit=50
AFK = {}
AFK.BounceWiggle = {}
AFK.Debug = {}
AFK.Init = {}
AFK.Init.IsSelected = {}
AFK.Init.IsFrozen = {}
AFK.BounceWiggle.DoShake = false
AFK.IsMutable = false
AFK.BounceWiggle.DoMutate = false
AFK.BounceWiggle.Iterations = 1000
AFK.BounceWiggle.MinGain = 0
AFK.BounceWiggle.Risky = false
AFK.BounceWiggle.SkipCIMaximization = true
AFK.Debug.DoDebug=false
SKETCHBOOK = false
--START extraction of information from puzzle metadata --Extrait des infos
sym= 1 --Options: 1 normal; 2 dimer; 3 trimer; 4 tetramer (dimer of dimer) etc.
function detectfilterandmut() -- Bruno Kestemont 10/10/2013; 13/2/2015; 5/1/2019; (14/2/2021 simplified topscore for AFK)
local descrTxt=puzzle.GetDescription()
local puzzletitle=puzzle.GetName()
local function SymetryFinder() -- by Bruno Kestemont 7/2/2013, 25/8/2013
local segMeanScore=(current.GetEnergyScore()-8000)/structure.GetCount() -- top score pour eviter les debuts de puzzle
--p("Score moyen par segment= "..segMeanScore)
if PROBABLESYM then
if segMeanScore<33.39 then sym=1
PROBABLESYM=false
elseif segMeanScore<85 then sym=2
elseif segMeanScore<132 then sym=3
elseif segMeanScore<197 then sym=4
else sym=5
end
else sym=1
end
return
end
if #descrTxt>0 and (descrTxt:find("filter") or descrTxt:find("filters") or descrTxt:find("bonus") or descrTxt:find("bonuses") and not descrTxt:find("disabled"))then
PROBABLEFILTER=true
FILTERMANAGE=true -- default yes during wiggle (will always be activate when scoring)
GENERICFILTER=false -- to be evaluated
end
if #descrTxt>0 and (descrTxt:find("H-bond networks") or descrTxt:find("Hydrogen Bond Networks") or descrTxt:find("H-bond Networks")
or descrTxt:find("H-bond Network") and not descrTxt:find("disabled"))then
PROBABLEFILTER=true
FILTERMANAGE=false -- default no
GENERICFILTER=false -- to be evaluated
end
if #descrTxt>0 and (descrTxt:find("design") or descrTxt:find("designs")) then
HASMUTABLE=true
IDEALCHECK=true
HANDFOLD=true
end
if #descrTxt>0 and (descrTxt:find("De-novo") or descrTxt:find("de-novo") or descrTxt:find("freestyle")
or descrTxt:find("prediction") or descrTxt:find("predictions")) then
IDEALCHECK=true
HANDFOLD=true
end
if #puzzletitle>0 then
if (puzzletitle:find("Sym") or puzzletitle:find("Symmetry") or puzzletitle:find("Symmetric")
or puzzletitle:find("Dimer") or puzzletitle:find("Trimer") or puzzletitle:find("Tetramer")
or puzzletitle:find("Pentamer")) then
PROBABLESYM=true
if puzzletitle:find("Dimer") and not puzzletitle:find("Dimer of Dimers") then sym=2
elseif puzzletitle:find("Trimer") or puzzletitle:find("trimer") then sym=3
elseif puzzletitle:find("Dimer of Dimers") or puzzletitle:find("Tetramer") then sym=4
elseif puzzletitle:find("Pentamer") then sym=5
else SymetryFinder()
end
end
end
if #descrTxt>0 and (descrTxt:find("Sym") or descrTxt:find("Symmetry") or descrTxt:find("Symmetric")
or descrTxt:find("sym") or descrTxt:find("symmetry") or descrTxt:find("symmetric")) then
PROBABLESYM=true
if (descrTxt:find("Dimer") or descrTxt:find("dimer") or descrTxt:find("C2 symmetry") or descrTxt:find("twoo symmetric"))
and not (descrTxt:find("Dimer of Dimers") or descrTxt:find("dimer of dimers")) then sym=2
elseif descrTxt:find("Trimer") or descrTxt:find("trimer") or descrTxt:find("C3 symmetry") or descrTxt:find("three symmetric") then sym=3
elseif (descrTxt:find("Dimer of Dimers") or descrTxt:find("Tetramer") or descrTxt:find("C4 symmetry") or descrTxt:find("four symmetric"))
and not (descrTxt:find("dimer of dimers") or descrTxt:find("tetramer"))then sym=4
elseif descrTxt:find("Pentamer") or descrTxt:find("pentamer") or descrTxt:find("C5 symmetry") or descrTxt:find("five symmetric") then sym=5
else SymetryFinder()
end
end
--print resulting sym info
if PROBABLESYM then
print("Symmetric")
if sym==2 then
print("Dimer")
elseif sym==3 then
print("Trimer")
elseif sym==4 then
print("Tetramer")
elseif sym==5 then
print("Pentamer")
elseif sym>5 then
print("Terrible polymer")
end
else print("Monomer")
end
if #puzzletitle>0 and puzzletitle:find("Sepsis") then -- new BK 17/6/2013
SEPSIS=true
HANDFOLD=true
--p(true,"-Sepsis")
print("Sepsis")
end
if #puzzletitle>0 and puzzletitle:find("Electron Density") then -- for Electron Density
--p(true,"-Electron Density")
ELECTRON=true
HANDFOLD=true
print("Electron density")
end
if #puzzletitle>0 and puzzletitle:find("Centroid") then -- New BK 20/10/2013
--p(true,"-Centroid")
CENTROID=true
print("Centroid")
end
if #puzzletitle>0 and puzzletitle:find("Hotspot") then -- New BK 21/01/2014
HOTSPOT=true
print("Hotspot")
end
return
end
detectfilterandmut()
--END extraction of information from puzzle metadata --Extrait des infos
--START Isaksson Share v1.4
--Copy this into your recipe and call before and after every period of time.
--Warning: all saves onto you hard disk will have to be removed manually afterwards !
--reference: supplementary material for Koepnick et al (2019) De novo protein design by citizen scientists, Nature, volume 570, pages 390394
--https://static-content.springer.com/esm/art%3A10.1038%2Fs41586-019-1274-4/MediaObjects/41586_2019_1274_MOESM1_ESM.pdf
--v1: script by Isaksson
--v1.2 added the dialog (BK 1/10/2019)
--v1.3 added time intervals when no gain
--v1.4 PrintVerbose, check every 60 seconds
timeLeft=os.difftime(puzzle.GetExpirationTime(),os.time())/3600 -- in hours
print("Remaining time: "..timeLeft)
startTime=os.time() -- in seconds
userTimeInterval= 60 -- in seconds
lastchecktime = startTime -- in seconds
verbose = false -- print more or less info
save_resolution=1000
function PrintVerbose(text)
if verbose then
print(text)
end
end
function ItsCheckTime()
local currentTime= os.time() -- in seconds
if currentTime-lastchecktime > userTimeInterval then
local HoursRemaining= os.difftime(puzzle.GetExpirationTime(),os.time())/3600
PrintVerbose(HoursRemaining.." hours remaining")
return true
end
return false
end
function rounding(x)--cut all afer 3-rd place
return x-x%0.001
end
function before_Solution(rnd,str_name)
if save_resolution > 999 then return end -- New BK 1/10/2019
PrintVerbose("-Before-")
hi_score = 0
hi_idx = 1
sol = save.GetSolutions()
if (sol[0] == nil) then
print("0 solutions found")
--save.SaveSolution("auto_"..rnd)
else
PrintVerbose((#sol+1) .. " solutions found")
for idx = 0, #sol do
soli = sol[idx]
if (string.find(soli.name,rnd) ~= nil) then
PrintVerbose(soli.name .. " : " .. soli.score)
if (soli.score > hi_score) then
hi_score = soli.score
hi_idx = idx
end
end
end
--print("Load the solution ...")
if(current.GetEnergyScore()+save_resolution < hi_score) then
save.LoadSolution(sol[hi_idx])
soli = sol[hi_idx]
print("Load solution: "..soli.name.." : "..rounding(soli.score,value_score_resolution))
end
end
end
function after_Solution(rnd,str_name)
if save_resolution > 999 then return end -- New BK 1/10/2019
PrintVerbose("-After-")
hi_score = 0
hi_idx = 1
sol = save.GetSolutions()
if (sol[0] == nil) then
print("0 solutions found")
str = "auto".."-"..rnd.."-"..rounding(current.GetEnergyScore(),value_score_resolution)
print("Save solution "..str)
save.SaveSolution(str)
else
PrintVerbose((#sol+1) .. " solutions found")
for idx = 0, #sol do
soli = sol[idx]
if (string.find(soli.name,rnd) ~= nil) then
PrintVerbose(soli.name .. " : " .. soli.score)
if (soli.score > hi_score) then
hi_score = soli.score
hi_idx = idx
end
end
end
PrintVerbose("Save the solution ...")
band.DeleteAll()
if(current.GetEnergyScore()-save_resolution > hi_score) then
str = str_name.."-"..rnd.."-"..rounding(current.GetEnergyScore(),value_score_resolution)
print("Save solution: "..str)
save.SaveSolution(str)
end
end
end
str_name= ui.GetTrackName() -- copy-paste anywhere on top of the recipe
rnd= "Temp" -- Warning: edit before in order to cach the right loop name
--How to use:
--Uncomment and insert the following 2 lines on the right places, before or after each loop:
--if ItsCheckTime() then before_Solution(rnd,str_name) end -- as often as possible after score evaluations, e.g. in savebest(), or before any action
--after_Solution(rnd,str_name) -- after any gain (will not save any loaded solution)
--Uncommend and copy-paste the following 2x2 lines within the dialog on the right places:
--ask.LabelRowBeforeSave = dialog.AddLabel("Keep save resolution to 1000 to avoid local saves") --(optional) copy-paste and adapt in the dialog
--ask.save_resolution = dialog.AddSlider("Save after gain > ", 1000, 0.3, 1000, 1) --copy-paste and adapt in the dialog (parameters)-- 1000 means no sharing
--ask.save_Name = dialog.AddTextbox("Name2share", rnd)
--rnd=ask.save_Name.value
--save_resolution=ask.save_resolution.value -- copy-paste and adapt after the dialog.show
--if save_resolution > 999 then print("Checking for solutioun every "..userTimeInterval.." seconds") end
--End of Isaksson Share
if creditbest.GetScore() > current.GetScore() then
print("???????????")
print("WARNING not starting from creditbest score")
print("Risky endless on your own risk !")
print("???????????")
end
AFK.CreateBounceWiggleStrategicDialog = function()
local currentDialog = dialog.CreateDialog("BounceWiggleStrategy")
currentDialog.sketchbooklabel = dialog.AddLabel("Sketchbook automatic")
currentDialog.BlankLabel1 = dialog.AddLabel("")
currentDialog.TwoMoves = dialog.AddButton("2 moves", 1)
currentDialog.TenMoves = dialog.AddButton("7 moves", 2)
currentDialog.Custom = dialog.AddButton("Custom", 3)
currentDialog.CancelButton = dialog.AddButton("Cancel", 0)
local choice = dialog.Show(currentDialog)
return choice
end
AFK.CreateBounceWiggleDialog = function()
for n=1,structure.GetCount() do
if(structure.IsMutable(n)) then
AFK.IsMutable = true
end
if(selection.IsSelected(n)) then
AFK.Init.IsSelected[n] = true
else
AFK.Init.IsSelected[n] = false
end
if(freeze.IsFrozen(n)) then
AFK.Init.IsFrozen[n] = true
else
AFK.Init.IsFrozen[n] = false
end
end
local currentDialog = dialog.CreateDialog("BounceWiggle")
currentDialog.IterationsLabel = dialog.AddLabel("Failed Iterations before ending")
currentDialog.IterationsSlider = dialog.AddSlider("Failure Iterations", AFK.BounceWiggle.Iterations, 0, 1000, 0)
currentDialog.BlankLabel1 = dialog.AddLabel("")
currentDialog.DiscardLabel = dialog.AddLabel("(Sketchbook) Discard gains less than")
currentDialog.DiscardSlider = dialog.AddSlider("Discard <", AFK.BounceWiggle.MinGain, 0, 500, 2)
currentDialog.Risky = dialog.AddCheckbox("Risky endless using CreditBest", AFK.BounceWiggle.Risky)
currentDialog.BlankLabel2 = dialog.AddLabel("")
currentDialog.SkipMaximization = dialog.AddCheckbox("Skip CI=1 Maximization", AFK.BounceWiggle.SkipCIMaximization)
--currentDialog.LabelRowBeforeSave = dialog.AddLabel("Keep save resolution to 1000 to avoid local saves") --(optional) copy-paste and adapt in the dialog
currentDialog.save_resolution = dialog.AddSlider("Save every gain > ", 1000, 0.3, 1000, 1) --copy-paste and adapt in the dialog (parameters)-- 1000 means no sharing
currentDialog.save_Name = dialog.AddTextbox("Name2share", rnd)
currentDialog.NoShakeButton = dialog.AddButton("No Shake", 1)
currentDialog.ShakeButton = dialog.AddButton("Shake", 2)
if(AFK.IsMutable) then
currentDialog.MutateButton = dialog.AddButton("Mutate", 3)
end
currentDialog.CancelButton = dialog.AddButton("Cancel", 0)
local choice = dialog.Show(currentDialog)
AFK.BounceWiggle.Iterations = currentDialog.IterationsSlider.value
AFK.BounceWiggle.MinGain = currentDialog.DiscardSlider.value
AFK.BounceWiggle.Risky = currentDialog.Risky.value
AFK.BounceWiggle.SkipCIMaximization = currentDialog.SkipMaximization.value
save_resolution=currentDialog.save_resolution.value -- copy-paste and adapt after the dialog.show
if save_resolution < 1000 then print("Checking for solutioun every "..userTimeInterval.." seconds") end
rnd=currentDialog.save_Name.value
if(AFK.BounceWiggle.Iterations < 1) then
AFK.BounceWiggle.Iterations = -1
end
AFK.BounceWiggle.IterationsReset = AFK.BounceWiggle.Iterations -- init if further rounds needed
if (choice > 2) then
print("AFK3(BounceWiggleMutate) started. "..AFK.BounceWiggle.Iterations.." Failed Iterations before ending")
AFK.BounceWiggle.DoMutate = true
elseif (choice > 1) then
print("AFK3(BounceWiggleShake) started. "..AFK.BounceWiggle.Iterations.." Failed Iterations before ending")
AFK.BounceWiggle.DoShake = true
elseif (choice > 0) then
print("AFK3(BounceWiggleNoShake) started. "..AFK.BounceWiggle.Iterations.." Failed Iterations before ending")
else
print("Dialog cancelled")
end
return choice
end
AFK.BounceWiggle.Init = function()
-- dialog stuff
local choice = 3 -- default to normal dialog
if SKETCHBOOK then -- sketchbook dialog choices 1 or 2
choice = AFK.CreateBounceWiggleStrategicDialog()
end
if(choice < 1) then return -- stops the recipe
elseif choice <2 then -- 2 moves
AFK.BounceWiggle.DoShake = false
AFK.BounceWiggle.DoMutate = false
AFK.BounceWiggle.Iterations = 1000
AFK.BounceWiggle.MinGain = 500
AFK.BounceWiggle.Risky = false
elseif choice <3 then -- 7 moves
AFK.BounceWiggle.DoShake = true
if HASMUTABLE then AFK.BounceWiggle.DoMutate = true end
AFK.BounceWiggle.Iterations = 100
AFK.BounceWiggle.MinGain = 500
AFK.BounceWiggle.Risky = true
elseif choice <4 then -- custom (normal dialog)
choice = AFK.CreateBounceWiggleDialog() -- normal dialog
if(choice < 1) then return end
end
-- end dialog stuff
AFK.BounceWiggle.IterationsReset = AFK.BounceWiggle.Iterations -- init if further rounds needed
local currentScore = AFK.StartScore
local tempScore = currentScore
local tempScore2 = tempScore
save.Quicksave(BestSlot)
recentbest.Save()
behavior.SetClashImportance(1)
local init = true
if(AFK.BounceWiggle.SkipCIMaximization == false) then
print("Maximizing Wiggle Score at Clashing Impotance = 1. Please wait.")
while(current.GetEnergyScore() > currentScore or init == true) do
init = false
currentScore = current.GetEnergyScore()
tempScore = currentScore
tempScore2 = tempScore
selection.SelectAll()
structure.WiggleAll(25)
recentbest.Restore()
tempScore = current.GetEnergyScore()
if(tempScore > (tempScore2 + AFK.BounceWiggle.MinGain)) then
save.Quicksave(BestSlot)
tempScore2 = tempScore
after_Solution(rnd,str_name) -- after any gain (will not save any loaded solution)
else
save.Quickload(BestSlot)
if ItsCheckTime() then before_Solution(rnd,str_name) end -- as often as possible after score evaluations, e.g. in savebest(), or before any action
tempScore = current.GetEnergyScore()
end
structure.LocalWiggleAll(25)
recentbest.Restore()
tempScore = current.GetEnergyScore()
if(tempScore > (tempScore2 + AFK.BounceWiggle.MinGain)) then
save.Quicksave(BestSlot)
tempScore2 = tempScore
after_Solution(rnd,str_name) -- after any gain (will not save any loaded solution)
else
save.Quickload(BestSlot)
if ItsCheckTime() then before_Solution(rnd,str_name) end -- as often as possible after score evaluations, e.g. in savebest(), or before any action
tempScore = current.GetEnergyScore()
end
structure.WiggleSelected(25)
recentbest.Restore()
tempScore = current.GetEnergyScore()
if(tempScore > (tempScore2 + AFK.BounceWiggle.MinGain)) then
save.Quicksave(BestSlot)
tempScore2 = tempScore
after_Solution(rnd,str_name) -- after any gain (will not save any loaded solution)
else
save.Quickload(BestSlot)
if ItsCheckTime() then before_Solution(rnd,str_name) end -- as often as possible after score evaluations, e.g. in savebest(), or before any action
tempScore = current.GetEnergyScore()
end
structure.LocalWiggleSelected(25)
recentbest.Restore()
tempScore = current.GetEnergyScore()
if(tempScore > (tempScore2 + AFK.BounceWiggle.MinGain)) then
save.Quicksave(BestSlot)
tempScore2 = tempScore
after_Solution(rnd,str_name) -- after any gain (will not save any loaded solution)
else
save.Quickload(BestSlot)
if ItsCheckTime() then before_Solution(rnd,str_name) end -- as often as possible after score evaluations, e.g. in savebest(), or before any action
tempScore = current.GetEnergyScore()
end
end
currentScore = current.GetEnergyScore()
end
if(currentScore > AFK.StartScore)then
print ("script started: + "..(currentScore - AFK.StartScore).." -- "..currentScore)
else
print("script started: "..currentScore)
end
init = true
while(init == true or AFK.BounceWiggle.Iterations > 0 or AFK.BounceWiggle.Iterations < 0) do
init = false
currentScore = current.GetEnergyScore()
if(AFK.Debug.DoDebug == true) then
print("Debug")
end
AFK.BounceWiggle.Run()
if(current.GetEnergyScore() > currentScore + AFK.BounceWiggle.MinGain)then
print (AFK.BounceWiggle.Iterations..": + "..(current.GetEnergyScore() - currentScore).." -- "..current.GetEnergyScore())
JumpSlot=JumpSlot+1
if(AFK.Debug.DoDebug == true) then
--print ("CI("..ci..") "..co.."("..ce..") ".." CI(1) "..ca.."("..cu..") ")
print ("JumpSlot ("..JumpSlot..") ")
end
if JumpSlot>50 then JumpSlot=10 end
save.Quicksave(JumpSlot)
if(AFK.BounceWiggle.Iterations > 0) then
AFK.BounceWiggle.Iterations = AFK.BounceWiggle.Iterations + 1
end
if(AFK.Debug.DoDebug == true) then
--print ("CI("..ci..") "..co.."("..ce..") ".." CI(1) "..ca.."("..cu..") ")
print ("Iterations("..AFK.BounceWiggle.Iterations..") ")
end
else
if(AFK.Debug.DoDebug == true) then
--print ("CI("..ci..") "..co.."("..ce..") ".." CI(1) "..ca.."("..cu..") ")
print ("Iterations("..AFK.BounceWiggle.Iterations..") ")
end
if (AFK.BounceWiggle.Iterations == 25) or (AFK.BounceWiggle.Iterations == 50) or (AFK.BounceWiggle.Iterations == 100)
or (AFK.BounceWiggle.Iterations == 200) or (AFK.BounceWiggle.Iterations == 400) then
print (AFK.BounceWiggle.Iterations.." iterations left (creditbest= ".. creditbest.GetScore()..")")
end
end
if(AFK.BounceWiggle.Iterations > 0) then AFK.BounceWiggle.Iterations = AFK.BounceWiggle.Iterations - 1 end
if AFK.BounceWiggle.Risky and (AFK.BounceWiggle.Iterations == 1) then
AFK.BounceWiggle.Iterations = AFK.BounceWiggle.IterationsReset
print("Starting over with creditbest scoring",creditbest.GetScore())
creditbest.Restore()
JumpCredit=JumpCredit+1
if JumpCredit>90 then JumpCredit=51 end
save.Quicksave(JumpCredit)
end
end
init = true
currentScore = current.GetEnergyScore()
if(AFK.BounceWiggle.SkipCIMaximization == false) then
print("Maximizing Wiggle Score at Clashing Impotance = 1. Please wait.")
while(current.GetEnergyScore() > currentScore or init == true) do
init = false
currentScore = current.GetEnergyScore()
tempScore = currentScore
tempScore2 = tempScore
selection.SelectAll()
structure.WiggleAll(25)
recentbest.Restore()
tempScore = current.GetEnergyScore()
if(tempScore > (tempScore2 + AFK.BounceWiggle.MinGain)) then
save.Quicksave(BestSlot)
tempScore2 = tempScore
after_Solution(rnd,str_name) -- after any gain (will not save any loaded solution)
else
save.Quickload(BestSlot)
if ItsCheckTime() then before_Solution(rnd,str_name) end -- as often as possible after score evaluations, e.g. in savebest(), or before any action
tempScore = current.GetEnergyScore()
end
structure.LocalWiggleAll(25)
recentbest.Restore()
tempScore = current.GetEnergyScore()
if(tempScore > (tempScore2 + AFK.BounceWiggle.MinGain)) then
save.Quicksave(BestSlot)
tempScore2 = tempScore
after_Solution(rnd,str_name) -- after any gain (will not save any loaded solution)
else
save.Quickload(BestSlot)
if ItsCheckTime() then before_Solution(rnd,str_name) end -- as often as possible after score evaluations, e.g. in savebest(), or before any action
tempScore = current.GetEnergyScore()
end
structure.WiggleSelected(25)
recentbest.Restore()
tempScore = current.GetEnergyScore()
if(tempScore > (tempScore2 + AFK.BounceWiggle.MinGain)) then
save.Quicksave(BestSlot)
tempScore2 = tempScore
after_Solution(rnd,str_name) -- after any gain (will not save any loaded solution)
else
save.Quickload(BestSlot)
if ItsCheckTime() then before_Solution(rnd,str_name) end -- as often as possible after score evaluations, e.g. in savebest(), or before any action
tempScore = current.GetEnergyScore()
end
structure.LocalWiggleSelected(25)
recentbest.Restore()
tempScore = current.GetEnergyScore()
if(tempScore > (tempScore2 + AFK.BounceWiggle.MinGain)) then
save.Quicksave(BestSlot)
tempScore2 = tempScore
after_Solution(rnd,str_name) -- after any gain (will not save any loaded solution)
else
save.Quickload(BestSlot)
if ItsCheckTime() then before_Solution(rnd,str_name) end -- as often as possible after score evaluations, e.g. in savebest(), or before any action
tempScore = current.GetEnergyScore()
end
end
end
if(current.GetEnergyScore() > currentScore)then
print ("script complete: + "..(current.GetEnergyScore() - AFK.StartScore).." -- "..current.GetEnergyScore())
else
print("script complete:"..current.GetEnergyScore())
end
AFK.Cleanup()
end
AFK.BounceWiggle.Run = function()
local currentScore = current.GetEnergyScore()
local tempScore = currentScore
local tempScore2 = tempScore
save.Quicksave(BestSlot)
--truly random numbers are not required
local wiggle1Type = math.random(1,4)
local wiggle1Iterations = math.random(1, 3)
local wiggle1CI = math.random(1, 1000) / 1000
if(wiggle1CI < 0.10) then wiggle1CI = 0.10 end -- Fixed by Zeroleak7
local wiggle2Type = math.random(1,4)
if(AFK.Debug.DoDebug == true) then
print("wiggle1Type "..wiggle1Type)
print("wiggle1Iterations "..wiggle1Iterations)
print("wiggle1CI "..wiggle1CI)
print("wiggle2Type "..wiggle2Type)
end
behavior.SetClashImportance(wiggle1CI)
if(wiggle1Type > 3) then
structure.LocalWiggleSelected(wiggle1Iterations)
--wiggle1Type = "LocalWiggleSelected"
elseif(wiggle1Type > 2) then
structure.WiggleSelected(wiggle1Iterations)
--wiggle1Type = "LocalWiggleSelected"
elseif(wiggle1Type > 1) then
structure.LocalWiggleAll(wiggle1Iterations)
--wiggle1Type = "LocalWiggleSelected"
else
structure.WiggleAll(wiggle1Iterations)
--wiggle1Type = "LocalWiggleSelected"
end
if(AFK.BounceWiggle.DoShake == true or AFK.BounceWiggle.DoMutate == true) then
local shakeType = math.random(1,3)
local mutateIterations = math.floor(((wiggle1Type + wiggle2Type) / 2) + 0.5) -- 1 to 4
local shakeIterations = math.floor(((mutateIterations) / 2) + 0.6) -- 1 to 2
local shakeCI = math.random(1, 1000) / 1000
if(shakeCI < 0.10) then shakeCI = 0.10 end -- fixed by Zeroleak7
behavior.SetClashImportance(shakeCI)
if(AFK.Debug.DoDebug == true) then
print("shakeType "..shakeType)
print("shakeIterations "..shakeIterations)
print("shakeCI "..shakeCI)
end
if(shakeType > 1 and AFK.BounceWiggle.DoMutate == true) then
structure.MutateSidechainsAll(mutateIterations)
elseif(shakeType > 1) then
structure.ShakeSidechainsAll(shakeIterations)
else
selection.DeselectAll()
local shakeSelectionCount = math.random(1,structure.GetCount())
if(AFK.Debug.DoDebug == true) then
print("shakeSelectionCount "..shakeSelectionCount)
end
for n=1,shakeSelectionCount do
local selectSegment = math.random(1,structure.GetCount())
if(AFK.Debug.DoDebug == true) then
print("selectSegment "..selectSegment)
end
selection.Select(selectSegment)
end
if(AFK.BounceWiggle.DoMutate == true) then
structure.MutateSidechainsSelected(mutateIterations)
else
structure.ShakeSidechainsSelected(shakeIterations)
end
selection.SelectAll()
end
end
behavior.SetClashImportance(1)
if(AFK.Debug.DoDebug == true) then
print("wiggle2Type "..wiggle2Type)
end
if(wiggle2Type > 3) then
structure.LocalWiggleSelected(25)
--wiggle2Type = "LocalWiggleSelected"
elseif(wiggle2Type > 2) then
structure.WiggleSelected(25)
--wiggle2Type = "WiggleSelected"
elseif(wiggle2Type > 1) then
structure.LocalWiggleAll(25)
--wiggle2Type = "LocalWiggleAll"
else
structure.WiggleAll(25)
--wiggle2Type = "WiggleAll"
end
recentbest.Restore()
tempScore = current.GetEnergyScore()
if(tempScore > (tempScore2 + AFK.BounceWiggle.MinGain)) then
save.Quicksave(BestSlot)
tempScore2 = tempScore
after_Solution(rnd,str_name) -- after any gain (will not save any loaded solution)
else
save.Quickload(BestSlot)
tempScore = current.GetEnergyScore()
end
end
AFK.StartScore = current.GetEnergyScore()
AFK.StartCI = behavior.GetClashImportance()
function AFK.Cleanup(errorMessage)
behavior.SetClashImportance(AFK.StartCI)
--recentbest.Restore()
--selection.DeselectAll()
print("Loading Jump Slots - see Undos")
for i= 10, JumpSlot do
save.QuickLoad(i)
end
print("Loading Jump Credits - see Undos")
for i= 50, JumpCredit do
save.QuickLoad(i)
end
print("Loading Best Slot- see Undos")
save.QuickLoad(BestSlot)
end
xpcall(AFK.BounceWiggle.Init, AFK.Cleanup)