Icon representing a recipe

Recipe: move tester 1.0

created by LociOiling

Profile


Name
move tester 1.0
ID
102440
Shared with
Public
Parent
None
Children
None
Created on
August 03, 2017 at 01:17 AM UTC
Updated on
August 03, 2017 at 01:17 AM UTC
Description

Test Foldit Lua functions for their impact on the move count in sketchbook puzzles.

Best for


Code


--[[ move tester Painfully call each Foldit function interactively to assess the impact on the move count for sketchbook puzzles. Reset the puzzle before running the recipe. Open the "conditions satisfied" dropdown and adjust the display until you can see the "move count limit" filter. Run the recipe. You'll be prompted to continue after each Foldit Lua function. Some functions are skipped for various reasons, including: * print * dialog functions * pose restore functions like recentbest.Restore * unimplemented functions For most functions, the "moves remaining" count should remain unchanged. The functions that change the move count are the interesting ones. Unfortunately, there's no automated to check the move count. The recipe adds a default band and makes a default selection. The initial pose, including the added band, are saved in quicksave slot 1. Before each function, slot 1 is restored, and the default selection of segments 2 through 9 is applied. The Foldit functions are called using the pcall function. The pcall return code and first function return value are logged. The functions which count for moves are: behavior.SetFiltersDisabled rotamer.SetRotamer save.LoadSecondaryStructure structure.InsertCut structure.LocalWiggleAll structure.LocalWiggleSelected structure.MutateSidechainsAll structure.MutateSidechainsSelected structure.RebuildSelected structure.RemixSelected structure.ShakeSidechainsAll structure.ShakeSidechainsSelected structure.WiggleAll structure.WiggleSelected ]]-- Recipe = "move tester" Version = "1.0" ReVersion = Recipe .. " v." .. Version -- -- a quick-and-dirty list of arguments which should work for most puzzles -- some arguments are used in rather a loose way -- -- the goal is just to call each function without an error -- oneseg = { 1 } onesegs = { 1, "s" } onesegh = { 1, "H" } onerot = { 1, 1 } onesegbool = { 1, true, true } justs = { "s" } justh = { "H" } twoseg = { 1, 20 } scorepart = { 1, "hiding" } bandit = {} bandito = {} bandite = {} bandgeo = { 1, 20, structure.GetCount (), 20, 3.14 / 2, 3.14 } slotnum = { 10 } ssl = { "L" } onego = { 1 } troof = { false } noted = { 1, "this is some note text" } twonum = { 3.14, 3.1415 } remmy = { 2, 10 } -- -- function table -- -- For each function, the first entry indicates whether to test the function. -- -- The second entry is the display name of the function. -- -- The third entry is the callable name of the function, which becomes the first -- argument to pcall. -- -- The fourth entry is the argument list. If this is not nil, the value is passed to -- pcall through the unpack function. -- funcx = { { false, "print", print, nil, }, { true, "absolutebest.AreConditionsMet", absolutebest.AreConditionsMet, nil, }, { true, "absolutebest.GetEnergyScore", absolutebest.GetEnergyScore, nil, }, { true, "absolutebest.GetExplorationMultiplier", absolutebest.GetExplorationMultiplier, nil, }, { true, "absolutebest.GetScore", absolutebest.GetScore, nil, }, { true, "absolutebest.GetSegmentEnergyScore", absolutebest.GetSegmentEnergyScore, oneseg, }, { true, "absolutebest.GetSegmentEnergySubscore", absolutebest.GetSegmentEnergySubscore, scorepart, }, { false, "absolutebest.Restore", absolutebest.Restore, nil, }, { true, "band.Add", band.Add, bandgeo, }, { true, "band.AddBetweenSegments", band.AddBetweenSegments, twoseg, }, { true, "band.AddToBandEndpoint", band.AddToBandEndpoint, bandite, }, { true, "band.Delete", band.Delete, bandit, }, { true, "band.DeleteAll", band.DeleteAll, nil, }, { true, "band.Disable", band.Disable, bandit, }, { true, "band.DisableAll", band.DisableAll, nil, }, { true, "band.Enable", band.Enable, bandit, }, { true, "band.EnableAll", band.EnableAll, nil, }, { true, "band.GetCount", band.GetCount, nil, }, { true, "band.GetGoalLength", band.GetGoalLength, bandit, }, { true, "band.GetLength", band.GetLength, bandit, }, { true, "band.GetStrength", band.GetStrength, bandit, }, { true, "band.IsEnabled", band.IsEnabled, bandit, }, { true, "band.SetGoalLength", band.SetGoalLength, bandito, }, { true, "band.SetStrength", band.SetStrength, bandito, }, { false, "behavior.GetBandStrengthFactor", behavior.GetBandStrengthFactor, nil, }, { false, "behavior.GetBuriedSidechainShakeAccuracy", behavior.GetBuriedSidechainShakeAccuracy, nil, }, { true, "behavior.GetClashImportance", behavior.GetClashImportance, nil, }, { false, "behavior.GetExposedSidechainShakeAccuracy", behavior.GetExposedSidechainShakeAccuracy, nil, }, { true, "behavior.GetFiltersDisabled", behavior.GetFiltersDisabled, nil, }, { false, "behavior.GetShakeAccuracy", behavior.GetShakeAccuracy, nil, }, { false, "behavior.GetSlowFiltersDisabled", behavior.GetSlowFiltersDisabled, nil, }, { false, "behavior.GetWiggleAccuracy", behavior.GetWiggleAccuracy, nil, }, { false, "behavior.SetBandStrengthFactor", behavior.SetBandStrengthFactor, nil, }, { false, "behavior.SetBuriedSidechainShakeAccuracy", behavior.SetBuriedSidechainShakeAccuracy, nil, }, { true, "behavior.SetClashImportance", behavior.SetClashImportance, onego, }, { false, "behavior.SetExposedSidechainShakeAccuracy", behavior.SetExposedSidechainShakeAccuracy, onego, }, { true, "behavior.SetFiltersDisabled", behavior.SetFiltersDisabled, troof, }, { false, "behavior.SetShakeAccuracy", behavior.SetShakeAccuracy, nil, }, { false, "behavior.SetSlowFiltersDisabled", behavior.SetSlowFiltersDisabled, nil, }, { false, "behavior.SetWiggleAccuracy", behavior.SetWiggleAccuracy, nil, }, { true, "contactmap.GetHeat", contactmap.GetHeat, twoseg, }, { true, "contactmap.IsContact", contactmap.IsContact, twoseg, }, { true, "creditbest.AreConditionsMet", creditbest.AreConditionsMet, nil, }, { true, "creditbest.GetEnergyScore", creditbest.GetEnergyScore, nil, }, { true, "creditbest.GetExplorationMultiplier", creditbest.GetExplorationMultiplier, nil, }, { true, "creditbest.GetScore", creditbest.GetScore, nil, }, { true, "creditbest.GetSegmentEnergyScore", creditbest.GetSegmentEnergyScore, oneseg, }, { true, "creditbest.GetSegmentEnergySubscore", creditbest.GetSegmentEnergySubscore, scorepart, }, { false, "creditbest.Restore", creditbest.Restore, nil, }, { true, "current.AreConditionsMet", current.AreConditionsMet, nil, }, { true, "current.GetEnergyScore", current.GetEnergyScore, nil, }, { true, "current.GetExplorationMultiplier", current.GetExplorationMultiplier, nil, }, { true, "current.GetScore", current.GetScore, nil, }, { true, "current.GetSegmentEnergyScore", current.GetSegmentEnergyScore, oneseg, }, { true, "current.GetSegmentEnergySubscore", current.GetSegmentEnergySubscore, scorepart, }, { false, "dialog.AddButton", dialog.AddButton, nil, }, { false, "dialog.AddCheckbox", dialog.AddCheckbox, nil, }, { false, "dialog.AddLabel", dialog.AddLabel, nil, }, { false, "dialog.AddSlider", dialog.AddSlider, nil, }, { false, "dialog.AddTextbox", dialog.AddTextbox, nil, }, { false, "dialog.CreateDialog", dialog.CreateDialog, nil, }, { false, "dialog.Show", dialog.Show, nil, }, { true, "freeze.Freeze", freeze.Freeze, onesegbool, }, { true, "freeze.FreezeAll", freeze.FreezeAll, nil, }, { true, "freeze.FreezeSelected", freeze.FreezeSelected, twoseg, }, { true, "freeze.GetCount", freeze.GetCount, nil, }, { true, "freeze.IsFrozen", freeze.IsFrozen, oneseg, }, { true, "freeze.Unfreeze", freeze.Unfreeze, onesegbool, }, { true, "freeze.UnfreezeAll", freeze.UnfreezeAll, nil, }, { true, "puzzle.GetDescription", puzzle.GetDescription, nil, }, { true, "puzzle.GetExpirationTime", puzzle.GetExpirationTime, nil, }, { true, "puzzle.GetName", puzzle.GetName, nil, }, { true, "puzzle.GetPuzzleID", puzzle.GetPuzzleID, nil, }, { true, "puzzle.GetPuzzleSubscoreNames", puzzle.GetPuzzleSubscoreNames, nil, }, { false, "puzzle.StartOver", puzzle.StartOver, nil, }, { true, "recentbest.AreConditionsMet", recentbest.AreConditionsMet, nil, }, { true, "recentbest.GetEnergyScore", recentbest.GetEnergyScore, nil, }, { true, "recentbest.GetExplorationMultiplier", recentbest.GetExplorationMultiplier, nil, }, { true, "recentbest.GetScore", recentbest.GetScore, nil, }, { true, "recentbest.GetSegmentEnergyScore", recentbest.GetSegmentEnergyScore, oneseg, }, { true, "recentbest.GetSegmentEnergySubscore", recentbest.GetSegmentEnergySubscore, scorepart, }, { false, "recentbest.Restore", recentbest.Restore, nil, }, { true, "recentbest.Save", recentbest.Save, nil, }, { true, "recipe.CompareNumbers", recipe.CompareNumbers, twonum, }, { true, "recipe.GetRandomSeed", recipe.GetRandomSeed, nil, }, { false, "recipe.ReportStatus", recipe.ReportStatus, nil, }, { false, "recipe.SectionEnd", recipe.SectionEnd, nil, }, { false, "recipe.SectionStart", recipe.SectionStart, nil, }, { true, "rotamer.GetCount", rotamer.GetCount, oneseg, }, { true, "rotamer.SetRotamer", rotamer.SetRotamer, onerot, }, { true, "save.LoadSecondaryStructure", save.LoadSecondaryStructure, nil, }, { false, "save.Quickload", save.Quickload, nil, }, { false, "save.Quicksave", save.Quicksave, nil, }, { true, "save.QuicksaveEmpty", save.QuicksaveEmpty, slotnum, }, { true, "save.SaveSecondaryStructure", save.SaveSecondaryStructure, nil, }, { true, "scoreboard.GetGroupRank", scoreboard.GetGroupRank, nil, }, { true, "scoreboard.GetGroupScore", scoreboard.GetGroupScore, nil, }, { true, "scoreboard.GetRank", scoreboard.GetRank, nil, }, { true, "scoreboard.GetScore", scoreboard.GetScore, nil, }, { true, "scoreboard.GetScoreType", scoreboard.GetScoreType, nil, }, { true, "selection.Deselect", selection.Deselect, oneseg, }, { true, "selection.DeselectAll", selection.DeselectAll, nil, }, { true, "selection.GetCount", selection.GetCount, nil, }, { true, "selection.IsSelected", selection.IsSelected, oneseg, }, { true, "selection.Select", selection.Select, oneseg, }, { true, "selection.SelectAll", selection.SelectAll, nil, }, { true, "selection.SelectRange", selection.SelectRange, twoseg, }, { true, "structure.CanMutate", structure.CanMutate, onesegs, }, { true, "structure.DeleteCut", structure.DeleteCut, oneseg, }, { true, "structure.DeleteResidue", structure.DeleteResidue, oneseg, }, { true, "structure.GetAminoAcid", structure.GetAminoAcid, oneseg, }, { true, "structure.GetAtomCount", structure.GetAtomCount, oneseg, }, { true, "structure.GetCount", structure.GetCount, nil, }, { true, "structure.GetDistance", structure.GetDistance, twoseg, }, { true, "structure.GetNote", structure.GetNote, oneseg, }, { true, "structure.GetSecondaryStructure", structure.GetSecondaryStructure, oneseg, }, { true, "structure.IdealizeSelected", structure.IdealizeSelected, nil, }, { true, "structure.InsertCut", structure.InsertCut, oneseg, }, { true, "structure.InsertResidue", structure.InsertResidue, oneseg, }, { true, "structure.IsHydrophobic", structure.IsHydrophobic, oneseg, }, { true, "structure.IsLocked", structure.IsLocked, oneseg, }, { true, "structure.IsMutable", structure.IsMutable, oneseg, }, { true, "structure.LocalWiggleAll", structure.LocalWiggleAll, onego, }, { true, "structure.LocalWiggleSelected", structure.LocalWiggleSelected, onego, }, { true, "structure.MutateSidechainsAll", structure.MutateSidechainsAll, onego, }, { true, "structure.MutateSidechainsSelected", structure.MutateSidechainsSelected, onego, }, { true, "structure.RebuildSelected", structure.RebuildSelected, onego, }, { true, "structure.RemixSelected", structure.RemixSelected, remmy, }, { true, "structure.SetAminoAcid", structure.SetAminoAcid, onesegs, }, { true, "structure.SetAminoAcidSelected", structure.SetAminoAcidSelected, justs, }, { true, "structure.SetNote", structure.SetNote, noted, }, { true, "structure.SetSecondaryStructure", structure.SetSecondaryStructure, onesegh, }, { true, "structure.SetSecondaryStructureSelected", structure.SetSecondaryStructureSelected, justh, }, { true, "structure.ShakeSidechainsAll", structure.ShakeSidechainsAll, onego, }, { true, "structure.ShakeSidechainsSelected", structure.ShakeSidechainsSelected, onego, }, { false, "structure.TweakRotate", structure.TweakRotate, nil, }, { false, "structure.TweakShift", structure.TweakShift, nil, }, { false, "structure.TweakStraighten", structure.TweakStraighten, nil, }, { true, "structure.WiggleAll", structure.WiggleAll, onego, }, { true, "structure.WiggleSelected", structure.WiggleSelected, onego, }, { true, "ui.AlignGuide", ui.AlignGuide, nil, }, { true, "ui.CenterViewport", ui.CenterViewport, nil, }, { true, "ui.GetPlatform", ui.GetPlatform, nil, }, { true, "ui.GetTrackName", ui.GetTrackName, nil, }, { true, "undo.SetUndo", undo.SetUndo, troof, }, { true, "user.GetGroupID", user.GetGroupID, nil, }, { true, "user.GetGroupName", user.GetGroupName, nil, }, { true, "user.GetPlayerID", user.GetPlayerID, nil, }, { true, "user.GetPlayerName", user.GetPlayerName, nil, }, } function More ( slug ) local ask = dialog.CreateDialog ( "More!" ) ask.MORE = dialog.AddLabel ( slug ) ask.OK = dialog.AddButton ( "OK", 1 ) dialog.Show ( ask ) end -- -- make one segment-to-segment band and store its index -- in various argument lists -- function MakeBand () local bndx = band.AddBetweenSegments ( 2, 10 ) bandit [ 1 ] = bndx bandito [ 1 ] = bndx bandito [ 2 ] = 10 bandite [ 1 ] = 1 bandite [ 2 ] = bndx save.Quicksave ( 1 ) end function main () MakeBand () More ( "Begin testing " .. #funcx .. " functions!" ) print ( #funcx .. " functions to test" ) for ii = 1, #funcx do save.Quickload ( 1 ) selection.DeselectAll () selection.SelectRange ( 2, 10 ) if funcx [ ii ] [ 1 ] then print ( "#" .. ii .. ": calling " .. funcx [ ii ] [ 2 ] .. "!" ) local ret, val if funcx [ ii ] [ 4 ] ~= nil then ret, val = pcall ( funcx [ ii ] [ 3 ], unpack ( funcx [ ii ] [ 4 ] ) ) else ret, val = pcall ( funcx [ ii ] [ 3 ] ) end More ( "After # " .. ii .. ": " .. funcx [ ii ] [ 2 ] .. "!" ) print ( "After " .. funcx [ ii ] [ 2 ] .. "!" ) print ( "return code = " .. tostring ( ret ) ) if val ~= nil then print ( "return value = " .. tostring ( val ) ) end else print ( "#" .. ii .. ": skipping " .. funcx [ ii ] [ 2 ] .. "!" ) end end print ( "end of the function table" ) cleanup () end function cleanup ( error ) if CLEANUPENTRY ~= nil then return end CLEANUPENTRY = true 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 () end xpcall ( main, cleanup )

Comments


LociOiling Lv 1

This recipe calls most of the Foldit Lua functions, pausing after each one.

This allows you to look at the "moves remaining count" to see if it has changed. (There's no way to do this automatically.)

To use this recipe, open a sketchbook puzzle and reset the puzzle if you've already worked on it. Open the "conditions satisfied" dropdown and adjust it so you can see the "Move Count Limit" filter.

Run the recipe. Some functions,such as "print", are skipped. The recipe pauses after each function it does test, giving you a chance to see whether the move count has changed.

(Hint: if you drag the "More!" window up near the move count limit filter, it'll will appear there again the next time, making it easier to keep track.)

The functions that change the move count include:

    behavior.SetFiltersDisabled
    rotamer.SetRotamer
    save.LoadSecondaryStructure
    structure.InsertCut
    structure.LocalWiggleAll
    structure.LocalWiggleSelected
    structure.MutateSidechainsAll
    structure.MutateSidechainsSelected
    structure.RebuildSelected
    structure.RemixSelected
    structure.ShakeSidechainsAll
    structure.ShakeSidechainsSelected
    structure.WiggleAll
    structure.WiggleSelected

Most of these are as expected, but save.LoadSecondaryStructure and behavior.SetFiltersDisabled were surprises. Also, the "MutateSidechains" functions count as moves even on puzzles with no mutable sidechains.

LociOiling Lv 1

Filter toggling is free, see the feedback for details. Unfortunately, save.LoadSecondaryStructure still costs, but that one is easy to get around.

The current list of functions which cost is:

    rotamer.SetRotamer
    save.LoadSecondaryStructure
    structure.InsertCut
    structure.LocalWiggleAll
    structure.LocalWiggleSelected
    structure.MutateSidechainsAll
    structure.MutateSidechainsSelected
    structure.RebuildSelected
    structure.RemixSelected
    structure.ShakeSidechainsAll
    structure.ShakeSidechainsSelected
    structure.WiggleAll
    structure.WiggleSelected

Of course, the move tool itself still costs a move each time you touch it, which seems to spoil the "hand folded" ethic of the sketchbook puzzles.

LociOiling Lv 1

Missed these:

structure.IdealizeSelected
structure.InsertResidue
structure.DeleteResidue

Not sure how I missed IdealizeSelected, but InsertResidue and DeleteResidue are rarely used.

Good news, however, InsertResidue and DeleteResidue don't cost anything on puzzles where they don't do anything.