Icon representing a recipe

Recipe: Rav3n_pl GAB BiS 2.2.3F No Mutate

created by Bruno Kestemont

Profile


Name
Rav3n_pl GAB BiS 2.2.3F No Mutate
ID
102336
Shared with
Public
Parent
Rav3n_pl GAB BiS Filter v2.2.4
Children
None
Created on
January 07, 2019 at 19:01 PM UTC
Updated on
January 07, 2019 at 19:01 PM UTC
Description

Bands! Bands in space! GAB BiS v2. Now it have options dialog! Never mutate (for contests)

Best for


Code


--[[ Bands! Bands in space! GAB - Genetic Algorythm on Bands by Rav3n_pl based on CartoonVillan and Crashguard303 scripts Lua V2 Definitions: band: random band to space from random segment critter: set of bands herd: set of critters 1. - randomize needed bands - randomly assigning them to criters 2. - score each critter 3. - keep critters scoring above score - breed best critters - breed bastards (best one + random one) - forget about rest of critter - randomize new critters to fill herd porky added the filter management BK added more filters on recentbest and save ver 2.02 Filter --debugged line 239 ver 2.03 --debugged filter ver 2.04 --debuggeg monomer ver 2.05 -- just update the commands Get/SetFiltersDisabled ver 2.06 -- debugged generic filter & second dialog ver 2.1 -- second dialog with sliders (no text box). This reduces the range available but it's also more convenient and it avoids user errors ver 2.1.1 Generic filter only after dialog to save time at start ver 2.1.2 Check conditions option on exploration puzzles ver 2.1.3 debugged conditions ver 2.2.0 added Jeff101's display on each loop, and archive in note by pauldunn keep user bands FILTERMANAGE activated (disable filter during wiggle) ver 2.2.1 bug fixed in loop_count ver 2.2.2 added quickshake ver 2.2.3 undo.SetUndo ver 2.2.3 No Mut Never mutate (for contests) ]]-- recipename= "Rav3n_pl GAB BIS 2.2.3 No Mut" p=print userbands=band.GetCount() p("Starting "..recipename.. " on\n puzzle "..(puzzle.GetName())) p(' with puzzle ID '..(puzzle.GetPuzzleID())..' and '..userbands..' user-supplied bands.\n ') ssstr="" -- jeff101 gen=0 --SLOTS: --[[ 3 is best 4 used in recipe 5 used in recipe 50-100 used to record each big steps for movie at the end ]]-- SlotStepStart=50 -- New for SaveBigSteps() SlotStep=SlotStepStart undo.SetUndo(false) --START Translate old filter functions in order to keep original recipe code Bruno Kestemont 7/1/2019 function behavior.GetFiltersDisabled() return not filter.AreAllEnabled() --True if all filters are active end function behavior.SetFiltersDisabled(disabling) local disabling = disabling or true if disabling then filter.DisableAll() --Disables all filters else filter.EnableAll() --Enables all filters end end function behavior.SetSlowFiltersDisabled(disabling) if disabling then filter.DisableAll() --Disables all filters else filter.EnableAll() --Enables all filters end end --END --Translate old filter functions in order to keep original recipe code OriginalFilterSetting = behavior.GetFiltersDisabled() PROBABLEFILTER= false GENERICFILTER=false FILTERMANAGE= false HASMUTABLE= false IDEALCHECK= false PROBABLESYM= false SEPSIS= false ELECTRON= false CENTROID= false HOTSPOT= false EXPLORATION= false conditions=false sym=1 segCnt=structure.GetCount() segCnt2=segCnt while structure.GetSecondaryStructure(segCnt2)=="M" do segCnt2=segCnt2-1 end -- not used yet (ligand) --START extraction of information from puzzle metadata --Extrait des infos function detectfilterandmut() -- Bruno Kestemont 10/10/2013; 13/2/2015; 5/1/2019 local descrTxt=puzzle.GetDescription() local puzzletitle=puzzle.GetName() local function SymetryFinder() -- by Bruno Kestemont 7/2/2013, 25/8/2013 local segMeanScore=(TopScore()-8000)/segCnt -- top score pour eviter les debuts de puzzle --p("Score moyen par segment= "..segMeanScore) if PROBABLESYM then if segMeanScore<33.39 then sym=1 PROBABLESYM=false elseif segMeanScore<85 then sym=2 elseif segMeanScore<132 then sym=3 elseif segMeanScore<197 then sym=4 else sym=5 end else sym=1 end return end if #descrTxt>0 and (descrTxt:find("filter") or descrTxt:find("filters") or descrTxt:find("bonus") or descrTxt:find("bonuses") and not descrTxt:find("disabled"))then PROBABLEFILTER=true FILTERMANAGE=true -- default yes during wiggle (will always be activate when scoring) GENERICFILTER=false -- to be evaluated end if #descrTxt>0 and (descrTxt:find("H-bond networks") or descrTxt:find("Hydrogen Bond Networks") or descrTxt:find("H-bond Networks") or descrTxt:find("H-bond Network") and not descrTxt:find("disabled"))then PROBABLEFILTER=true FILTERMANAGE=false -- default no GENERICFILTER=false -- to be evaluated end if #descrTxt>0 and (descrTxt:find("design") or descrTxt:find("designs")) then HASMUTABLE=true IDEALCHECK=true HANDFOLD=true end if #descrTxt>0 and (descrTxt:find("De-novo") or descrTxt:find("de-novo") or descrTxt:find("freestyle") or descrTxt:find("prediction") or descrTxt:find("predictions")) then IDEALCHECK=true HANDFOLD=true end if #puzzletitle>0 then if (puzzletitle:find("Sym") or puzzletitle:find("Symmetry") or puzzletitle:find("Symmetric") or puzzletitle:find("Dimer") or puzzletitle:find("Trimer") or puzzletitle:find("Tetramer") or puzzletitle:find("Pentamer")) then PROBABLESYM=true if puzzletitle:find("Dimer") and not puzzletitle:find("Dimer of Dimers") then sym=2 elseif puzzletitle:find("Trimer") or puzzletitle:find("trimer") then sym=3 elseif puzzletitle:find("Dimer of Dimers") or puzzletitle:find("Tetramer") then sym=4 elseif puzzletitle:find("Pentamer") then sym=5 else SymetryFinder() end end end if #descrTxt>0 and (descrTxt:find("Sym") or descrTxt:find("Symmetry") or descrTxt:find("Symmetric") or descrTxt:find("sym") or descrTxt:find("symmetry") or descrTxt:find("symmetric")) then PROBABLESYM=true if (descrTxt:find("Dimer") or descrTxt:find("dimer") or descrTxt:find("C2 symmetry") or descrTxt:find("twoo symmetric")) and not (descrTxt:find("Dimer of Dimers") or descrTxt:find("dimer of dimers")) then sym=2 elseif descrTxt:find("Trimer") or descrTxt:find("trimer") or descrTxt:find("C3 symmetry") or descrTxt:find("three symmetric") then sym=3 elseif (descrTxt:find("Dimer of Dimers") or descrTxt:find("Tetramer") or descrTxt:find("C4 symmetry") or descrTxt:find("four symmetric")) and not (descrTxt:find("dimer of dimers") or descrTxt:find("tetramer"))then sym=4 elseif descrTxt:find("Pentamer") or descrTxt:find("pentamer") or descrTxt:find("C5 symmetry") or descrTxt:find("five symmetric") then sym=5 else SymetryFinder() end end --print resulting sym info if PROBABLESYM then print("Symmetric") if sym==2 then print("Dimer") elseif sym==3 then print("Trimer") elseif sym==4 then print("Tetramer") elseif sym==5 then print("Pentamer") elseif sym>5 then print("Terrible polymer") end else print("Monomer") end if #puzzletitle>0 and puzzletitle:find("Sepsis") then -- new BK 17/6/2013 SEPSIS=true HANDFOLD=true --p(true,"-Sepsis") print("Sepsis") end if #puzzletitle>0 and puzzletitle:find("Electron Density") then -- for Electron Density --p(true,"-Electron Density") ELECTRON=true HANDFOLD=true print("Electron density") end if #puzzletitle>0 and puzzletitle:find("Centroid") then -- New BK 20/10/2013 --p(true,"-Centroid") CENTROID=true print("Centroid") end if #puzzletitle>0 and puzzletitle:find("Hotspot") then -- New BK 21/01/2014 HOTSPOT=true print("Hotspot") end return end detectfilterandmut() --END extraction of information from puzzle metadata --Extrait des infos --START Generic Filter Management by BitSpawn 21/12/2014 --Source: http://fold.it/portal/node/1998917 -- Handy shorts module Original version by BitsPawn (WARNING: filter translator above is now necessary). GENERICFILTER=false -- duplicate because it has to be in generic filter management -- function to copy class/table function CopyTable(orig) local copy = {} for orig_key, orig_value in pairs(orig) do copy[orig_key] = orig_value end return copy end -- functions for filters function FiltersOn() if behavior.GetFiltersDisabled() then behavior.SetFiltersDisabled(false) end end function FiltersOff() if behavior.GetFiltersDisabled()==false then behavior.SetFiltersDisabled(true) end end -- function to overload a funtion function mutFunction(func) local currentfunc = func local function mutate(func, newfunc) local lastfunc = currentfunc currentfunc = function(...) return newfunc(lastfunc, ...) end end local wrapper = function(...) return currentfunc(...) end return wrapper, mutate end -- function to overload a class -- to do: set the name of function classes_copied = 0 myclcp = {} function MutClass(cl, filters) classes_copied = classes_copied+1 myclcp[classes_copied] = CopyTable(cl) local mycl =myclcp[classes_copied] for orig_key, orig_value in pairs(cl) do myfunc, mutate = mutFunction(mycl[orig_key]) if filters==true then mutate(myfunc, function(...) FiltersOn() if table.getn(arg)>1 then -- first arg is self (function pointer), we pack from second argument local arguments = {} for i=2,table.getn(arg) do arguments[i-1]=arg[i] end return mycl[orig_key](unpack(arguments)) else --print("No arguments") return mycl[orig_key]() end end) cl[orig_key] = myfunc else mutate(myfunc, function(...) FiltersOff() if table.getn(arg)>1 then local arguments = {} for i=2, table.getn(arg) do arguments[i-1]=arg[i] end return mycl[orig_key](unpack(arguments)) else return mycl[orig_key]() end end) cl[orig_key] = myfunc end end end -- how to use: --setting default options if filters BK 4/2/2015 --MutClass(structure, false) --MutClass(band, false) --MutClass(current, true) function GenericFilterMngt() if GENERICFILTER then -- WARNING: TO VERIFY !! (may be it's irreversible for several funtions bellow) MutClass(structure, false) MutClass(band, false) MutClass(current, true) MutClass(recentbest, true) -- otherwise, it remembers cut solutions MutClass(save, true) -- better to save with full score end end --STOP Generic Filter Management --START SET NOTES BY PD --[[ Set note with author, recipe and big steps -- By Pauldunn This subroutine is used in much group recipe versions in various groups originally in Go Science It traces the various recipes and players that improved the current solution Module to quick copy-paste it in existing recipes, by Bruno Kestemont ]]-- --HOW TO include in a recipe? --1a) COPY from here ================ function InitNotes(recipename) local recipename=recipename or "" note_number=structure.GetCount() for seg=structure.GetCount(),1,-1 do if structure.GetNote(seg)~="" then break end note_number=seg end print(string.format("Recording "..recipename.." results in Note for segment %i",note_number)) starting_score=current.GetScore() --structure.SetNote(note_number,string.format("(%s) %.3f + %s(%i) %.3f",user.GetPlayerName(),starting_score,recipename,loop_count,current.GetScore())) end function SetNote(note_number, starting_score, recipename, loop_count) local recipename=recipename or "" local starting_score=starting_score or 0 local loop_count=loop_count or 1 --print(string.format("Recording "..recipename.." results in Note for segment %i",note_number)) structure.SetNote(note_number,string.format("(%s) %.3f + %s(%i) %.3f",user.GetPlayerName(),starting_score,recipename,loop_count,current.GetScore())) end InitNotes(recipename) -- WARNING: and match "recipename" with the recipename of the recipe --1b) COPY to here. ================ -- options: energy=false --set true to seek energy in exploration puzzles; false works on all puzzles pullCI=0.9 --Clash Impotrance during pull shakeCI=0.21 --CI when shake on qstab or mutate once maxCI=1 --maximum CI used by script fastQstab=true -- only 1s1w after pull if true fuzeThresh = 1 -- run fuze if we are close to best score (negative=new best score) qstabThresh=1 -- run qstab if score drops more than... wiggle only in other case onlyMutable=true --if true use ONLY all mutable aas, no matter of always use mutateOnce=false --if true use mutate(1) instead of shake in qstab mutateAlwas=false --if true use muatate(1) instead of all shakes herd= --herd options { breedBest = 5, --breed best 4 critters - all combinations => 6 kids form 4 critters, 3 form 3, 1 form 2, 9 form 5 ;] keepBest = 3, --save up to 3 best scoring critters, rest are forgotten breedBastards = 8, --number of best will have one random bastard newRandom = 10, --adding new random ones each generation maxGen= 1000, --maximum generations shuffle = true, --set true to run critters in random order renew=4, --create totally fresh herd after that many gens w/o improvement } critter= --critter options { minBands=3, --minimum bands maxBands=7, --maximum bands keepScore = 0 , --survive to next gen only if score higher than breedScore=-20, --will breed kids only if score higher. Basttards always breed maxLoss=30, --maximum loss by critter. set 0 to disable } bands= --bands options { minStr=0.3, --minimum band str maxStr=1.1, --maximum band str maxUp = 12.1, -- maximum band lenght minUp = 0.1 -- debugging case=0 } DoNotUse={--just comment lines below or add more areas to avoid --{segCnt,segCnt}, --ligand cant be used --{120,134}, --{1,10}, } AlwaysUse={ --areas should be always used --{238,238}--ligand need to be at one end --{308,311}, --loopy --{272,319}, --loopy } UseSegments= --use ONLY this segments { --2,3,4,5 } -- bands by secondary structure use= { Sheet=true, --set false to not band sheets Helix=true, --set false to not band helices Loop=true, --set false to not band loops } --end of options --START quick save algorithm function QuickShake() --[[------------------------------------------------------------------------------------------------ -- Algorithm for faster shake REFERENCES 1. N/A Copyright (C) 2014 Seagat2011 <http://fold.it/port/user/1992490> This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. $Id$ ------------------------------------------------------------------------------------------------]]-- --[[ v1 - Inception 1.2 - Loops until nogain ]]-- local idx = 1 local idx2 = structure.GetCount () local hash = {} local cs = current.GetScore () --print ( 'Quick Shake Algorithm v1.2 SG2011 - Current Score: '..cs ) local function New ( obj ) return obj -- pass-new-obj-by-value end local _gses = New ( current.GetSegmentEnergySubscore ) local function SmartShake ( iters ) local gain = true while (gain) do gain = false for i=idx,idx2 do local ci = _gses ( i,'clashing' ) if ci < _gses ( i,'hiding' ) and ci < _gses ( i,'packing' ) and ci < _gses ( i,'ideality' ) and ci < _gses ( i,'sidechain') and ci < _gses ( i,'bonding' ) and ci < _gses ( i,'other' ) and ci < _gses ( i,'reference') then selection.Select ( i ) end -- test ci -- end -- loop -- if selection.GetCount () then local css = current.GetScore () structure.ShakeSidechainsSelected ( iters ) selection.DeselectAll () if current.GetScore () > css then gain = true end -- test -- end -- test -- end -- loopf -- end structure.SmartShake = SmartShake structure.SmartShake ( 1 ) --print ( 'Done.' ) end --END quick save algorithm function CI(c) if c>maxCI then c=maxCI end behavior.SetClashImportance(c) end function round(x)--cut all afer 3-rd place return x-x%0.001 end function down(x) return x-x%1 end function Score()--return score, exploration too if energy==true then return current.GetEnergyScore() else return current.GetScore() end end --local seed=recipe.GetRandomSeed() --NOT WORKING!!! --calculate REALLY good seed seed=os.time()/math.abs(Score()) seed=seed%0.001 seed=1/seed while seed<10000000 do seed=seed*1000 end seed=seed-seed%1 p("Seed is: "..seed) math.randomseed(seed) --REALLY good seed made by rav3n_pl :P --[[ original Wiggle function Wiggle(how, iters, minppi) if how==nil then how="wa" end if iters==nil then iters=3 end if minppi==nil then minppi=0.3 end if iters>0 then iters=iters-1 sp=Score() if how == "s" then if mutateAlwas==true then structure.MutateSidechainsSelected(1) else structure.ShakeSidechainsSelected(1) end elseif how == "wb" then structure.WiggleAll(25, true,false) elseif how == "ws" then structure.WiggleAll(25, false,true) elseif how == "wa" then structure.WiggleAll(25, true,true) end ep = Score() ig=ep-sp if how~="s" then if ig > minppi then return Wiggle(how, iters, minppi) end --tail call end end end ]]-- function Wiggle(how, iters, minppi) -- NEW one, with filter management, 17/4/2016 if FILTERMANAGE then behavior.SetSlowFiltersDisabled(true) end-- new BK 8/4/2013, always disable filter here if how==nil then how="wa" end if iters==nil then iters=6 end if minppi==nil then minppi=0.1 end if iters>0 then iters=iters-1 sp=Score() if how == "s" then if FILTERMANAGE then behavior.SetSlowFiltersDisabled(OriginalFilterSetting) end -- new BK 8/4/2013, always back to user settings if mutateAlwas==true then structure.MutateSidechainsSelected(1) --else structure.ShakeSidechainsSelected(1) end else QuickShake() end elseif how == "wb" then structure.WiggleAll(2, true,false) elseif how == "ws" then structure.WiggleAll(2, false,true) elseif how == "wa" then structure.WiggleAll(2) end ep = Score() ig=ep-sp if how~="s" then if ig > minppi then return Wiggle(how, iters, minppi) end --tail call end end if FILTERMANAGE then behavior.SetSlowFiltersDisabled(OriginalFilterSetting) end -- new BK 10/10/2013, always back to user settings end function SaveBest() local g=Score()-bestScore if not (conditions and not current.AreConditionsMet) then if g>0 then if g>0.01 then p("Gained another "..round(g).." pts.") end bestScore=Score() save.Quicksave(3) end else print("Conditions not met. Returning to former solution") -- for DEBUG end end function SaveRB() if recentbest.GetScore()>bestScore or (recentbest.GetEnergyScore()>bestScore and energy==true)then if not (conditions and not current.AreConditionsMet) then save.Quicksave(4) recentbest.Restore() SaveBest() save.Quickload(4) end end end function Qstab() selection.SelectAll() CI(shakeCI) if mutateOnce==true then structure.MutateSidechainsSelected(1) else Wiggle("s",1) end if fastQstab==false then CI(0.4) Wiggle("wa",1) CI(1) Wiggle("s",1) end CI(1) Wiggle() end function FuzeEnd() CI(1) Wiggle("wa",1) Wiggle("s",1) Wiggle() srb() end function Fuze1(ci1,ci2) CI(ci1) Wiggle("s",1) CI(ci2) Wiggle("wa",1) end function Fuze2(ci1,ci2) CI(ci1) Wiggle("wa",1) CI(1) Wiggle("wa",1) CI(ci2) Wiggle("wa",1) end function srb() recentbest.Restore() SaveBest() end function Fuze() p("Fuzing...") local scr=Score() selection.SelectAll() recentbest.Save() Fuze1(0.3,0.6) FuzeEnd() Fuze2(0.3,1) srb() Fuze1(0.05,1) srb() Fuze2(0.7,0.5) FuzeEnd() Fuze1(0.07,1) srb() end function random(n1,n2) --random function returns int or float depends on input vars if n1==nil then return math.random() else if n2==nil then if n1%1==0 then return math.random(n1) --integer else return math.random()*n1 --float end else if n1%1==0 and n2%1==0 then return math.random(n1,n2) --integer between else return math.random()*(n2-n1)+n1 --float between end end end end function FillHerd() --fill up herd local n=#critters if n>0 then --fill up n=herd.newRandom else --fresh herd n=herd.breedBest + herd.keepBest + herd.breedBastards end p("Randomizing "..n.." new critters...") for i=1,n do AddCritter() end end function AddCritter() --vreate new random critter local c={} critterID=critterID+1 c.no=critterID c.name=c.no..'-rnd' c.bands={} local r=random(critter.minBands, critter.maxBands) for i=1,r do c.bands[#c.bands+1]=AddBand() end critters[#critters+1]=c p(c.name.." bands: "..#c.bands) end function AddBand() --create one random band local cnt=0 local b={} while true do --try till die cnt=cnt+1 local s1=random(segCnt) if onlyMutable==true or #UseSegments>0 then s1=UseSegments[random(#UseSegments)] end if #UseSegments>0 or CanBeUsed(s1) then local str=random(bands.minStr,bands.maxStr) local length=random(bands.minUp,bands.maxUp) --debugged BK 15/2/2015, length cannot be 0 local theta = math.acos(math.random()) local phi = 2 * math.pi * math.random() local segmentXAxis=0 local segmentYAxis=0 while true do --all 3 must be different segmentXAxis = random(segCnt) segmentYAxis = random(segCnt) if segmentXAxis~=s1 and segmentYAxis~=s1 and segmentXAxis~=segmentYAxis then break end end --{segmentOrigin, segmentXAxis, segmentYAxis, rho, theta, phi} b={s1, segmentXAxis, segmentYAxis, length, theta, phi, str} break end if cnt>100 then p("Sorry! Cant create band! Breaking script!") BreakScript() --there is no such function, so it crashes script end end return b end function deletebands() --leave user bands intact nbands=band.GetCount() if nbands>userbands then for i=nbands,userbands+1,-1 do -- count down from nbands to userbands+1 band.Delete(i) end -- for i end -- if nbands end -- function function CanBeUsed(sg1) --checking end of bands function ssCheck(ss) local good=false if use.Sheet and ss=="E" then good=true end if use.Helix and ss=="H" then good=true end if use.Loop and ss=="L" then good=true end return good end local ok=true if #DoNotUse>0 then --none of 2 can be in that area for i=1, #DoNotUse do local r=DoNotUse[i] -- r={from,to} for x=r[1],r[2] do if x==sg1 then ok=false break end end if ok==false then break end end end if ok==false then return false --if false can`t be used else ok=false if #AlwaysUse>0 then --at least one have to be there for i=1, #AlwaysUse do local r=AlwaysUse[i] for x=r[1],r[2] do if x==sg1 then ok=true break end end if ok==true then break end end else ok=true end end if ok==true then --check structure ok=false if ssCheck(structure.GetSecondaryStructure(sg1)) then ok=true end end return ok end function ScoreHerd() --score all critters from herd save.Quickload(3) p("Scoring "..#critters.." critters...") save.Quicksave(5) local herdScore=Score() for i=1,#critters do --band.DeleteAll() deletebands() local crt=critters[i] --critter local s=Score() --start score local bnds=crt.bands for b=1,#bnds do local bnd=bnds[b] local atom=5 local sn=bnd[1] if sn==segCnt then atom=6 end --bug in last segment if structure.GetAminoAcid(sn)=='g' then atom=0 end --glycyne band.Add(sn,bnd[2],bnd[3],bnd[4],bnd[5],bnd[6],atom) local bc=band.GetCount() band.SetStrength(bc,bnd[7]) end selection.SelectAll() CI(pullCI) recentbest.Save() Wiggle("wb",1) --band.DeleteAll() deletebands() CI(1) if s-Score() > qstabThresh then Qstab() else Wiggle() end if Score()-bestScore>fuzeThresh then SaveRB() Fuze() else SaveRB() end crt.score=Score()-s p("Critter "..crt.name.." : "..round(crt.score)) if critter.maxLoss>0 then if Score()>herdScore-critter.maxLoss then save.Quicksave(5) herdScore=Score() else save.Quickload(5) end else save.Quickload(3) end end save.Quickload(3) if band.GetCount()>0 then --clean bands from best solution (if any) --band.DeleteAll() deletebands() save.Quicksave(3) end end function BreedCritters(mom,dad,t) --breed 2 critters. bands are taken randomly local kid={} critterID=critterID+1 kid.no=critterID kid.name=kid.no.."-"..t..mom.no..'/'..dad.no kid.bands={} local mb=#mom.bands local db=#dad.bands if mb>db then mb,db=db,mb end --kid have bands count between mom and dad bands local bn=random(mb,db) for i=1,bn,2 do kid.bands[#kid.bands+1]=mom.bands[random(#mom.bands)] kid.bands[#kid.bands+1]=dad.bands[random(#dad.bands)] end p(kid.name.." bands: "..#kid.bands) return kid end function KeepGood() --copy best scoring critters form last gen if score above local newHerd={} for i=1,herd.keepBest do if critters[i].score>critter.keepScore then newHerd[#newHerd+1]=critters[i] end end return newHerd end function SortCritters() --bubble sort for i=1,#critters do for j=i+1,#critters do if critters[i].score<critters[j].score then critters[i],critters[j]=critters[j],critters[i] --love lua :) end end end end function BreedHerd() p("Breeding...") SortCritters() newHerd=KeepGood() for i=1, herd.breedBest do local mom=critters[i] if mom.score>critter.breedScore or i<2 then --breed only good ones, 1st is always breed anyway for j=i+1, herd.breedBest do local dad=critters[j] newHerd[#newHerd+1]=BreedCritters(mom,dad,"kid-") newHerd[#newHerd+1]=BreedCritters(dad,mom,"kid-") end end end for i=1, herd.breedBastards do --they will always appear ;] local mom=critters[i] local j=random(herd.breedBastards+1,#critters) local dad=critters[j] newHerd[#newHerd+1]=BreedCritters(mom,dad,"bas-") newHerd[#newHerd+1]=BreedCritters(dad,mom,"bas-") end critters=newHerd FillHerd() end function ShuffleHerd() if herd.shuffle==true then for i=1,#critters do local r=random(#critters) if r~=i then critters[i],critters[r]=critters[r],critters[i] end end end end function GAB() if onlyMutable==true then for i=1,segCnt do if structure.IsMutable(i) then UseSegments[#UseSegments+1]=i end end end critterID=0 gen=0 ss=Score() bestScore=ss save.Quicksave(3) recentbest.Save() p("Rav3n_pl Bands! Bands in space! GAB BiS") p("Start score: "..round(ss)) if energy then energy=false ssNormal=Score() p("Normal score: "..round(ssNormal).. " Conditions= "..ss-ssNormal) energy=true end critters={} FillHerd() badGen=0 ssstr=(ssstr..round(ss)) -- jeff101 while true do --this is (almost) endless script ;] undo.SetUndo(false) -- reset each loop if gain will give a long list of interesting undos genScore=Score() gen=gen+1 p() p("Generation: "..gen..", score: "..round(Score())..", gain: "..round(Score()-ss)) ShuffleHerd() ScoreHerd() save.Quickload(3) if gen==herd.maxGen then break end --end of script if genScore<=Score() then badGen=badGen+1 else badGen=0 end if badGen>=herd.renew then p("Creating fresh random herd...") critters={} FillHerd() badGen=0 else BreedHerd() end -- START jeff101's display genEndScore=Score() genGain=genEndScore-genScore if gen>1 and (gen-1)==5*down((gen-1)/5) then -- New 18/1/2016 jeff101 log display ssstr=(ssstr..'\n ') -- start new line every 5 generations end if genGain>=0 then ssstr=(ssstr..' + '..round(genGain)) undo.SetUndo(true) else ssstr=(ssstr..' - '..(-round(genGain))) end p(ssstr..' = '..round(genEndScore)) --END jeff101's display --3a) COPY from here --------------- loop_count=gen SetNote(note_number, starting_score, recipename, loop_count) -- WARNING: and mach "recipename" and "loop_count" with the names of the recipe --3b) COPY to here -------------- SaveBigSteps() -- for movie at the end end p("Final score: "..round(Score()).." Total gain: "..round(Score()-ss)) end --START Movie store big steps StepScore= Score() -- New 4/11/2014 function StoreBigStep() StepScore= Score() save.Quicksave(SlotStep) SlotStep=SlotStep+1 end function SaveBigSteps() -- in order to be able to display big steps afterwards in undos local g=Score()-StepScore local s= Score() if s >0 and ( (s <7000 and g>500) or (s <9000 and g>200) or (s <10000 and g>100) or (s >10000 and g>50)) then StoreBigStep() end end function MovieSteps() undo.SetUndo(true) for i= SlotStepStart, SlotStep do save.Quickload(SlotStep) end --save.Quickload(3) print("See remembering of big steps in undos") end --END Movie store big steps function Cleanup(err) -- NEW BK 10/10/2013 start,stop,line,msg=err:find(":(%d+):%s()") err=err:sub(msg,#err) print('---') if err:find('Cancelled')~=nil then print("User stop.") else print("unexpected error detected.") --p("Error line: %i.") --p("Error : %s.") p("Error line: ", line) p("Error: ", err) end print("Restoring CI, best result, filter and structures") CI(1) undo.SetUndo(true) if FILTERMANAGE then behavior.SetSlowFiltersDisabled(OriginalFilterSetting) end -- always back to user settings StoreBigStep() MovieSteps() save.Quickload(3) --3a) COPY from here --------------- loop_count=gen SetNote(note_number, starting_score, recipename, loop_count) -- WARNING: and mach "recipename" and "loop_count" with the names of the recipe --3b) COPY to here -------------- deletebands() -- WARNING must be defined anywhere !! print(err) end function dialogOptions() local mut=false for i=1,segCnt do --if structure.IsMutable(i) then mut=true break end end if not mut then onlyMutable=false mutateOnce=false end opt = dialog.CreateDialog("Main Options") opt.lbl1 = dialog.AddLabel("GAB BiS main options:") opt.gen = dialog.AddTextbox("Generations:", herd.maxGen) opt.pull= dialog.AddSlider("Pulling CI", pullCI, 0.05, 1, 2)--desctip, default, min, max, precision opt.shak= dialog.AddSlider("Shake CI", shakeCI, 0.01, 1, 2) opt.maxci= dialog.AddSlider("Maximum CI", maxCI, 0.05, 1, 2) opt.qstab=dialog.AddCheckbox("FastQstab", fastQstab) opt.energy=dialog.AddCheckbox("Seek energy", energy) -- will be better on on exploration puzzles opt.mutonly=dialog.AddCheckbox("Only mutable", onlyMutable) --opt.mutonce=dialog.AddCheckbox("Mutate once", mutateOnce) --opt.mutalways=dialog.AddCheckbox("Mutate always", mutateAlwas) opt.fuzeth=dialog.AddTextbox("Fuze threshold: ",fuzeThresh) opt.qsth=dialog.AddTextbox("Qstab threshold: ",qstabThresh) if EXPLORATION then opt.conditions=dialog.AddCheckbox("Check conditions", conditions) end if PROBABLEFILTER then opt.FILTERMANAGE=dialog.AddCheckbox("Fast filter during wiggle only: ",FILTERMANAGE) opt.GENERICFILTER=dialog.AddCheckbox("Fast filter unless for score: ",GENERICFILTER) end opt.run = dialog.AddButton("Start", 1) opt.more = dialog.AddButton("More", 2) opt.cancel = dialog.AddButton("Cancel (???)", 0) res=dialog.Show(opt) if res>0 then energy=opt.energy.value pullCI=opt.pull.value shakeCI=opt.shak.value maxCI=opt.maxci.value fastQstab=opt.qstab.value fuzeThresh = tonumber(opt.fuzeth.value) qstabThresh= tonumber(opt.qsth.value) onlyMutable=opt.mutonly.value --mutateOnce=opt.mutonce.value --mutateAlwas=opt.mutalways.value herd.maxgen=tonumber(opt.gen.value) if PROBABLEFILTER then FILTERMANAGE=opt.FILTERMANAGE.value GENERICFILTER=opt.GENERICFILTER.value end if EXPLORATION then conditions=opt.conditions.value end if res==2 then opt = dialog.CreateDialog("More Options") opt.lbl1 = dialog.AddLabel("Herd:") opt.brbest=dialog.AddSlider("Breed best", herd.breedBest, 1, 20, 0) opt.kbest=dialog.AddSlider("Keep best", herd.keepBest, 1, 20, 0) opt.bas=dialog.AddSlider("Breed bastards", herd.breedBastards, 1, 20, 0) opt.rnd=dialog.AddSlider("New random", herd.newRandom, 1, 30, 0) opt.renew=dialog.AddSlider("Renew hers", herd.renew, 1, 10, 0) opt.shuff=dialog.AddCheckbox("Shuffle critters", herd.shuffle) opt.lbl2 = dialog.AddLabel("Critter:") opt.minb=dialog.AddSlider("Minimum bands:", critter.minBands, 1,4,0) opt.maxb=dialog.AddSlider("Maximum bands:", critter.maxBands,4,50,0) opt.keeps=dialog.AddSlider("Keep score:", critter.keepScore, -10, 10, 0) opt.breeds=dialog.AddSlider("Breed score:", critter.breedScore, -40, 10,0) opt.maxloss=dialog.AddSlider("Max loss:", critter.maxLoss, 0,50,0) opt.lbl4 = dialog.AddLabel("(0 to disable max loss)") opt.lbl3 = dialog.AddLabel("Bands:") opt.minst=dialog.AddSlider("Min str", bands.minStr, 0.1, 2, 1) opt.maxst=dialog.AddSlider("Max str", bands.maxStr, 0.2, 2, 1) opt.maxup=dialog.AddSlider("Max lenght", bands.maxUp, 1, 20, 0) opt.run = dialog.AddButton("Start", 1) dialog.Show(opt) herd.breedBest = opt.brbest.value herd.keepBest = opt.kbest.value herd.breedBastards = opt.bas.value herd.newRandom = opt.rnd.value herd.shuffle = opt.shuff.value herd.renew=opt.renew.value critter.minBands=tonumber(opt.minb.value) critter.maxBands=tonumber(opt.maxb.value) critter.keepScore = tonumber(opt.keeps.value) critter.breedScore=tonumber(opt.breeds.value) critter.maxLoss=tonumber(opt.maxloss.value) bands.minStr=opt.minst.value bands.maxStr=opt.maxst.value bands.maxUp = opt.maxup.value end else p("Exiting...") BreakScript() end end -- main call function MAIN() dialogOptions() GenericFilterMngt() GAB() end xpcall(MAIN,Cleanup) --end of script

Comments