Code
recipe_name = "Random Idealize 1.8"
--[[
Author: mirp
- last updated 11/15/14 536pm
Version 1.0 (12/11/2013):
- First Release
Version 1.1 (12/28/2013):
- Idealize requires at least two adjacent segments
- Handle locked or frozen segments
- Wiggle all after each idealize added
- Fuze added
- Mutate added
- Ask for keeping bands, freeze and ci
- Note with the result added
- Verbose mode added
- No sign means no change
- Elapsed time added
- Clean break added
- Best solution is stored in slot 3
Version 1.2 (01/17/2014):
- Loop limit added
- Simple walker added
- Presets added
- Fast: similar to version 1.0
- Slow: similar to version 1.1, but larger segments
- Slower: larger segments than Slow and walker if small gain
Version 1.3 (10/16/2014):
- adapted by jeff101 from version 1.2
- sometimes print actual time
- added print lines for debugging devprev BETA Symmetry Debugging puzzle
- as described at http://fold.it/portal/node/1998494
- when flag_verbose > 2
version 1.4 (10/30/14):
- adapted by jeff101 from 1.3b.txt 310pm 10/16/14 code
- lets user input range of segments (index_lo to index_hi) to pick from
- for flag_verbose > 2,
- prints current score and
- does a quicksave to debug_slot before mutate, wiggle, or idealize
- moved AAA into randomIdealize()
- is program flow and logic unchanged versus previous versions?
- needs testing on proteins with frozen or locked segments
version 1.5 (11/1/14):
- adapted by jeff101 from 1.4b.txt 119am 10/31/14 code
- for flag_verbose > 2,
- does quicksave then quickload to/from debug_slot and
- prints scores before and after, plus their difference
version 1.6 (11/6/14):
- adapted by jeff101 from 1.5a.txt 558pm 11/1/14 code
- lets user input rand_seed and rand_so_far to make recipe repeatable
version 1.7 (11/7/14)
- adapted by jeff101 from 1.6c.txt 945pm 11/6/14 code
- list amino acids and secondary structures for segment range
- list groups of 10 random #'s regularly to help sync up rand_so_far
version 1.8 (11/15/14)
- adapted by jeff101 from 1.7d.txt 539pm 11/9/14 code
- have minimum # of segments
- have checkbox options to skip main wiggles or idealizes
]]--
n = structure.GetCount() -- length of the protein
-- Defaults
default_preset = 3 -- default preset: 2 = fast, 3 = slow, 4 = slower
loop_limit = 0 -- ends after loop_limit (0 = no limit)
-- Iterations
idealize_wiggle_selected = 5 -- wiggle selected iterations after idealize
idealize_wiggle_all = 1 -- wiggle all iterations after each idealize
loop_wiggle = 10 -- loop wiggle iterations after each loop
walker_wiggle_iterations = 2 -- wiggle selected iterations for walker
fuze_wiggle_iterations = 3 -- wiggle iterations while fuzing
fuze_shake_iterations = 2 -- shake iterations while fuzing
idealize_mutate_iterations = 1 -- mutate selected iterations after each idealize
loop_mutate_iterations = 1 -- mutate all iterations after each loop
-- Fuze
trigger_fuze = 1 -- fuze if cumulative gain is greater than trigger_fuze
-- Walker
trigger_walker = 0.1 -- only use walker if loop gain is smaller than trigger_walker
-- Verbose
flag_verbose = 0 -- more information (0 = off, 1 = when gained, 2 = always, 3 = for debugging)
-- Note
flag_note = true -- save result as note in segment note_segment
-- Keep
keep_bands = false -- don't keep bands
keep_frozen = false -- don't keep frozen
keep_ci = false -- don't keep ci
index_lo = 1 -- min segment # to process
index_hi = n -- max segment # to process
debug_slot = 13 -- slot to use for debugging quicksaves
rand_so_far = 0 -- # of random #'s generated so far
rand_seed = os.time() -- the default seed for random # generator
min_segments = 2
skip_idealize = false
skip_wiggle = false
-- Preset Fast
fast_loop_length = 60 -- length of a loop
fast_max_segments = 8 -- max. number of segments selected for idealize
fast_flag_idealize_wiggle_all = false -- wiggle all after each idealize
fast_flag_walker = false -- walker after loop if loop gain is less than trigger_walker
fast_flag_loop_wiggle = true -- wiggle all after each loop
fast_flag_loop_fuze = false -- fuze after loop
fast_flag_idealize_mutate = false -- mutate selected after each idealize
fast_flag_loop_mutate = false -- mutate all after each loop
-- Preset Slow
slow_loop_length = 50
slow_max_segments = 12
slow_flag_idealize_wiggle_all = true
slow_flag_walker = false
slow_flag_loop_wiggle = true
slow_flag_loop_fuze = true
slow_flag_idealize_mutate = true
slow_flag_loop_mutate = true
-- Preset Slower
slower_loop_length = 40
slower_max_segments = 16
slower_flag_idealize_wiggle_all = true
slower_flag_walker = true
slower_flag_loop_wiggle = true
slower_flag_loop_fuze = true
slower_flag_idealize_mutate = true
slower_flag_loop_mutate = true
-- many functions follow
function isSlower()
if loop_length == slower_loop_length and
max_segments == slower_max_segments and
flag_idealize_wiggle_all == slower_flag_idealize_wiggle_all and
flag_walker == slower_flag_walker and
flag_loop_wiggle == slower_flag_loop_wiggle and
flag_loop_fuze == slower_flag_loop_fuze and
flag_idealize_mutate == slower_flag_idealize_mutate and
flag_loop_mutate == slower_flag_loop_mutate then
return true
else return false end
end -- function
function isFast()
if loop_length == fast_loop_length and
max_segments == fast_max_segments and
flag_idealize_wiggle_all == fast_flag_idealize_wiggle_all and
flag_walker == fast_flag_walker and
flag_loop_wiggle == fast_flag_loop_wiggle and
flag_loop_fuze == fast_flag_loop_fuze and
flag_idealize_mutate == fast_flag_idealize_mutate and
flag_loop_mutate == fast_flag_loop_mutate then
return true
else return false end
end -- function
function isSlow()
if loop_length == slow_loop_length and
max_segments == slow_max_segments and
flag_idealize_wiggle_all == slow_flag_idealize_wiggle_all and
flag_walker == slow_flag_walker and
flag_loop_wiggle == slow_flag_loop_wiggle and
flag_loop_fuze == slow_flag_loop_fuze and
flag_idealize_mutate == slow_flag_idealize_mutate and
flag_loop_mutate == slow_flag_loop_mutate then
return true
else return false end
end -- function
function setFast()
loop_length = fast_loop_length
max_segments = fast_max_segments
flag_idealize_wiggle_all = fast_flag_idealize_wiggle_all
flag_walker = fast_flag_walker
flag_loop_wiggle = fast_flag_loop_wiggle
flag_loop_fuze = fast_flag_loop_fuze
flag_idealize_mutate = fast_flag_idealize_mutate
flag_loop_mutate = fast_flag_loop_mutate
recipe_name_preset = recipe_name.." Fast"
end -- function
function setSlow()
loop_length = slow_loop_length
max_segments = slow_max_segments
flag_idealize_wiggle_all = slow_flag_idealize_wiggle_all
flag_walker = slow_flag_walker
flag_loop_wiggle = slow_flag_loop_wiggle
flag_loop_fuze = slow_flag_loop_fuze
flag_idealize_mutate = slow_flag_idealize_mutate
flag_loop_mutate = slow_flag_loop_mutate
recipe_name_preset = recipe_name.." Slow"
end -- function
function setSlower()
loop_length = slower_loop_length
max_segments = slower_max_segments
flag_idealize_wiggle_all = slower_flag_idealize_wiggle_all
flag_walker = slower_flag_walker
flag_loop_wiggle = slower_flag_loop_wiggle
flag_loop_fuze = slower_flag_loop_fuze
flag_idealize_mutate = slower_flag_idealize_mutate
flag_loop_mutate = slower_flag_loop_mutate
recipe_name_preset = recipe_name.." Slower"
end -- function
-- many functions are above
-- below is loose code not in a function
-- Initialize global variables
loop_length = 0
max_segments = 0
flag_idealize_wiggle_all = false
flag_walker = false
flag_loop_wiggle = false
flag_loop_fuze = false
flag_idealize_mutate = false
flag_loop_mutate = false
recipe_name_preset = recipe_name
setFast()
start_time = 0
initial_score = current.GetScore()
pre_ci = behavior.GetClashImportance()
fuze_score = 0 -- last fuze score
loop_score = initial_score
loop_n = 0
idealize_n = 0
fuze_score = initial_score
pre_score = 0
post_score = 0
-- more functions follow
function puzzleHasMutable()
for i = 1,n do
if structure.IsMutable(i) then
return true
end -- if
end -- for
return false
end -- function
function puzzleHasLocked()
for i = 1,n do
if structure.IsLocked(i) then
return true
end -- if
end -- for
return false
end -- function
function noteSegment()
for i=n,1,-1 do
if structure.GetNote(i) ~= "" then
if i == n then return(-1) else return(i+1) end
end -- if
end -- for
return(1)
end -- function
-- more loose code not part of a function is next
note_segment = noteSegment()
flag_mutable_puzzle = puzzleHasMutable()
flag_locked_puzzle = puzzleHasLocked()
flag_bands = band.GetCount() > 0
flag_freeze = math.max(freeze.GetCount()) > 0
flag_freeze_puzzle = flag_freeze
flag_ci = behavior.GetClashImportance() ~= 1
-- more functions below
function saveSlot3()
if flag_note and loop_n > 0 then
structure.SetNote(note_segment,string.format("(%s) %.3f + %s (%i)[%i] %.3f",
user.GetPlayerName(),roundScore(initial_score),recipe_name_preset,loop_n,idealize_n,roundScore(current.GetScore())))
end -- if
save.Quicksave(3)
end -- function
function roundScore(val)
return val - val % 0.001 -- rounds val down to nearest 0.001
end -- function
-- below rounds val to 3 decimal places to get res
function round3(val)
local res=round(val*1000)/1000
return res
end -- round3()
-- 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()
function notLockedAdjacentSegments()
-- idealize requires at least two segments
-- all segments has to be adjacent
if index_lo==index_hi then return {} end
-- not locked list
not_locked_list = {}
if flag_locked_puzzle or flag_freeze_puzzle then
last_segment = false -- segment i
for i = index_lo, index_hi-1 do
if not freeze.IsFrozen(i) and not structure.IsLocked(i) and
not freeze.IsFrozen(i+1) and not structure.IsLocked(i+1) then
if last_segment then
not_locked_list[#not_locked_list+1] = i+1
else
not_locked_list[#not_locked_list+1] = i
not_locked_list[#not_locked_list+1] = i+1
end -- if/else
last_segment = true
else
last_segment = false
end -- if/else
end -- for
else
for i = index_lo, index_hi do
not_locked_list[#not_locked_list+1] = i
end -- for
end -- if/else
if #not_locked_list == 0 then return {} end
return not_locked_list
end -- function
-- AAA code was here before 10/30/14
-- and not as part of a function
-- moved AAA code into randomIdealize() function 10/30/14
function getrand(val1,val2) -- val1,val2 should be integers
local res
res = math.random(val1,val2) -- res should be random integer from val1 to val2
rand_so_far = rand_so_far + 1
return res
end -- function getrand()
function randomAdjacentSegments(not_locked_list)
if flag_locked_puzzle or flag_freeze then
-- select random start segments
repeat
start_index = getrand(1,#not_locked_list-1)
-- previous line gets rand # from 1 to #not_locked_list-1
until not_locked_list[start_index] + 1 == not_locked_list[start_index+1]
-- random range
segments = getrand(min_segments,max_segments) - 1
-- previous line gets rand # from min_segments-1 to max_segments-1
for i = 1,segments do
if start_index + i > #not_locked_list then
end_index = #not_locked_list
else
if not_locked_list[start_index] + i == not_locked_list[start_index+i] then
end_index = start_index + i
else
return {not_locked_list[start_index],not_locked_list[end_index]}
end -- if/else
end -- if/else
end -- for
segment_range = {not_locked_list[start_index],not_locked_list[end_index]}
else
-- select random segments
segments = getrand(min_segments,max_segments) - 1
-- previous line sets segments to random # from min_segments-1 to max_segments-1
start_seg = getrand(index_lo,index_hi - segments)
-- previous line sets start_seg to random # from index_lo to index_hi-segments
end_seg = start_seg + segments
-- want start_seg and end_seg to be from index_lo to index_hi
segment_range = {start_seg,end_seg}
end -- if/else
return segment_range
end -- function
function printScore(score_label,initial_score,pre_score,post_score,flag_total,flag_iterations)
if flag_total then
if post_score - initial_score > 0 then gain_sign = "+" else gain_sign = "" end
total_string = ", "..gain_sign..string.format("%.3f", post_score - initial_score)
else
total_string = ""
end -- if/else
if flag_iterations then
iterations_string = ") ["..idealize_n.."]"
else
iterations_string = ")"
end -- if/else
if post_score - pre_score > 0 then gain_sign = "+" else gain_sign = "" end
print(score_label..": ",roundScore(post_score), "("..gain_sign..string.format("%.3f", post_score - pre_score)
..total_string..iterations_string.." "..rand_so_far)
end -- function
function printTime()
elapsed_time = os.time() - start_time
seconds = elapsed_time % 60
minutes = ((elapsed_time - seconds) % (60 * 60)) / 60
hours = (elapsed_time - minutes * 60 - seconds) / 3600
print(string.format("Elapsed time: %ih %02im %02is at %s",hours,minutes,seconds,os.date()))
end -- function
function walker()
selection.DeselectAll()
recentbest.Save()
pre_score = current.GetScore()
if flag_verbose > 1 then print("Walker...") end
for i = 1,n do
if not freeze.IsFrozen(i) and not structure.IsLocked(i) then
selection.Select(i)
structure.WiggleSelected(walker_wiggle_iterations)
selection.DeselectAll()
if flag_verbose > 1 then printScore(" Segment "..i,initial_score,pre_score,current.GetScore(),false,false) end
end -- if
end -- for
recentbest.Restore()
post_score = current.GetScore()
if post_score > pre_score then
saveSlot3()
printScore("Walker",initial_score,pre_score,post_score,true,false)
else
if ((flag_verbose > 1) or (flag_verbose == 1 and post_score > pre_score)) then
printScore("Walker",initial_score,pre_score,post_score,true,false)
end -- if
end -- if/else
end -- function
function loopMutate()
recentbest.Save()
pre_score = current.GetScore()
selection.SelectAll()
structure.MutateSidechainsSelected(loop_mutate_iterations)
recentbest.Restore()
post_score = current.GetScore()
if post_score > pre_score then
saveSlot3()
printScore("Loop mutate all",initial_score,pre_score,post_score,true,false)
else
if ((flag_verbose > 1) or (flag_verbose == 1 and post_score > pre_score)) then
printScore("Loop mutate all",initial_score,pre_score,post_score,true,false)
end -- if
end -- if/else
end -- function
function loopWiggle()
recentbest.Save()
pre_score = current.GetScore()
selection.SelectAll()
structure.WiggleSelected(loop_wiggle)
recentbest.Restore()
post_score = current.GetScore()
if post_score > pre_score then
saveSlot3()
printScore("Loop wiggle all",initial_score,pre_score,post_score,true,false)
else
if ((flag_verbose > 1) or (flag_verbose == 1 and post_score > pre_score)) then
printScore("Loop wiggle all",initial_score,pre_score,post_score,true,false)
end -- if
end -- if/else
end -- function
function fuze()
recentbest.Save()
pre_score = current.GetScore()
selection.SelectAll()
behavior.SetClashImportance(0.1*pre_ci)
structure.ShakeSidechainsSelected(fuze_shake_iterations)
behavior.SetClashImportance(0.6*pre_ci)
structure.WiggleSelected(fuze_wiggle_iterations)
behavior.SetClashImportance(1*pre_ci)
structure.WiggleSelected(fuze_wiggle_iterations)
fuze1_score = current.GetScore()
recentbest.Restore()
post_score = current.GetScore()
if post_score > pre_score then
saveSlot3()
if post_score > fuze1_score then
fuze1_score = post_score
end -- if
end -- if
behavior.SetClashImportance(0.6*pre_ci)
structure.WiggleSelected(fuze_wiggle_iterations)
behavior.SetClashImportance(1*pre_ci)
structure.ShakeSidechainsSelected(fuze_shake_iterations)
structure.WiggleSelected(fuze_wiggle_iterations)
selection.DeselectAll()
behavior.SetClashImportance(1*pre_ci)
fuze2_score = current.GetScore()
recentbest.Restore()
post_score = current.GetScore()
if post_score > pre_score then
if post_score > fuze2_score then
fuze2_score = post_score
end -- if
end -- if
if post_score > pre_score then
saveSlot3()
printScore("Fuze",initial_score,pre_score,post_score,true,false)
else
if flag_verbose > 1 then
printScore("Fuze",initial_score,pre_score,post_score,true,false)
end -- if
end -- if/else
if ((flag_verbose > 1) or (flag_verbose == 1 and post_score > pre_score)) then
printScore(" Step 1",initial_score,pre_score,fuze1_score,false,false)
if fuze1_score > pre_score then pre_score = fuze1_score end
printScore(" Step 2",initial_score,pre_score,fuze2_score,false,false)
end -- if
end -- function
function askDialog()
local ask = dialog.CreateDialog(recipe_name_preset)
ask.loopLimit = dialog.AddSlider("Loop limit", loop_limit, 0, 50, 0)
ask.loopLength = dialog.AddSlider("Loop length", loop_length, 1, 100, 0)
ask.index_lo = dialog.AddSlider("Min segment #", index_lo, 1, n-1, 0)
ask.index_hi = dialog.AddSlider("Max segment #", index_hi, 2, n, 0)
-- Idealize
ask.segmentsLabel = dialog.AddLabel("Minimum & maximum selected segments for idealize")
ask.minSegments = dialog.AddSlider("Min Segments", min_segments, 2, 30, 0)
ask.maxSegments = dialog.AddSlider("Max Segments", max_segments, 2, 30, 0)
ask.skipWiggle = dialog.AddCheckbox("Skip main wiggles",skip_wiggle)
ask.skipIdealize = dialog.AddCheckbox("Skip main idealizes",skip_idealize)
-- Wiggle all after idealize
ask.flagIdealizeWiggleAll = dialog.AddCheckbox("Wiggle all after each idealize",flag_idealize_wiggle_all)
-- Walker after each loop
ask.flagWalker = dialog.AddCheckbox("Walker after loop",flag_walker)
-- Wiggle all after each loop
ask.flagLoopWiggle = dialog.AddCheckbox("Wiggle all after each loop",flag_loop_wiggle)
-- Fuze
ask.flagLoopFuze = dialog.AddCheckbox("Fuze after loop",flag_loop_fuze)
-- Mutate
if flag_mutable_puzzle then
ask.flagIdealizeMutate = dialog.AddCheckbox("Mutate selected after each idealize",flag_idealize_mutate)
ask.flagLoopMutate = dialog.AddCheckbox("Mutate all after each loop",flag_loop_mutate)
end -- if
-- Verbose
ask.verboseLabel1 = dialog.AddLabel("Verbose mode:")
ask.verboseLabel2 = dialog.AddLabel(" 0 = off, 1 = when gained, 2 = always, 3 = for debugging")
ask.flagVerbose = dialog.AddSlider("Verbose mode", flag_verbose, 0, 3, 0)
if note_segment > 0 then
ask.flagNote = dialog.AddCheckbox("Save result as note in segment "..note_segment,flag_note)
else
flag_note = false
end -- if/else
-- Keep Bands/Freeze/CI
if flag_bands then ask.flagBands = dialog.AddCheckbox("Keep bands",keep_bands) end
if flag_freeze then ask.flagFreeze = dialog.AddCheckbox("Keep frozen",keep_frozen) end
if flag_ci then ask.flagCI = dialog.AddCheckbox("Keep clash importance",keep_ci) end
ask.rand_seed = dialog.AddTextbox("rand_seed: ",rand_seed)
ask.rand_so_far = dialog.AddTextbox("rand_so_far: ",rand_so_far)
-- Buttons
ask.Fast = dialog.AddButton("Fast", 2)
ask.Normal = dialog.AddButton("Slow", 3)
ask.Slow = dialog.AddButton("Slower", 4)
ask.OK = dialog.AddButton("OK", 1)
ask.Cancel = dialog.AddButton("Cancel", 0)
dialog_show_ask = dialog.Show(ask)
min_segments = ask.minSegments.value
max_segments = ask.maxSegments.value
if min_segments > max_segments then
min_segments = ask.maxSegments.value
max_segments = ask.minSegments.value
end
loop_limit = ask.loopLimit.value
loop_length = ask.loopLength.value
index_lo = ask.index_lo.value
index_hi = ask.index_hi.value
if index_lo > index_hi then
index_lo = ask.index_hi.value
index_hi = ask.index_lo.value
elseif index_lo == index_hi then
if index_hi < n then
index_hi = index_hi + 1
elseif index_lo > 1 then
index_lo = index_lo - 1
else
print("ERROR: for "..n.." segments, min segment # = "..index_lo.." while max segment # = "..index_hi)
end -- if index_hi
end -- if index_lo
skip_wiggle=ask.skipWiggle.value
skip_idealize=ask.skipIdealize.value
flag_idealize_wiggle_all = ask.flagIdealizeWiggleAll.value
flag_walker = ask.flagWalker.value
flag_loop_wiggle = ask.flagLoopWiggle.value
flag_loop_fuze = ask.flagLoopFuze.value
if flag_mutable_puzzle then
flag_idealize_mutate = ask.flagIdealizeMutate.value
flag_loop_mutate = ask.flagLoopMutate.value
end -- if
flag_verbose = ask.flagVerbose.value
if note_segment > 0 then
flag_note = ask.flagNote.value
end -- if
if flag_bands then keep_bands = ask.flagBands.value end
if flag_freeze then keep_frozen = ask.flagFreeze.value end
if flag_ci then keep_ci = ask.flagCI.value end
local res
for res in string.gmatch(ask.rand_seed.value,'[%s%a]*([%d%-%+]+)') do
rand_seed=res
end
for res in string.gmatch(ask.rand_so_far.value,'[%s%a]*([%d%-%+]+)') do
rand_so_far=res
end
rand_seed = rand_seed + 0 -- force rand_seed to be a number
-- below forces rand_so_far to be a non-negative integer
rand_so_far = rand_so_far + 0 -- force rand_so_far to be a number
if rand_so_far < 0 then rand_so_far = 0 end
if rand_so_far ~= math.floor(rand_so_far) then rand_so_far = math.floor(rand_so_far) end
return dialog_show_ask
end -- function
function getrange(i1,i2,resstr)
local res=(i1..'-'..i2)
if i1<=i2 then
local i
local aastr=''
local ssstr=''
for i=i1,i2 do
aastr=(aastr..structure.GetAminoAcid(i))
ssstr=(ssstr..structure.GetSecondaryStructure(i))
end -- for i
res=(res..' ('..aastr..'='..ssstr..')')
end -- if i1<=i2
if string.len(resstr)>0 then
res=(res..' '..resstr)
end -- if length
return res
end -- function
function save4debug(tmpstr)
local savescore,loadscore
savescore=current.GetScore()
save.Quicksave(debug_slot)
save.Quickload(debug_slot)
loadscore=current.GetScore()
print(string.format('Saved/Loaded %.3f/%.3f to/from slot %d, changing score by %.3e.',roundScore(savescore),roundScore(loadscore),debug_slot,(loadscore-savescore)))
print(tmpstr..' from score '..roundScore(loadscore)..':')
end -- function
function randomIdealize()
show_dialog = default_preset
repeat
if show_dialog == 2 then setFast()
elseif show_dialog == 3 then setSlow()
elseif show_dialog == 4 then setSlower() end
show_dialog = askDialog()
until show_dialog < 2 -- repeat
-- AAA code was moved below 10/30/14
-- start of AAA code
-- quit when not enough segments
if freeze.GetCount() == n then
print("Puzzle is frozen.")
return
end -- if
not_locked_segments = notLockedAdjacentSegments()
if #not_locked_segments == 0 then
print("There are not enough segments.")
return
end -- if
-- end of AAA code
if show_dialog > 0 then
if isFast() then recipe_name_preset = recipe_name.." Fast"
elseif isSlow() then recipe_name_preset = recipe_name.." Slow"
elseif isSlower() then recipe_name_preset = recipe_name.." Slower"
else recipe_name_preset = recipe_name.." Custom" end
selection.DeselectAll()
if (flag_bands and not keep_bands) then band.DeleteAll() end
if (flag_freeze and not keep_frozen) then freeze.UnfreezeAll() end
if (flag_ci and not keep_ci) then
pre_ci = 1
behavior.SetClashImportance(1)
end -- if (flag_ci
if not flag_mutable_puzzle then
flag_idealize_mutate = false
flag_loop_mutate = false
end -- if not
print(recipe_name_preset)
print("")
print('Doing puzzle '..puzzle.GetName()..' with ID '..puzzle.GetPuzzleID())
print(' '..n..' segments, initial score='..roundScore(initial_score)..', ci='..round3(pre_ci)..', and ')
print(' '..band.GetCount()..' user-supplied bands at '..os.date())
print("Best solution is stored in slot 3")
if flag_verbose > 2 then print('Latest solution is stored in slot '..debug_slot) end
if flag_note then print("Save result as note in segment "..note_segment) end
saveSlot3()
if loop_limit > 1 then print(loop_limit.." Loops with "..loop_length.." idealizes each")
elseif loop_limit == 1 then print("1 Loop with "..loop_length.." idealizes")
else print("No loop limit, "..loop_length.." idealizes each loop") end
print("Will process segments "..index_lo.." to "..index_hi.." of 1 to "..n)
print("Minimum to maximum selected segments: "..min_segments..'-'..max_segments)
if skip_wiggle then print("Skip main wiggles") end
if skip_idealize then print("Skip main idealizes") end
if flag_idealize_wiggle_all then print("Wiggle all after each idealize") end
if flag_walker then print("Walker after loop") end
if flag_loop_wiggle then print("Wiggle all after each loop") end
if flag_loop_fuze then print("Fuze after loop") end
if flag_idealize_mutate then print("Mutate selected after each idealize") end
if flag_loop_mutate then print("Mutate all after each loop") end
if flag_verbose == 1 then print("Verbose mode: when gained") end
if flag_verbose == 2 then print("Verbose mode: always") end
if flag_verbose == 3 then print("Verbose mode: for debugging") end
print('rand_seed='..rand_seed..' and rand_so_far='..rand_so_far)
math.randomseed(rand_seed)
-- below lists rand_so_far random #'s from 0 to 9
-- to help adjust rand_so_far when repeating runs
local res
local resstr=''
for i=1,rand_so_far do
res = math.random(0,9) -- sets res to integer in range [0,9]
resstr=resstr..res
if i<rand_so_far then
if i==50*math.floor(i/50) then -- if i is divisible by 50
resstr=resstr..' = '..(i-49)..'-'..i..'\n '
elseif i==10*math.floor(i/10) then -- if i is divisible by 10
resstr=resstr..' '
end -- if i
end -- if i
end -- for i
if rand_so_far>0 then
print('Skipping first '..rand_so_far..' random numbers from 0 to 9:\n '..resstr)
end -- if rand_so_far
print("")
print("Loop 1 initial score: ",roundScore(initial_score), "(gain, total) [#idealize] rand_so_far")
start_time = os.time()
repeat
loop_n = loop_n + 1
loop_score = current.GetScore()
for j = 1,loop_length do
idealize_n = idealize_n + 1
-- Save
recentbest.Save()
pre_score = current.GetScore()
-- Select
random_adjacent_segments = randomAdjacentSegments(not_locked_segments)
-- next part makes a string of 10 random #'s from 0 to 9
-- to help adjust rand_so_far when repeating runs
resstr=''
for i=1,10 do
res = getrand(0,9) -- sets res to integer in range [0,9]
resstr=resstr..res
end -- for i
start_seg = random_adjacent_segments[1]
end_seg = random_adjacent_segments[2]
range=getrange(start_seg,end_seg,resstr)
selection.DeselectAll()
selection.SelectRange(start_seg,end_seg)
-- Idealize
if not skip_idealize then
if flag_verbose > 2 then save4debug(("Idealizing "..range)) end
structure.IdealizeSelected()
if flag_verbose > 2 then print("Done Idealizing.") end
end
if current.GetScore() > pre_score then saveSlot3() end
if flag_verbose > 0 then idealize_score = current.GetScore() end
-- Mutate
if flag_idealize_mutate then
selection.DeselectAll()
for i = start_seg,end_seg do
if structure.IsMutable(i) then selection.Select(i) end
end -- for i
if flag_verbose > 2 then save4debug(("Mutating "..range)) end
structure.MutateSidechainsSelected(idealize_mutate_iterations)
if flag_verbose > 2 then print("Done Mutating.") end
if current.GetScore() > pre_score then saveSlot3() end
selection.SelectRange(start_seg, end_seg)
if flag_verbose > 0 then mutate_score = current.GetScore() end
end
-- Wiggle
if not skip_wiggle then
if flag_verbose > 2 then save4debug(("Wiggling "..range)) end
structure.WiggleSelected(idealize_wiggle_selected)
if flag_verbose > 2 then print("Done Wiggling.") end
end
if current.GetScore() > pre_score then saveSlot3() end
if flag_verbose > 0 then wiggle_selected_score = current.GetScore() end
if flag_idealize_wiggle_all then
selection.SelectAll()
if not skip_wiggle then
if flag_verbose > 2 then save4debug(("Wiggling All")) end
structure.WiggleSelected(idealize_wiggle_all)
if flag_verbose > 2 then print("Done Wiggling.") end
end
if flag_verbose > 0 then wiggle_all_score = current.GetScore() end
end -- if
segment_score = current.GetScore()
recentbest.Restore()
post_score = current.GetScore()
range = ("Segments "..range)
if post_score > pre_score then
saveSlot3()
printScore(range,initial_score,pre_score,post_score,true,true)
else
save.Quickload(3)
if flag_verbose > 1 then printScore(range,initial_score,pre_score,segment_score,false,true) end
end -- if/else
if ((flag_verbose > 1) or (flag_verbose == 1 and post_score > pre_score)) then
printScore(" Idealize selected",initial_score,pre_score,idealize_score,false,false)
if flag_idealize_mutate then
printScore(" Mutate selected",initial_score,idealize_score,mutate_score,false,false)
idealize_score = mutate_score
end -- if
printScore(" Wiggle selected",initial_score,idealize_score,wiggle_selected_score,false,false)
if flag_idealize_wiggle_all then printScore(" Wiggle all",initial_score,wiggle_selected_score,wiggle_all_score,false,false) end
end -- if
end -- for j
-- Loop walker
if (flag_walker and current.GetScore() - loop_score < trigger_walker) then walker() end
-- Loop mutate all
if flag_loop_mutate then loopMutate() end
-- Loop wiggle all
if flag_loop_wiggle then loopWiggle() end
-- Loop fuze
if (flag_loop_fuze and post_score - fuze_score > trigger_fuze) then
fuze()
fuze_score = current.GetScore() -- reset cumulative gain
end -- if
printScore("Loop "..loop_n,initial_score,loop_score,current.GetScore(),true,true)
printTime()
until loop_n == loop_limit -- repeat
end -- if (no dialog cancel)
end -- main function, randomIdealize()
function cleanbreak()
recentbest.Restore()
selection.DeselectAll()
behavior.SetClashImportance(pre_ci)
if current.GetScore() > pre_score then saveSlot3() else save.Quickload(3) end
printScore("Loop "..loop_n,initial_score,loop_score,current.GetScore(),true,true)
printTime()
end -- function
-- randomIdealize() -- for debugging
xpcall(randomIdealize,cleanbreak) -- no error messages