Code
--[[
Rav3n_pl Fuzes
Fuzes for Exploration v1
Combination of Blufuze and Pinkfuze looped till any gain
Can be used in normal puzzles too
Options at end
Script is using save slot 3 and recent best
version 1.3 - 2014/05/22 - LociOiling
-- add dialog
* minimum points per loop
* wiggle factor
-- add cleanup
-- convert to V2
-- remove tail calls (short tails best)
-- add model reporting - see "model" comments
version 1.4 - 2014/07/07 - LociOiling
-- refine model reporting
-- add CSV (spreadsheet) output option
version 1.5 - 2014/09/05 - LociOiling
-- minor revisions to model reporting
version 1.5.1 - 2014/10/13 - LociOiling
-- no functional changes, updated for visibility
-- see "Model Recipes", http://foldit.wikia.com/wiki/Model_Recipes
]]--
--
-- globals section
--
--
-- model 001 -- standard recipe name and version
--
Recipe = "Rav3n_pl Fuzes"
Version = "1.5.1"
ReVersion = Recipe .. " v." .. Version
-- options VVVV
normal = true --set false to seek energy in exploration puzzles
daCapo = 2 --minimum gain from loop to run again
WF = 2 -- wiggle factor
useIRFF = false
IRFF = 0.05 -- irreproducible random fuzz factor
-- end of options ^^^^^^
p = print
CI = behavior.SetClashImportance
segCnt = structure.GetCount()
bestScore = 0
startChunque = nil -- initial chunquePoint
--
-- end of globals section
--
-- Module Random
-- Tvdl, 01-11-2012
function Seedrandom()
math.randomseed ( os.time() % 1000000 )
math.random ( 100 ) -- Because the first is not random
end
Seedrandom()
function Score ()
if normal == true then
return current.GetScore ()
else
return current.GetEnergyScore ()
end
end
function round ( x )--cut all afer 3-rd place
return x - x % 0.001
end
function Wiggle ( how, iters, minppi )
if how == nil then
how = "wa"
end
if iters == nil then
iters = 6
end
if minppi == nil then
minppi = 0.1
end
local sp = 0
local ep = 0
local ig = 0
repeat
sp = Score ()
iters = iters - 1
if how == "s" then
structure.ShakeSidechainsAll ( 1 )
elseif how == "wb" then
structure.WiggleAll ( 2 * WF, true, false )
elseif how == "ws" then
structure.WiggleAll ( 2 * WF, false, true )
elseif how == "wa" then
structure.WiggleAll ( 2 * WF, true, true )
end
ep = Score ()
ig = ep - sp
until how == "s" or ( iters <= 0 or ig < minppi )
end
function SaveBest ()
local gGain = Score () - bestScore
if gGain > 0 then
--
-- model 060 - report significant gains
--
if gGain > 0.001 then
print ( "Gained another " .. round ( gGain ) .. ", score = " .. round ( Score() ) )
end
bestScore = Score ()
save.Quicksave ( 3 )
else
save.Quickload ( 3 )
end
end
function doRFF ( iCI )
local oCI
if useIRFF and iCI < 1.0 then
tRFF = math.random ( IRFF * 100 ) / 100
if math.random () > 0.5 then
oCI = iCI + tRFF
else
oCI = iCI - tRFF
end
if oCI > 1 then
oCI = 1
end
if oCI < 0 then
oCI = 0
end
--print ( "CI adjusted from " .. round ( iCI ) .. " to " .. round ( oCI ) )
else
oCI = iCI
end
return oCI
end
function FuzeEnd ()
CI ( 1 )
Wiggle ( "wa", 1 )
Wiggle ( "s", 1 )
Wiggle ()
recentbest.Restore ()
SaveBest ()
end
function Fuze1 ( ci1, ci2 )
CI ( doRFF ( ci1 ) )
Wiggle ( "s", 1 )
CI ( doRFF ( ci2 ) )
Wiggle ( "wa", 1 )
end
function Fuze2 ( ci1, ci2 )
CI ( doRFF ( ci1 ) )
Wiggle ( "wa", 1 )
CI ( 1 )
Wiggle ()
CI ( doRFF ( ci2 ) )
Wiggle ( "wa", 1 )
end
--
-- begin chunquePoint Beta package version 0.2
--
CSVoutput = false
function beginChunque ( startChunque, prefix, scoreFunc, pose )
local chunque = chunquePoint ( prefix, scoreFunc, pose )
if startChunque == nil then
chunquePrint ( chunque )
else
local gain = chunque [ 2 ] - startChunque [ 2 ]
chunquePrint ( chunque, gain )
end
return chunque
end
function endChunque ( startChunque, prefix, scoreFunc, pose )
local chunque = chunquePoint ( prefix, scoreFunc, pose )
chunqueGain ( startChunque, chunque )
end
function chunquePoint ( prefix, scoreFunc, pose )
if prefix == nil then
prefix = ""
end
if scoreFunc == nil then
scoreFunc = current.GetEnergyScore
end
local score = 0
if pose == nil then
score = scoreFunc ()
else
score = scoreFunc ( pose )
end
local runDate, runClock, runTime
runDate = os.date ()
runClock = os.clock()
runTime = os.time()
return { prefix, score, runDate, runClock, runTime }
end
function chunquePrint ( chunque, gain )
local function round ( ii )
return ii - ii % 0.001
end
if gain == nil then
if CSVOutput then
print ( chunque [ 1 ] .. "," ..
round ( chunque [ 2 ] ) .. "," ..
chunque [ 3 ]
)
else
print ( chunque [ 1 ] .. ", score: " ..
round ( chunque [ 2 ] ) .. ", " ..
chunque [ 3 ]
)
end
else
if CSVOutput then
print ( chunque [ 1 ] .. "," ..
round ( chunque [ 2 ] ) .. "," ..
round ( gain ) .. "," ..
chunque [ 3 ]
)
else
print ( chunque [ 1 ] .. ", score: " ..
round ( chunque [ 2 ] ) .. ", total gain: " ..
round ( gain ) .. ", " ..
chunque [ 3 ]
)
end
end
end
function chunqueGain ( startChunk, endChunk )
local function round ( ii )
return ii - ii % 0.001
end
local Clocktime = os.difftime ( endChunk [ 5 ], startChunk [ 5 ] )
local gain = round ( endChunk [ 2 ] - startChunk [ 2 ] )
local hours = Clocktime / ( 60 * 60 )
local pph = gain / hours
if CSVOutput then
print ( endChunk [ 1 ] .. "," ..
round ( endChunk [ 2 ] ) .. "," ..
round ( gain ) .. "," ..
round ( hours ) .. "," ..
round ( pph ) .. "," ..
endChunk [ 3 ]
)
else
print ( endChunk [ 1 ] .. ", score: " ..
round ( endChunk [ 2 ] ) .. ", gain: " ..
round ( gain ) .. ", " ..
endChunk [ 3 ]
)
print ( endChunk [ 1 ] .. ", hours: " ..
round ( hours ) .. ", points per hour: " ..
round ( pph ) )
end
end
--
-- end chunquePoint Beta package version 0.2
--
function GetParams ()
local dlg = dialog.CreateDialog ( ReVersion )
dlg.daCapo = dialog.AddSlider ( "minimum gain" , daCapo, 0.1, 25, 1 )
dlg.WF = dialog.AddSlider ( "Wiggle Factor" , WF, 1, 5, 0 )
dlg.useIRFF = dialog.AddCheckbox ( "Use CI fuzz factor?" , useIRFF )
dlg.IRFF = dialog.AddSlider ( "CI fuzz factor" , IRFF, 0.00, 0.50, 2 )
dlg.CSVOutput = dialog.AddCheckbox ( "CSV output?" , CSVOutput )
dlg.ok = dialog.AddButton ( "OK", 1 )
dlg.cancel = dialog.AddButton ( "Cancel", 0 )
if dialog.Show ( dlg ) > 0 then
daCapo = dlg.daCapo.value
WF = dlg.WF.value
useIRFF = dlg.useIRFF.value
IRFF = dlg.IRFF.value
CSVOutput = dlg.CSVOutput.value
return true
end
return false
end
function Fuzes ()
if GetParams () then
--
-- model 010 - startup - print recipe name, puzzle name, track
--
print ( ReVersion )
print ( "Puzzle: " .. puzzle.GetName () )
print ( "Track: " .. ui.GetTrackName () )
--
-- model 020 - startup - print recipe parms
--
print ( "options:" )
print ( "minimum gain per cycle = " .. daCapo )
print ( "Wiggle Factor = " .. WF )
if ( useIRFF ) then
print ( "max fuzz factor = " .. IRFF )
end
print ( "--" )
local startScore = Score ()
--
-- model 030 - startup - print start time, start score
--
startChunque = beginChunque ( nil, "Start", Score )
bestScore = Score ()
save.Quicksave ( 3 )
selection.SelectAll ()
recentbest.Save ()
local fuzeCount = 1
repeat
local ss = Score ()
--
-- model 040 - start cycle - print cycle #, current score
--
local runName = "Fuze run " .. fuzeCount
local begChunque = beginChunque ( startChunque, runName, Score )
--
-- pink fuse
--
print ( "Run " .. fuzeCount .. ", Fuze 1/6" ) --model 050 - log major sections
Fuze1 ( 0.3, 0.6 )
FuzeEnd ()
print ( "Run " .. fuzeCount .. ", Fuze 2/6" ) --model 050 - log major sections
Fuze2 ( 0.5, 0.7 )
FuzeEnd ()
print ( "Run " .. fuzeCount .. ", Fuze 3/6" ) --model 050 - log major sections
Fuze2 ( 0.7, 0.5 )
FuzeEnd ()
--
-- blue fuse
--
print ( "Run " .. fuzeCount .. ", Fuze 4/6" ) --model 050 - log major sections
Fuze1 ( 0.05, 1 )
recentbest.Restore ()
SaveBest ()
print ( "Run " .. fuzeCount .. ", Fuze 5/6" ) --model 050 - log major sections
Fuze1 ( 0.07, 1 )
recentbest.Restore ()
SaveBest ()
print ( "Run " .. fuzeCount .. ", Fuze 6/6" ) --model 050 - log major sections
Fuze2 ( 0.3, 1 )
recentbest.Restore ()
SaveBest ()
local runGain = Score () - ss
--
-- model 070 - end cycle - print cycle #, time, gain
--
endChunque ( begChunque, "end run " .. fuzeCount, Score )
fuzeCount = fuzeCount + 1
until runGain < daCapo
--
-- model 090 - exit via the cleanup routine
--
cleanup ()
end
end
function cleanup ( error )
print ( "---" )
--
-- model 100 - print recipe name, puzzle, track, time, score, and gain
--
local reason
local start, stop, line, msg
if error == nil then
reason = "complete"
else
--
-- model 120 - civilized error reporting,
-- thanks to Bruno K. and Jean-Bob
--
start, stop, line, msg = error:find ( ":(%d+):%s()" )
if msg ~= nil then
error = error:sub ( msg, #error )
end
if error:find ( "Cancelled" ) ~= nil then
reason = "cancelled"
else
reason = "error"
end
end
print ( ReVersion .. " " .. reason )
print ( "Puzzle: " .. puzzle.GetName () )
print ( "Track: " .. ui.GetTrackName () )
if reason == "error" then
print ( "Unexpected error detected" )
print ( "Error line: " .. line )
print ( "Error: \"" .. error .. "\"" )
end
--
-- model 130 - reset clash importance, clear selections, restore structures, etc.
--
behavior.SetClashImportance ( 1 )
selection.DeselectAll ()
if error ~= nil then
save.Quickload ( 3 )
end
--
-- model 150 - report the final time, score, gain, elapsed time, and points per hour
--
if startChunque ~= nil then
endChunque ( startChunque, "Final", Score )
end
end
-- main call
xpcall ( Fuzes, cleanup )
--end of script