Code
--[[ Worst Select Best Freeze 1.0
Based on TvdL Show worst subscoring parts
version 1.1.1 - 2014/07/14 - LociOiling
-- add FindActiveSubscores (brutally yank'd from TvdL EDRW)
-- this version of FindActiveSubscores totals subscores for *all* segments
-- add some score and subscore reporting to the dialog
version 1.1.2 - 2014/08/28 LociOiling
-- implement jeff101's suggestions
+ combine subtotals and checkboxes in dialog
+ include more detailed information in recipe output
-- automatically select all subscores if user selects none
-- reduce the scope of key result variables
-- rename confusing or ambiguous variables and functions
version 1.1.3 - 2014/12/22 Bruno Kestemont (obs: name confuzing with another vesion from Locioiling)
-- option to freeze best (not selected) segments
this is nice for original interface, to show on screen the worst/best segments
Note that, on selection interface, you can run actions on the selected worst segs
Worst Select Best Freeze 1.0 Bruno Kestemont
version 1.0 Only changed name.
Tip: first run 20 % and freeze best, then run again and select 10%
]]--
--
-- globals section
--
segCnt = structure.GetCount()
pct = 15
pctBest = 80
Recipe = "Worst Select Best Freeze"
Version = "1.0"
ReVersion = Recipe .. " v." .. Version
FreezeBestSidechains=false
FreezeBestBones=false
RebuildNb=0
WiggleSelectedNb=0
ShakeSelectedNb=0
gTotal = 0 -- grand total all subscores
--
-- end of globals section
--
function round ( x )--cut all afer 3-rd place
return x - x % 0.001
end
function FindActiveSubscores ( show )
local result = {}
local Subs = puzzle.GetPuzzleSubscoreNames ()
for ii = 1, #Subs do
local total = 0
local abstotal = 0
local part
for jj = 1, segCnt do
part = current.GetSegmentEnergySubscore ( jj, Subs [ ii ] )
total = total + part
abstotal = abstotal + math.abs ( part )
end
if abstotal > 10 then
result [ #result + 1 ] = { Subs [ ii ], total }
gTotal = gTotal + total
if show then print ( "Active subscore: " .. Subs [ ii ] .. ", total = " .. round ( total ) ) end
end
end
if show then print ( #result .. " active subscores" ) end
if show then print ( "Total of all subscores: " .. round ( gTotal ) ) end
return result
end
function AskSelScores ( scrParts )
local selParts = {}
local ask = dialog.CreateDialog ( ReVersion )
ask.segcnt = dialog.AddLabel ( segCnt .. " segments" )
ask.active = dialog.AddLabel ( #scrParts .. " active subscores" )
ask.gTotal = dialog.AddLabel ( "Total of all subscores: " .. round ( gTotal ) )
ask.energyscore = dialog.AddLabel ( "current.GetEnergyScore(): " .. round ( current.GetEnergyScore() ) )
if current.GetEnergyScore() ~= current.GetScore() then
ask.score =
dialog.AddLabel ( "current.GetScore(): " .. round ( current.GetScore() ) )
ask.exmult =
dialog.AddLabel ( "current.GetExplorationMultiplier(): " .. round ( current.GetExplorationMultiplier() ) )
end
ask.l0 = dialog.AddLabel ( "Subscore totals (all segments)" )
ask.l1 = dialog.AddLabel ( "Specify which worst subscore totals to count" )
for ii = 1,#scrParts do
ask [ scrParts [ ii ] [ 1 ] ] = dialog.AddCheckbox ( scrParts [ ii ] [ 1 ] .. ": " .. round ( scrParts [ ii ] [ 2 ] ), false )
end
ask.perc = dialog.AddSlider ( "Percent Worst to select:", pct, 1, 100, 0 )
ask.l2 = dialog.AddLabel ( "Show on puzzle:" )
ask.FreezeBestBones = dialog.AddCheckbox ( "Freeze best backbones:", FreezeBestBones)
ask.FreezeBestSidechains = dialog.AddCheckbox ( "Freeze best sidechains:", FreezeBestSidechains)
ask.l3 = dialog.AddLabel ( "What next on selected ?" )
ask.RebuildNb = dialog.AddSlider ( "Rebuild nb:", RebuildNb, 0, 30, 0 )
ask.ShakeSelectedNb = dialog.AddSlider ( "Shake nb:", ShakeSelectedNb, 0, 3, 0 )
ask.WiggleSelectedNb = dialog.AddSlider ( "Wiggle nb:", WiggleSelectedNb, 0, 30, 0 )
ask.OK = dialog.AddButton ( "OK", 1 )
ask.Cancel = dialog.AddButton ( "Cancel", 0 )
if dialog.Show ( ask ) > 0 then
for ii = 1, #scrParts do
if ask [ scrParts [ ii ] [ 1 ] ].value then selParts [ #selParts + 1 ] = scrParts [ ii ] [ 1 ] end
end
--
-- select all if nothing selected
--
if #selParts == 0 then
for ii = 1, #scrParts do
selParts [ #selParts + 1 ] = scrParts [ ii ] [ 1 ]
end
end
pct = ask.perc.value
FreezeBestBones=ask.FreezeBestBones.value
FreezeBestSidechains=ask.FreezeBestSidechains.value
RebuildNb=ask.RebuildNb.value
ShakeSelectedNb=ask.ShakeSelectedNb.value
WiggleSelectedNb=ask.WiggleSelectedNb.value
end
return selParts
end
function Showsels ( selParts )
local sels = ""
for jj = 1, # selParts do
if jj > 1 then sels = sels .. ", " end
sels = sels .. selParts [ jj ]
end
print ( "Selected scoreparts: " .. sels )
end
function Compute ( selParts )
local segscores = {}
for ii = 1, segCnt do
local sub = 0
for jj = 1, #selParts do
sub = sub + current.GetSegmentEnergySubscore ( ii, selParts [ jj ] )
end
segscores [ #segscores + 1 ] = { ii, sub }
end
return segscores
end
function SortScores ( segscores )
table.sort ( segscores, function ( a, b ) return a [ 2 ] < b [ 2 ] end)
return segscores
end
function Showresult ( segscores )
selection.DeselectAll ()
print ( "Selecting " .. pct .. "% of segments" )
print ( "Selecting " .. math.floor ( pct * segCnt / 100 ) .. " out of " .. segCnt .. " segments" )
print ( "Selected segments:" )
local totSelScore = 0
for ii = 1, pct * segCnt / 100 do
selection.Select ( segscores [ ii ] [ 1 ] )
print ( "Segment " .. segscores [ ii ] [ 1 ] .. ", score = " .. round ( segscores [ ii ] [ 2 ] ) )
totSelScore = totSelScore + segscores [ ii ] [ 2 ]
end
if FreezeBestBones or FreezeBestSidechains then
print("Freezing Best segments")
for ii = math.floor ( pct * segCnt / 100 ) +1, segCnt do
local unselectseg=segscores [ ii ] [ 1 ]
if FreezeBestBones then freeze.Freeze(unselectseg, true, false) end
if FreezeBestSidechains then freeze.Freeze(unselectseg, false, true) end
end
end
print ( "Total of selected subscores for selected segments: " .. round ( totSelScore ) )
print ("The worst segments are selected")
end
function AfterSelection()
if RebuildNb >0 then structure.RebuildSelected(RebuildNb) end
if ShakeSelectedNb >0 then structure.ShakeSidechainsSelected(ShakeSelectedNb) end
if WiggleSelectedNb >0 then structure.LocalWiggleSelected(WiggleSelectedNb) end
end
function main ()
print ( ReVersion )
print ( "Puzzle: " .. puzzle.GetName () )
print ( "Track: " .. ui.GetTrackName () )
print ( "Segments: " .. segCnt )
scoreParts = FindActiveSubscores ( true )
print ( "current.GetEnergyScore(): " .. round ( current.GetEnergyScore() ) )
if current.GetEnergyScore() ~= current.GetScore() then
print ( "current.GetScore(): " .. round ( current.GetScore() ) )
print ( "current.GetExplorationMultiplier(): " .. round ( current.GetExplorationMultiplier() ) )
end
selParts = AskSelScores ( scoreParts )
if #selParts > 0 then
local sss= current.GetScore()
local tg=0
local g=1
while g> 0.1 do
local ss= current.GetScore()
Showsels ( selParts )
local segscores = {}
segscores = Compute ( selParts )
segscores = SortScores ( segscores )
Showresult ( segscores )
recentbest.Save()
AfterSelection()
recentbest.Restore()
g= current.GetScore()-ss
print("Gained another "..g.." pts")
print("Now trying score parts one by one")
end
tg= current.GetScore()- sss
print("Total gain= "..tg)
end
cleanup ()
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
end
-- main call
xpcall ( main, cleanup )
--end of script