Code
--
-- bandit
--
-- test banding, optionally disabling undo and filters
--
-- adapted from "peg frozen segments PD" -- original by Paul Dunn
--
-- bandit adds a zero-length spaceband to the backbone of every
-- segments of the protein, timing the whole operation
--
-- for the specified number of loops, bandit tries the combinations
-- of enabling and disabling undo and filters
--
-- at the end, bandit prints out the total time, number of runs,
-- and mean (average) time for each case, using tab-delimited
-- format (CSV) suitable for pasting into a spreadsheet
--
-- bandit also prints the settings and time for each individual test
--
--
Recipe = "bandit"
Version = "1.0"
ReVersion = Recipe .. " " .. Version
lastseg = structure.GetCount()
disable_undo = false
disable_filters = false
cases = {
{ noUndo = false, noFilters = false, totTime = 0, totRuns = 0, },
{ noUndo = true, noFilters = true, totTime = 0, totRuns = 0, },
{ noUndo = false, noFilters = true, totTime = 0, totRuns = 0, },
{ noUndo = true, noFilters = false, totTime = 0, totRuns = 0, },
}
loops = 100
runs = {}
STW = { -- STW--STW--STW--STW--STW--STW--STW--STW--STW--STW--STW--STW--STW
--[[
stopwatch package version 0.2
]]--
wat = {},
start = function ( self, tag )
if tag == nil or tag == "" then
tag = "default timer"
end
self.wat [ tag ] = { tag = tag, date = os.date (), time = os.time () }
print ( tag .. " started at " .. self.wat [ tag ].date )
end,
stop = function ( self, tag )
if tag == nil or tag == "" then
tag = "default timer"
end
local wot = self.wat [ tag ]
local elapsed = os.difftime ( os.time (), wot.time )
if wot ~= nil then
print ( tag ..
" stopped at "
.. os.date () ..
", clock time = "
.. elapsed ..
" s"
)
return elapsed
else
print ( "stopwatch \"" .. tag .. "\" not found" )
end
end,
} -- STW--STW--STW--STW--STW--STW--STW--STW--STW--STW--STW--STW--STW
function GetOpt ()
local menu = dialog.CreateDialog ( ReVersion )
menu.loops = dialog.AddSlider ( "loops", loops, 1, 250, 0 )
menu.Run = dialog.AddButton ( "Run", 1 )
menu.Cancel = dialog.AddButton ( "Cancel", 0 )
local rc = dialog.Show ( menu )
loops = menu.loops.value
return rc > 0
end
function main ()
STW:start ( "overall process" )
Ident ( ReVersion )
print ( "--" )
if GetOpt () then
--
-- make sure undo and filters are enabled at the start
--
undo.SetUndo ( true )
behavior.SetFiltersDisabled ( false )
for ii = 1, loops do
print ( "loop " .. ii .. "/" .. loops )
for jj = 1, #cases do
print ( "case " .. jj .. "/" .. #cases )
band.DeleteAll ()
local case = cases [ jj ]
if case.noUndo then
undo.SetUndo ( false )
print ( "undo disabled" )
end
if case.noFilters then
behavior.SetFiltersDisabled ( true )
print ( "filters disabled" )
end
STW:start ( "bandit" )
local count = 0
for seg = 1, lastseg do
local segx = seg - 1
local segy = seg + 1
if segx < 1 then
segx = lastseg
end
if segy > lastseg then
segy = 1
end
local b = band.Add ( seg, segx, segy, 1e-10, 0, 0)
if b ~= nil and b ~= 0 then
band.SetGoalLength ( b, 0 )
count = count + 1
end
end
local elapsed = STW:stop ( "bandit" )
case.totTime = case.totTime + elapsed
case.totRuns = case.totRuns + 1
runs [ #runs + 1 ] = { noUndo = case.noUndo, noFilters = case.noFilters, totTime = elapsed }
print ( count .. " bands added" )
if case.noUndo then
undo.SetUndo ( true )
print ( "re-enabled undo" )
end
if case.noFilters then
behavior.SetFiltersDisabled ( false )
print ( "re-enabled filters" )
end
end
end
end
cleanup ()
end
--
-- Ident - print identifying information at beginning and end of recipe
--
-- slugline - first line to print - normally recipe name and version
--
-- v0.2 - LociOiling - 20191118
-- + streamline the format
-- + user.GetGroupName not working, remove
--
function Ident ( slugline )
local function round ( ii )
return ii - ii % 0.001
end
print ( slugline )
print ( "Puzzle: " .. puzzle.GetName () .. " (" .. puzzle.GetPuzzleID () .. ")" )
print ( "Track: " .. ui.GetTrackName () )
--[[
user.GetGroupName not working
local gname = user.GetGroupName ()
if gname ~= nil then
gname = " (" .. gname .. ")"
else
gname = ""
end
print ( "User: " .. user.GetPlayerName () .. gname )
]]--
local luser = user.GetPlayerName ()
local scoretype = scoreboard.GetScoreType ()
local scort = ""
if scoretype == 0 then
scort = "soloist"
elseif scoretype == 1 then
scort = "evolver"
elseif scoretype == 2 then
scort = "all hands"
elseif scoretype == 3 then
scort = "no score"
else
scort = "unknown/error"
end
print ( "User: " .. luser )
print ( "Rank: " .. scoreboard.GetRank ( scoretype ) .. " (" .. scort .. ")" )
local sGroup = scoreboard.GetGroupScore ()
if sGroup ~= nil then
print ( "Group rank / score: " .. scoreboard.GetGroupRank () .. " / " .. round ( 10 * ( 800 - sGroup ) ) )
end
end
function cleanup ( errmsg )
if CLEANUPENTRY ~= nil then
return
end
CLEANUPENTRY = true
print ( "---" )
local reason
local start, stop, line, msg
if errmsg == nil then
reason = "complete"
else
--
-- model 120 - civilized error reporting,
-- thanks to Bruno K. and Jean-Bob
--
start, stop, line, msg = errmsg:find ( ":(%d+):%s()" )
if msg ~= nil then
errmsg = errmsg:sub ( msg, #errmsg )
end
if errmsg:find ( "Cancelled" ) ~= nil then
reason = "cancelled"
else
reason = "error"
end
end
--
-- model 100 - print recipe name, puzzle, track, time, score, and gain
--
Ident ( ReVersion .. " " .. reason )
if reason == "error" then
print ( "Unexpected error detected" )
print ( "Error line: " .. line )
print ( "Error: \"" .. errmsg .. "\"" )
end
--
-- model 130 - reset clash importance, clear selections, restore structures, etc.
--
print ( "banding results" )
print ( "--" )
print ( "case" .. "\t" .. "disable undo" .. "\t" .. "disable filters" .. "\t" .. "total time" .. "\t" .. "runs" .. "\t" .. "mean time" )
for ii = 1, #cases do
local case = cases [ ii ]
local ps = ii .. "\t" .. tostring ( case.noUndo ) .. "\t" .. tostring ( case.noFilters ) .. "\t"
if case.totRuns > 0 then
local meantime = case.totTime / case.totRuns
ps = ps .. case.totTime .. "\t" .. case.totRuns .. "\t" .. meantime
else
ps = ps .. 0 .. "\t" .. 0 .. "\t" .. 0
end
print ( ps )
end
print ( "--" )
print ( "test" .. "\t" .. "disable undo" .. "\t" .. "disable filters" .. "\t" .. "total time" )
for ii = 1, #runs do
local run = runs [ ii ]
local ps = ii .. "\t" .. tostring ( run.noUndo ) .. "\t" .. tostring ( run.noFilters ) .. "\t" .. run.totTime
print ( ps )
end
print ( "--" )
STW:stop ( "overall process" )
end
xpcall ( main, cleanup )