Code
--1st line blank
--jon resetting clash for BWP and other new sliders for AFK too
--begin Josh's Fuse snippet
-- Josh's Fuse - 6 Nov 2020 - see notes at end
--
print ( "Josh's Fuse" )
startScore = current.GetEnergyScore () -- Get the current energy score.
print ( "starting score = " .. startScore ) -- print the starting score
recentbest.Save () -- Save the current pose as the recent best pose.
behavior.SetPackingImportance(0.17)
seventeen = behavior.GetPackingImportance()
behavior.SetPackingImportance(0.18)
eighteen = behavior.GetPackingImportance()
modding = true
if (seventeen == eighteen) then
modding = false
end
function resetBehavior()
behavior.SetClashImportance ( 1.0 )
behavior.SetSidechainHBondImportance ( 1.0 )
behavior.SetBackboneHBondImportance ( 1.0 )
behavior.SetPackingImportance ( 1.0 )
behavior.SetHidingImportance ( 1.0 )
behavior.SetPairwiseImportance ( 1.0 )
end
--end Josh's Fuse snippet
while true do
resetBehavior()
-------begin NN
--keep blank line at top 4 debug
help()
--Fn Down or Up to jump, but creates "," at top
genlimit=10
noAddedMSG=false
deferentialNN=false --no mutate after pick by NN
humble=true --humble=no clover axon
testXor=true
hiddenLayers=3
yellowWood=1 --math.random(
chooseAminos=false--
debugActions=false
askXor=dialog.CreateDialog("Test XOR function?")
askXor.l1=dialog.AddLabel("Exclusive Or function")
askXor.l2=dialog.AddLabel("Is Bella in an exclusive ")
askXor.l3=dialog.AddLabel("relationship with Edward or Jacob ")
askXor.l4=dialog.AddLabel("but not both?")
askXor.play=dialog.AddButton("PlayFoldit",0)
askXor.pickAminos=dialog.AddButton("PickAminos",1)
askXor.test=dialog.AddButton("TestXOR",2)
resAskXor=dialog.Show(askXor)
if resAskXor==0 then
testXor=false
chooseAminos=false
--Josh fuse snippet
behavior.SetHidingImportance(0.5)
five=behavior.GetHidingImportance()
behavior.SetHidingImportance(0.6)
six=behavior.GetHidingImportance()
if five==six then
local ask = dialog.CreateDialog("Recipe modding is disabled")
ask.l1=dialog.AddLabel("You may want to")-- cancel,")
ask.l2=dialog.AddLabel(" open(dakai) the Behavior/Comporte tab,")
ask.l3=dialog.AddLabel(" and click Recipe Score Modding.")--, then re-run")
ask.l4=dialog.AddLabel("You don't need to cancel")
ask.l5=dialog.AddLabel("buyong quxiao")
ask.OK = dialog.AddButton("OK/Haode",1) --Wo bu guan", 1)
ask.Cancel = dialog.AddButton("Cancel/quxiao", 0)
res=dialog.Show(ask)
if res==0 then exitexitexit() end
end
else if resAskXor==1 then
chooseAminos=true
testXor=false
end
end
function resetBehavior()
behavior.SetClashImportance ( 1.0 )
behavior.SetSidechainHBondImportance ( 1.0 )
behavior.SetBackboneHBondImportance ( 1.0 )
behavior.SetPackingImportance ( 1.0 )
behavior.SetHidingImportance ( 1.0 )
behavior.SetPairwiseImportance ( 1.0 )
behavior.SetDensityImportance ( 1.0 )--jon
end
--end Josh's Fuse snippet
worstPossible=-999999.99999
multiStart=false
HASMUTABLE=false
descrTxt=puzzle.GetDescription()
if #descrTxt>0 and (descrTxt:find("design") or descrTxt:find("designs")) then
HASMUTABLE=true IDEALCHECK=true HANDFOLD=true end
--copied from AFK3.1.1 using new foldit editor
if #descrTxt>0 and (descrTxt:find("multi-start") or descrTxt:find("start positions")) then
multiStart=true
end
--if HASMUTABLE then environInput1=1 else environInput1=0 end
print("muta ")
print(HASMUTABLE) --can't cat
-----
--So I cut and pasted these functions from BWP here for AFK.
NonLockedSegList={}
function segCnt() return structure.GetCount() end --jon
function IsUnlockedSeg( seg1 )
return not structure.IsLocked( seg1 )
end
function FindAllMovableSegs( )
--segCnt=structure.GetCount() --jon lazy
NonLockedSegList={} --jon reinit in case deleting res.
for i=1, structure.GetCount() do --jon
if structure.IsLocked( i ) then
PuzzleHasLockedSegs = true
else
NonLockedSegList[ #NonLockedSegList + 1] = i
end
end
if PuzzleHasLockedSegs then
for i=1, structure.GetCount() do --jon
if IsUnlockedSeg( i ) then
MinUnlockedSeg = i
break
end
end
for i=segCnt(), 1, -1 do
if IsUnlockedSeg( i ) then
MaxUnlockedSeg = i
break
end
end
end
return false
end
FindAllMovableSegs()
------
param=099
squeezeToInt=function(max)
--param anything like -99.8
-- tanh -> -1 to 1
-- 0 to 2
-- 0 to 1
-- 0 to max-1
-- 1 to max+.99 for rounding fairness
--choice=math.floor((math.tanh(param)+1)/2*(max-1)+1.99)
min=1
choice=math.floor(param%(max-min)+min)
--Lua makes squeezing into range lil. complicated because lists start at 1
return choice
end
squeezeFloat=function(min,max) --bug where output constant value at max
--param anything like -99.8
-- tanh -> -1 to 1
-- 0 to 2
-- 0 to 1
-- 0 to max-1
-- 1 to max+.99 for rounding fairness
--choice=((math.tanh(param)+1)/2*((max-min)-1)+1)+min
--Lua makes squeezing into range lil. complicated because lists start at 1
--choice=eulerAct(param)*(max-min)+min
choice=param%(max-min)+min
print("choice is "..choice)
return choice
end
eulerAct=function(a)
--from xviniette's AsteroidsLearning Neuroevolution.js on Github
--activation:function(a){
ap = (-a)/1
return (1/(1 + math.exp(ap))) --like tanh but from 0 to 1 instead of -1 to 1
--exp(x) is Euler's constant e^x
end
print("euler "..eulerAct(-4.5))
------------A.i. learns v7 filters
performAction={}
actionDescription={}
function printTimeAndScore(startTime, scoreGain, currentStateString)
local ss = (os.time() - startTime) % 60
local mm = (((os.time() - startTime - ss) % 3600) / 60)
local hh = (os.time() - startTime - mm*60 - ss) / 3600
print("Time: " .. string.format("%02d", hh) .. ":" .. string.format("%02d", mm) .. ":" ..
string.format("%02d", ss) .. ". " .. currentStateString)
print(" Score: " .. current.GetEnergyScore() ..
", Total: +" .. scoreGain)
end
bookmark=0
function initializeActions()
performAction = {}
actionDescription = {}
--
performAction[0] = function()
local ss=math.random(1,structure.GetCount()-3)
selection.SelectRange(ss,ss+3)
structure.MutateSidechainsSelected(1) --All(1)
end
actionDescription[0] = "Mutate(1)"
--
table.insert(performAction,function() lastOutput=0 --brainOutput=1
param=0
end)
actionDescription[1] = "Reset prev. brainOutput to not spin out of control"
--keep this at first action, because Lua makes 3.56e+89 % 5 or % 6 to 1 I mean 0
performAction[2] = function()
local startSegmentNumber = math.random(1, structure.GetCount() - 9)
local endSegmentNumber = math.random(startSegmentNumber + 8, structure.GetCount())
local b=band.AddBetweenSegments(startSegmentNumber, endSegmentNumber)
band.SetStrength(b, 10) --jon b
band.SetGoalLength(b, structure.GetDistance(startSegmentNumber, endSegmentNumber) * 0.9)
end
actionDescription[2] = "Add random band"
performAction[3] = function()
band.DeleteAll()
end
actionDescription[3] = "Delete all bands"
recentbest.Save() --overwrite it first
performAction[4] = function()
recentbest.Restore() --still somehow accessing
FindAllMovableSegs()
--print("banned")
end
actionDescription[4] = "Restore recent best"
performAction[5] = function()
local startSegmentNumber = math.random(1,structure.GetCount() - 3)
selection.DeselectAll()
selection.SelectRange(startSegmentNumber, startSegmentNumber + 3)
structure.RebuildSelected(2)
selection.DeselectAll()
end
actionDescription[5] = "Rebuild random segment"
performAction[6] = function()
behavior.SetClashImportance(1)
end
actionDescription[6] = "Set clash importance to 1"
performAction[7] = function()
behavior.SetClashImportance(0.5)
end
actionDescription[7] = "Set clash importance to 0.5"
performAction[8] = function()
behavior.SetClashImportance(0.02)
end
actionDescription[8] = "Set clash importance to 0.02"
performAction[9] = function()
local startSegmentNumber = math.random(1, structure.GetCount() - 3)
selection.DeselectAll()
selection.SelectRange(startSegmentNumber, startSegmentNumber + 3)
structure.IdealizeSelected()
selection.DeselectAll()
end
table.insert(actionDescription,"Idealize random segment")
performAction[10] = function()
FindAllMovableSegs()
cut=(NonLockedSegList[math.random(#NonLockedSegList) ])
structure.InsertCut(cut)
structure.WiggleAll(1)
structure.DeleteCut(cut)
end
actionDescription[10] = "Wiggle(1 band safe 2 sided interf." --interface --no red lines
--table.insert(performAction,function() structure.MutateSidechainsAll(1) end)
--table.insert(actionDescription,"mutate1 moved from action 0")
function ParseError ( errmsg )
local reason
local start, stop, line, msg
start, stop, line, msg = errmsg:find ( ":(%d+):%s()" )
if msg ~= nil then
errmsg = errmsg:sub ( msg, #errmsg )
end
return errmsg
end
--
-- SafeSnap uses the Lua protected call function, pcall,
-- to call rotamer.SetRotamer
--
-- SafeSnap returns a numeric return code and an error message.
--
-- The return codes are:
--
-- 0 - successful, error message is nil
-- -1 - bad rotamer index
--
-- Errors other than a bad rotamer index are rethrown using
-- the Lua function error().
--
function SafeSnap ( segIdx, rotIdx )
--
-- error message when attempting to snap to an invalid rotamer
--
local BADSNAP = "(snap index out of bounds)"
--
-- don't allow a bad rotamer to stop us
--
local good, errmsg = pcall ( rotamer.SetRotamer, segIdx, rotIdx )
if good then
return 0, nil
else
local err2 = ParseError ( errmsg )
local errp = err2:find ( BADSNAP )
if errp ~= nil then
return -1, err2
end
error ( errmsg, 0 )
end
end
table.insert(performAction, function() SafeSnap(math.random(structure.GetCount()), param) end)
table.insert(actionDescription,"pcall rotamer for ligand or res")
table.insert(performAction,function()
local segmentIndex1=math.random(structure.GetCount())
local segmentIndex2=math.random(structure.GetCount())
local atomIndex1=math.random(structure.GetAtomCount(segmentIndex1))
local atomIndex2=math.random(structure.GetAtomCount(segmentIndex2))
local symnr2=math.random(0,structure.GetSymCount())
return band.AddBetweenSegments(segmentIndex1,segmentIndex2,atomIndex1,atomIndex2,symnr2)
end)
table.insert(actionDescription,
"Add a band between the two segments. By default bands to the backbone. Specify an atom number from 0 to structure.GetAtomCount() to band to a different atom. (0 for the default backbone atom) Returns band number. Specify an symnr from 0 t")
table.insert(performAction,function()
local lengthOfSegment = math.random(1, 3)
local segmentInformation = {}
local workSegmentNumber = math.random(1, 3)
local function sortSegments(segmentInformation)
for i = 1, #segmentInformation - 1 do
for j = i + 1, #segmentInformation do
if segmentInformation[i][3] > segmentInformation[j][3] then
segmentInformation[i], segmentInformation[j] = segmentInformation[j],
segmentInformation[i]
end
end
end
return segmentInformation
end
for i = 1, structure.GetCount() - lengthOfSegment + 1 do
segmentInformation[i] = {i, i + lengthOfSegment - 1, current.GetSegmentEnergyScore(i) }
for j = 2, lengthOfSegment do
segmentInformation[i][3] = segmentInformation[i][3] + current.GetSegmentEnergyScore(i
+ j - 1)
end
end
segmentInformation = sortSegments(segmentInformation)
selection.DeselectAll()
selection.SelectRange(math.max(segmentInformation[workSegmentNumber][1] - 1, 1),
math.min(segmentInformation[workSegmentNumber][2] + 1, structure.GetCount()))
structure.RebuildSelected(2)
selection.DeselectAll()
end)
table.insert(actionDescription,"Rebuild worst segment")
table.insert(performAction,function()
local startSegmentNumber = math.random(1, structure.GetCount() - 9)
local endSegmentNumber = math.random(startSegmentNumber + 8, structure.GetCount())
local b=band.AddBetweenSegments(startSegmentNumber, endSegmentNumber)
band.SetStrength(b, 10)
band.SetGoalLength(b, structure.GetDistance(startSegmentNumber, endSegmentNumber) * 1.1)
end)
table.insert(actionDescription,"expand band")
table.insert(performAction,function()
copier=math.random(1,structure.GetCount())
structure.SetSecondaryStructure(copier,structure.GetSecondaryStructure(
math.max(math.min(copier+math.random(0,1)*2-1,1),structure.GetCount())
)
)
end)
table.insert(actionDescription,"extend ss")
table.insert(performAction,function()
freeze.Freeze(math.random(1,structure.GetCount()),false,true) --bb --sc
end)
table.insert(actionDescription,"freeze sc")
table.insert(performAction,function()
freeze.Freeze(math.random(1,structure.GetCount()),true,false) --bb --sc
end)
table.insert(actionDescription,"freeze bb")
table.insert(performAction,function()
freeze.Freeze(math.random(1,structure.GetCount()),true,true) --bb --sc
end)
table.insert(actionDescription,"freeze bb sc") --threoretically could freeze neither for testing
table.insert(performAction,function()
freeze.Unfreeze(math.random(1,structure.GetCount()),false,true) --bb --sc
end)
table.insert(actionDescription,"unfreeze sc")
table.insert(performAction,function()
freeze.Unfreeze(math.random(1,structure.GetCount()),true,false) --bb --sc
end)
table.insert(actionDescription,"unfreeze bb")
act="freeze.Unfreeze(math.random(1,structure.GetCount()),true,true) --bb --sc"
table.insert(performAction,function()
pcall(act)
print(act)
end)
table.insert(actionDescription,act)--"unfreeze bb")
act="kokokokok" --still works, at least in Lua
table.insert(performAction,function()
freeze.UnfreezeAll() --bb --sc
end)
table.insert(actionDescription,"unfreeze all")
table.insert(performAction,function()
freeze.FreezeAll() --bb --sc
end)
table.insert(actionDescription,"freeze all")
table.insert(performAction,function() behavior.SetBackboneHBondImportance(math.random(0,300)/100)
end)
table.insert(actionDescription,"behavior.SetBackboneHBondImportance (rand)")
table.insert(performAction,function() behavior.SetBackboneHBondImportance(1)
end)
table.insert(actionDescription,"behavior.SetBackboneHBondImportance(1)")
table.insert(performAction,function() resetBehavior() end)
table.insert(actionDescription,"resetBehavior")
table.insert(performAction,function()
behavior.SetFiltersDisabled(true)
end)
table.insert(actionDescription,"disable filters")
table.insert(performAction,function()
behavior.SetFiltersDisabled(false)
end)
table.insert(actionDescription,"enable filters")
table.insert(performAction,function()
behavior.SetDensityImportance(squeezeFloat(0,3))
end)
table.insert(actionDescription,"density, enable recipe score modding first")
table.insert(performAction,function()
behavior.SetDensityImportance(1)
end)
table.insert(actionDescription,"density1, enable recipe score modding first")
table.insert(performAction,function()
options={"l","m","a"}
if behavior.HighPowerAllowed() then table.insert(options,"h") end
behavior.SetWigglePower(options[squeezeToInt(#options)])
--old buggy algo: math.floor(#options/2*(math.tanh(param)+1))
end)
table.insert(actionDescription,"power param")
table.insert(performAction,function()
options={"l","m","a"}
if behavior.HighPowerAllowed() then table.insert(options,"h") end
behavior.SetWigglePower("a")
end)
table.insert(actionDescription,"power auto")
table.insert(performAction,function()
options={"l","m","a"}
if behavior.HighPowerAllowed() then table.insert(options,"h") end
behavior.SetWigglePower(options[math.random(#options)])
end)
table.insert(actionDescription,"power rand")
table.insert(performAction,function()
FindAllMovableSegs()
cut=NonLockedSegList[math.random(#NonLockedSegList)] --plz only unlocked
structure.InsertCut(cut)
behavior.UseCutBands(false)
seg=NonLockedSegList[math.random(#NonLockedSegList)] --plz not the cut
options={"h","l","e","a"}
ss=options[math.random(4)]
structure.SetSecondaryStructure(seg,ss)
selection.DeselectAll()
selection.Select(seg)
structure.IdealSSSelected() --need cut beforehand in linker
behavior.UseCutBands(true)
behavior.SetClashImportance(1)
structure.WiggleAll(1)
structure.DeleteCut(cut)
end)
table.insert(actionDescription,"random SS, idealSS")
table.insert(performAction,function() structure.LocalWiggleAll(1) end)
table.insert(actionDescription,"LwA")
table.insert(performAction,function()
FindAllMovableSegs()
structure.InsertResidue(NonLockedSegList[math.random(#NonLockedSegList) ])
FindAllMovableSegs()
--structure.WiggleAll(1) --debug
end)
table.insert(actionDescription,"ins")
table.insert(performAction,function()
FindAllMovableSegs()
structure.DeleteResidue(NonLockedSegList[math.random(#NonLockedSegList) ])
FindAllMovableSegs()
--structure.WiggleAll(1) --debug
end)
table.insert(actionDescription,"del. seg, may cause band glitch")
table.insert(performAction,function()
FindAllMovableSegs()
cut=(NonLockedSegList[math.random(#NonLockedSegList) ])
structure.InsertCut(cut)
table.remove(NonLockedSegList,cut) --temporary
if #NonLockedSegList>0 then
structure.DeleteResidue(NonLockedSegList[math.random(#NonLockedSegList) ])
--hopefully diff.
end
--structure.DeleteCut(cut) --can be out of range
FindAllMovableSegs()
delCuts() --defined below
end)
table.insert(actionDescription,"cut and del. seg") --for 2 sided interface
table.insert(performAction,function()
puzzle.StartOver() FindAllMovableSegs()
end)
table.insert(actionDescription,"reset puzzle. maybe necessary for multi-start puzzles.".. "\n, doesn't exit evolver mode like manual reset does. ") --multi
table.insert(performAction,function()
if multiStart or current.GetEnergyScore()>10000 then
puzzle.StartOver() FindAllMovableSegs()
end
end)
table.insert(actionDescription,"reset puzzle if>10000. for multi-entries contest."..
"\n, doesn't exit evolver mode like manual reset does. ") --multi
table.insert(performAction,function() save.Quicksave(3) end)
table.insert(actionDescription,"save3")
table.insert(performAction,function() save.Quickload(3) FindAllMovableSegs() end)
table.insert(actionDescription,"load3")
table.insert(performAction,function() save.Quickload(9) FindAllMovableSegs() end)
table.insert(actionDescription,"load9")
table.insert(performAction,function() creditbest.Restore() FindAllMovableSegs() end)
table.insert(actionDescription,"credit")
table.insert(performAction,function() absolutebest.Restore() FindAllMovableSegs() end)
table.insert(actionDescription,"abs best")
table.insert(performAction,function()
local ss=math.random(1,structure.GetCount()-3)
selection.SelectRange(ss,ss+3)
structure.ShakeSidechainsSelected(1) --All(1)
end)
table.insert(actionDescription,"shake(1)")
function selectWorstSeg()
local lengthOfSegment = math.random(1, 3)
local segmentInformation = {}
local workSegmentNumber = math.random(1, 3) --jon asks if Quicksort
local function sortSegments(segmentInformation)
for i = 1, #segmentInformation - 1 do
for j = i + 1, #segmentInformation do
if segmentInformation[i][3] > segmentInformation[j][3] then
segmentInformation[i], segmentInformation[j] = segmentInformation[j],
segmentInformation[i]
end
end
end
return segmentInformation
end
for i = 1, structure.GetCount() - lengthOfSegment + 1 do
segmentInformation[i] = {i, i + lengthOfSegment - 1, current.GetSegmentEnergyScore(i) }
for j = 2, lengthOfSegment do
segmentInformation[i][3] = segmentInformation[i][3]
+ current.GetSegmentEnergyScore(i + j - 1)
end
end
segmentInformation = sortSegments(segmentInformation)
selection.DeselectAll()
selection.SelectRange(math.max(
segmentInformation[workSegmentNumber][1] - 1, 1),
math.min(segmentInformation[workSegmentNumber][2] + 1, structure.GetCount()))
end
table.insert(performAction,function()
selectWorstSeg()
structure.MutateSidechainsSelected(1)
selection.DeselectAll()
end)
table.insert(actionDescription,"muta worst segment")
table.insert(performAction,function()
selectWorstSeg()
structure.WiggleSelected(2,true,true)
selection.DeselectAll()
end)
table.insert(actionDescription,"wig bb sc worst segment")
table.insert(performAction, function()
i=math.random(1,structure.GetCount()) -- do --abridged for debugging
structure.SetAminoAcid(i,"e")
--e for msg
--acids arndceqghilkmfpstwyv
--g for glycine
--v for valine, suggested by Enzyme for 1947
--end
end)
table.insert(actionDescription,"set amino msg")
table.insert(performAction, function()
bookmark=(bookmark)%structure.GetCount()+1 --7%5=2 ...
i=bookmark --do --abridged for debugging
structure.SetAminoAcid(i,"e")
--e for msg
--acids arndceqghilkmfpstwyv
--g for glycine
--v for valine, suggested by Enzyme for 1947
--end
end)
table.insert(actionDescription,"set amino msg bookmark")
table.insert(performAction, function()
i=math.random(1,structure.GetCount()) -- do --abridged for debugging
structure.SetAminoAcid(i,"v")
--e for msg
--acids arndceqghilkmfpstwyv
--g for glycine
--v for valine, suggested by Enzyme for 1947
--end
end)
table.insert(actionDescription,"set amino val")
table.insert(performAction, function()
i=math.random(1,structure.GetCount()) -- do --abridged for debugging
structure.SetAminoAcid(i,"g")
structure.SetSecondaryStructure(i,"l")
--e for msg
--acids arndceqghilkmfpstwyv
--g for glycine
--v for valine, suggested by Enzyme for 1947
--end
end)
table.insert(actionDescription,"set amino gly for blueprint")
table.insert(performAction, function()
i=math.random(structure.GetCount())
aminos="arndceqghilkmfpstwyv"
choice=math.random(#aminos)
local char = aminos:sub(choice,choice)
structure.SetAminoAcid(i,char)
--e for msg
--g for glycine
--v for valine, suggested by Enzyme for 1947
end)
table.insert(actionDescription,"set amino rand")
table.insert(performAction, function()
i=math.random(structure.GetCount())
aminos="arndceqghilkmfpstwyv"
choice=squeezeToInt(#aminos)
local char = aminos:sub(choice,choice)
structure.SetAminoAcid(i,char)
--e for MSG, q for glutamine
--g for glycine
--v for valine, suggested by Enzyme for 1947
end)
table.insert(actionDescription,"set amino param")
table.insert(performAction, function()
aminos="arndceqghilkmfpstwyv"
i=math.random(#aminos)
choice=squeezeToInt(structure.GetCount())
print("choice"..choice)
local char = aminos:sub(i,i)
structure.SetAminoAcid(choice,char)
--e for MSG, q for glutamine
--g for glycine
--v for valine, suggested by Enzyme for 1947
end)
table.insert(actionDescription,"set amino by param")
--imported from AiLearns22
table.insert(performAction,function()
--Bands in Space
local s1=math.random(structure.GetCount())
local str=math.random(0.1,1)
local len=math.random(1,20) --jon: 1-1000
local theta = math.acos(math.random()) --jon: arccosine
local phi = 2 * math.pi * math.random()
local segmentXAxis=0
local segmentYAxis=0
while true do --all 3 must be different
segmentXAxis = math.random(structure.GetCount())--segCnt) --jon
segmentYAxis = math.random(structure.GetCount())--segCnt) --jon
if segmentXAxis~=s1 and segmentYAxis~=s1 and segmentXAxis~=segmentYAxis then
break end
end
--{segmentOrigin, segmentXAxis, segmentYAxis, rho, theta, phi}
band.Add(s1, segmentXAxis, segmentYAxis, len, theta, phi, str)
--bands.AddBand(b)
--puzzle.StartOver()
end)
table.insert(actionDescription,"band in space")
table.insert(performAction,function()
--Bands in Space
local s1=math.random(structure.GetCount())
local str=math.random(0.1,1)
local len=3.5 --angstroms
local theta = math.acos(math.random()) --jon: arccosine
local phi = 2 * math.pi * math.random()
local segmentXAxis=0
local segmentYAxis=0
while true do --all 3 must be different
segmentXAxis = math.random(structure.GetCount())--segCnt) --jon
segmentYAxis = math.random(structure.GetCount())--segCnt) --jon
if segmentXAxis~=s1 and segmentYAxis~=s1 and segmentXAxis~=segmentYAxis then
break end
end
--{segmentOrigin, segmentXAxis, segmentYAxis, rho, theta, phi}
band.Add(s1, segmentXAxis, segmentYAxis, len, theta, phi, str)
--bands.AddBand(b)
--puzzle.StartOver()
end)
table.insert(actionDescription,"band in space default length")
act="ends"
--print("act")
table.insert(actionDescription,act)
table.insert(performAction, function()
if band.GetCount() ~= 0 then
local band1 = math.random(band.GetCount())
band.AddToBandEndpoint ( math.random(structure.GetCount()), band1 )
end
end)
act="for ii = 1, band.GetCount () do band.SetGoalLength ( ii, math.random(0,23.5)) end"
table.insert(actionDescription,act)
table.insert(performAction, function() pcall(act) end)
table.insert(performAction, function() structure.WiggleAll(1) end)
table.insert(actionDescription, "Wiggle all, "..
"\n moved from action 0 because Lua starts at 1")
table.insert(performAction, function() structure.LocalWiggleAll(1) end )
table.insert(actionDescription, "local wiggle all inspired by BWP")
table.insert(performAction, function()
selection.DeselectAll()
local seg=math.random(structure.GetCount())
selection.SelectRange(seg,math.max(seg,math.random(structure.GetCount()))) --could use seg+1
structure.LocalWiggleSelected(1)
selection.DeselectAll()
end)
table.insert(actionDescription, "Local Wiggle Selected inspired by BWP")
table.insert(performAction, function()
selection.DeselectAll()
local seg=math.random(structure.GetCount()-1)
selection.SelectRange(seg,seg+1)
structure.LocalWiggleSelected(1)
selection.DeselectAll()
end)
table.insert(actionDescription, "Local Wiggle 2 segment inspired by BWP")
table.insert(performAction, function()
selection.DeselectAll()
local seg=math.random(structure.GetCount())
selection.SelectRange(seg,seg)
structure.LocalWiggleSelected(1)
selection.DeselectAll()
end)
table.insert(actionDescription, "Local Wiggle 1 segment inspired by Daoism")
table.insert(
performAction,
function()
for i=1,30 do
if structure.InsertResidue(
math.random(1,structure.GetCount()) --start at 1 for del.
--I think the wiki is outdated;
-- insert residue gives an error with index 0 (and count+1) now
) then break end
end
end
)
table.insert(actionDescription, "Try Insert residue/segment. Only works in Design puzzles.")
table.insert(
performAction, function() structure.DeleteCut(math.random(structure.GetCount())) end
)
table.insert(actionDescription, "del. cut")
table.insert(
performAction,function() structure.InsertCut(math.random(structure.GetCount())) end
)
table.insert(actionDescription, "insert cut")
table.insert(
performAction, function()
structure.DeleteResidue(math.random(2,structure.GetCount()-1))
FindAllMovableSegs()
end
)
table.insert(actionDescription, "delete residue. may cause Foldit crash in combination with GAB")
table.insert(performAction,function() ui.CenterViewport() end)
table.insert(actionDescription, "center view")
performAction[#performAction+1]=function()
selection.SelectAll()
structure.SetSecondaryStructureSelected("a") --auto
selection.DeselectAll()
end
actionDescription[#actionDescription+1]="auto secondary structure."..
"\n won't affect score until idealSS"
performAction[#actionDescription+1]=function() --interchangeable here
-- Set segments secondary structure. Valid values are e=sheet, h=helix, l=loop, m=molecule, a=auto.
local struct={[1]="e",[2]="h",[3]="l",[4]="m"}
structure.SetSecondaryStructure(math.random(1,structure.GetCount()), struct[math.random(1,#struct)])
end
actionDescription[#actionDescription+1]="random secondary structure"
--won't affect score until idealSS
--end import
table.insert(performAction,function()
behavior.SetClashImportance(math.random(0,100)/100)
end)
table.insert(actionDescription,"random C.i.") --based on AFK3
--May need to manually checkmark Enable Recipe Modding in Behavior
table.insert(performAction,function()
behavior.SetSidechainHBondImportance(math.random(0,300)/100)
end)
table.insert(actionDescription,"side hbond i. 0-3")
table.insert(performAction,function()
behavior.SetSidechainHBondImportance(1)
end)
table.insert(actionDescription,"side hbond i. 1")
table.insert(performAction,function()
behavior.SetPairwiseImportance(math.random(0,300)/100)
end)
table.insert(actionDescription,"set pair i. 0-3")
table.insert(performAction,function()
behavior.SetPairwiseImportance(1)
end)
table.insert(actionDescription,"set pair i. 1")
table.insert(performAction,function()
behavior.SetPackingImportance(math.random(0,300)/100)
end)
table.insert(actionDescription,"set pack i. 0-3")
table.insert(performAction,function()
behavior.SetPackingImportance(1)
end)
table.insert(actionDescription,"set pack i. 1")
table.insert(performAction,function()
behavior.SetHidingImportance(math.random(0,300)/100)
end)
table.insert(actionDescription,"set hiding i. 0-3")
table.insert(performAction,function()
behavior.SetHidingImportance(1)
end)
table.insert(actionDescription,"set hiding i. 1")
table.insert(performAction,function()
lastOutputTan=(math.tanh(#structure.GetNote(1))+1)/2
end)
table.insert(actionDescription,"getnote")
table.insert(performAction,function()
lastOutput=#structure.GetNote(2)/10
end)
table.insert(actionDescription,"getnote2")
table.insert(performAction,function()
string=""
for i=0,math.ceil(lastOutputTan*100) do string=string.."i" end
structure.SetNote(2,string) --pcall(exit())
end)
table.insert(actionDescription,"setnote")
table.insert(performAction,function()
behavior.UseCutBands(squeezeToInt(param,2)==2) --not enable
end)
table.insert(actionDescription,"usecutbands param")
--insert actions you want included by default above this line
---------
--insert new actions here before counting them --jon
------old actions don't want to spend debug time below
delCuts=function()
cuts=structure.GetCuts()
for i=1,#cuts do
structure.DeleteCut(cuts[i])
end
end
table.insert(performAction,delCuts)
table.insert(actionDescription,"del. cuts")
table.insert(performAction,function()
absolutebest.Restore()
delCuts()
behavior.SetFiltersDisabled(false)
end)
table.insert(actionDescription,"get credit for abs")
table.insert(performAction,function()
behavior.SetClashImportance(1) --needed?
behavior.UseCutBands(true) --not enable
structure.WiggleAll(1)
cuts=structure.GetCuts()
for i=1,#cuts do
--structure.WiggleAll(1)
structure.DeleteCut(cuts[i])
end
end)
table.insert(actionDescription,"del. cuts2")
-------------------
NumberOfActions=#performAction+1 --jon
save.Quicksave(9)
if not testXor and debugActions then
for iParam=1,1 do
param=math.random(-100,100)/10
print("debug actions, param "..param)
for i=1,#performAction-1 do --i=1 to skip mutate
--save.Quickload(9) --komi may help
starttime=os.clock()
startscore=current.GetEnergyScore()
print("debug action "..i..", "..actionDescription[i])
performAction[i]()
print("yield per sec "..(current.GetEnergyScore()-startscore)/(os.clock()-starttime+1))
end
--structure.WiggleAll(4) --lag for debug
end
end
end
initializeActions()
----------------
pokemons={}
--perhaps bias (threshold) is unfortunately named that way
--https://stackoverflow.com/questions/2480650/what-is-the-role-of-the-bias-in-neural-networks
--it means shifting a value to one side in algebra
--originally from French:
--https://www.etymonline.com/word/bias
numInputs=10
--must be exactly the same as number of inputs below
for i=1,4 do --*2 do --ought to be derivative of (numDendrites+1 [for bias])*numNeurons
local pokemon={layers={},score=0} --"ogres are made of layers"
function newNeuron(--[[optional]]numDendrites)
newDendrites={}
numDendrites=numDendrites or numInputs+1 --at least size of biggest layer
--https://forum.defold.com/t/lua-defining-a-function-with-optional-parameters-solved/3340
for iDendrite=1,numDendrites do --maybe extra for now?
table.insert(newDendrites,math.random(-10,10)/10)
end
local neuron={
dendrites=newDendrites
--weights (dentrites getting inputs from prev. neurons)
-- are factors to have a weighted importance
--for instance, if you're guessing the total weight of 2 elephants and 2 insects
--the number of elephants will be far more important
,
bias=math.random(-10,10)/10--can exceed
--bias in this case is like a T/F threshold. <50% on exam = F, you don't pass at all.
--some professors curve grades based on overall class grades
,
axon={0,1} --called neuron Value by techies. means neuron output
}
--print("neuron axon "..neuron.axon)
return neuron
end
layer={} --input layer, true, false
for i=1,numInputs do
table.insert(layer,{axon={0,1}})
end
print("input neuron axon "..layer[1].axon[1])
table.insert(pokemon.layers,layer)
for iHiddenLayer=1,hiddenLayers do
layer={} --new layer
--a Hidden Layer
--for XOR problem, set #neurons to 2
-- https://miro.medium.com/max/1346/1*bRoaMcjiD4yRjgfr2QGZcA.jpeg
for i=1,#pokemon.layers[1]+1 do --3 do --2 do
local neuron=newNeuron()
--print("my neuron "..neuron)
table.insert(layer,neuron)
end
print("done inserting neurons into hidden layer")
table.insert(pokemon.layers,layer)
end
layer={} --new layer
--output layer
for i=1,2 do
local neuron=newNeuron()
table.insert(layer,neuron)
end
table.insert(pokemon.layers,layer)
table.insert(pokemons,pokemon)
end
gen=0
lastOutputTan=.2 --forgot this
lastOutput=0
weakest=1
print("initializing velocity")
mutantLayer=math.random(#pokemons[1].layers-1)+1
mutantNeuron=math.random(#pokemons[1].layers[mutantLayer])
mutantDendrite=math.random(#pokemons[1].layers[mutantLayer][mutantNeuron].dendrites)
dendriteMutation=math.random(-50,50)/100 --Mozi's precision philosophy
biasMutation=math.random(-50,50)/100 --Mozi's precision philosophy
for gen=1,genlimit do
--88% cpu no recipe running
--100% cpu just checking hour
--140% cpu active Neural Net
print("sleeping")
repeat
hour=(os.date("%H"))
--hour="00"
--hour="23"
day=(tostring(11)<hour and hour<tostring(19))
until true or not day
--gen=gen+1
print("new gen "..gen)
path=1
for i=1,#pokemons do
starttime=os.clock()
--creditbest.Restore()
--band.DeleteAll()
--behavior.SetFiltersDisabled(false)
startscore=current.GetEnergyScore()
if not current.AreConditionsMet then
startscore=worstPossible --0
end
--puzzle.StartOver()
--puzzle.StartOver() --if multistart
diversity=0
pokemons[i].score=worstPossible --0 --for xor. for foldit, set to worst, get highscore?
if testXor then pokemons[i].score=0 end
attacks=4 --try even number for xor/not
iAttack=1
while iAttack<=attacks do --9 do
path=1--math.random(1,2) --set for input
selection.DeselectAll()
--selection.SelectAll()
selection.SelectRange(math.random(structure.GetCount()-3),math.random(structure.GetCount()))
--hopefully ends mutable if design but sadly not linker
--randomize inputs to test XOR
pokemons[i].layers[1][1].axon[path]=(iAttack-1)%2 --math.random(0,1)
pokemons[i].layers[1][2].axon[path]=math.floor((iAttack-1)/2) --math.random(0,1)
pokemons[i].layers[1][3].axon[path]=behavior.GetClashImportance() --math.random(0,1)
pokemons[i].layers[1][4].axon[path]=0--param --lastOutputTan
pokemons[i].layers[1][5].axon[path]=iAttack --algoStep)
pokemons[i].layers[1][6].axon[path]=0 --
if #structure.GetCuts()>0 then
pokemons[i].layers[1][6].axon[path]=1
end
pokemons[i].layers[1][7].axon[path]=(scoreboard.GetRank()) --shame,accurate endgame detection
pokemons[i].layers[1][8].axon[path]=0 --overkill updating
if HASMUTABLES then
pokemons[i].layers[1][8].axon[path]=1
end
pokemons[i].layers[1][9].axon[path]=((1+current.GetEnergyScore())/2) --
pokemons[i].layers[1][10].axon[path]=0--lastOutput
if testXor then
for iAxon=3,#pokemons[i].layers[1] do
pokemons[i].layers[1][iAxon].axon[path]=0
end
end
--we don't really understand bifurcated axons, so we generally don't simulate them
path=math.random(1,2) --randomize for road less traveled if even amount of neurons
if humble then path=1 end
--skip activation of first layer (input layer)
for iLayer=2,#pokemons[i].layers do
print("gen "..gen..", pokemon #"..i..", layer "..iLayer..",iA"..iAttack)
--print("layers is "..pokemons[i].layers)
print("layer length "..#pokemons[i].layers[iLayer])
for iNeuron=1,#pokemons[i].layers[iLayer] do
--"inputs go in times weights, summate, add a bias activate" --s. raval
sum=0
for iPrevNeuron=1,#pokemons[i].layers[iLayer-1] do --previous neurons
if iLayer>2 and not humble then
path=3-path --road less traveled
end
local input=pokemons[i].layers[iLayer-1][iPrevNeuron].axon[path]%1
local dendrite=pokemons[i].layers[iLayer][iNeuron].dendrites[iPrevNeuron]
--print("input "..input..", neuron weight "..dendrite)
sum=sum+input*dendrite
--input times weight of connection
end
--print("sum "..sum)
--"inputs go in times weights, get sums" -s. raval
--print("neuron bias "..pokemons[i].layers[iLayer][iNeuron].bias)
local axon={0,0}
axon[path]=sum+pokemons[i].layers[iLayer][iNeuron].bias
--most people add bias instead of subtract bias but maybe it's easier visualizing
-- subtracting bias, so you can view the bias as a threshold, then you can write
-- if axon<=bias instead of axon<=.5
-- or something like axon<=threshold
--"pass that **** [stuff] to my sigmoid function" -s. raval
--axon=math.tanh(axon)
-- [[
if iLayer<#pokemons[i].layers then --allow output to be negative
--ReLU activation function, not really a sigmoid function like tangent
if axon[path] <=0 then --.5 then
--axon[path]=0 --ReLU, rectified linear unit. dying ReLU
-- graph: __/
aloha=0.5 --alpha
axon[path]=aloha*axon[path] --leaky relu
end
end
--]]--
--MIT OpenCourseWare video of training a NN to output the same as the input
-- on MIT's site
--bifurcated axons sometimes
--more like chopsticks/kuazi than a fork, because not as branched as dentritic tree
pokemons[i].layers[iLayer][iNeuron].axon[path]=axon[path]
pokemons[i].layers[iLayer][iNeuron].axon[1-path]=0
end
end
local brainOutput=pokemons[i].layers[#pokemons[i].layers][1].axon[path]
lastOutput=brainOutput --not sure if nn can handle inputs>1,<0,<-1
print("gen"..gen..",brainOutput: \n"..brainOutput..",\n param "..param)
newTan=(math.tanh(brainOutput)+1)/2 --0 to 1
diversity=diversity+math.abs(lastOutputTan-newTan)
--print(#performAction)
lastOutputTan=newTan
print("output tan "..lastOutputTan)
choice=math.floor(brainOutput%#performAction)+1 --pemdas
--big out of bounds fix... and now maybe fixed for too negative for float too
--skip action 0 for now (mutate all), simplify math
--originally
--choice=math.floor((brainOutput*(1+#performAction))%(1+#performAction))--+.49)*lastOutputTan)
--causes crash when brainOuput is 2.58e+306, guessing because it wraps to negative
print("choice"..choice..", #actionDescription"..#actionDescription)
if chooseAminos and not testXor then
param=pokemons[i].layers[#pokemons[i].layers][2].axon[path]
--inspired by PUBG
if param>10000 or param<0 then
startscore = startscore+math.abs(param)*2
param=0
end
if brainOutput>10000 or brainOutput<0 then
startscore=startscore+math.abs(brainOutput)*2
brainOutput=0
end
aminos="arndceqghilkmfpstwyv"
local myAmino=math.floor((brainOutput*#aminos)%#aminos)+1
print("my amino is "..myAmino)
seg=NonLockedSegList[math.floor((#aminos*param)%#NonLockedSegList)+1]
original=structure.GetAminoAcid(seg)
local char = aminos:sub(myAmino,myAmino)
print("char is "..char)
if char==original and noAddedMSG then
startscore=startscore+400
else
structure.SetAminoAcid(seg,char)
print("set amino succ")
end
--e for MSG, q for glutamine
--g for glycine
--v for valine, suggested by Enzyme for 1947
--attacks=attacks+1
else
print(actionDescription[choice])
if (not testXor) and 0<choice and choice<=#actionDescription then
param=pokemons[i].layers[#pokemons[i].layers][2].axon[path]
performAction[choice]() --paused for xor debug
if param==1 and math.random(90)>1 --arcade coins continue?
then attacks=attacks+1
end --jiexu
end
end
komi=i--*6.5 --komidashi for playing 2nd
improv=(current.GetEnergyScore()-startscore)/(os.clock()-starttime+1)--+diversity+komi
if not current.AreConditionsMet() or #structure.GetCuts()>0 or behavior.GetFiltersDisabled() then
improv=improv*0.0 --7 --0
--*0.7
--shifu:
--layer , neuron: dendrites: -1.642, 1.74, -2.005, -4.18, , bias: 3.048,
--neuron: dendrites: -5.839, 3.608, 1.621, -2.22, , bias: 3.683
--layer , neuron: dendrites: -0.023000000000014, 0.67800000000008, , bias: -1.7139999999999
end
function orFunc(a,b) return math.min(1,a+b) end
function andFunc(a,b) return a*b end
function notFunc(a) return 1-a end
-- https://miro.medium.com/max/1346/1*bRoaMcjiD4yRjgfr2QGZcA.jpeg
xorFunc= function(in1,in2)
return andFunc(
notFunc(andFunc(in1, in2)),
orFunc(in1, in2)
)
end
--real vs predict
path=1 --for xor
--print("xor func "..xorFunc(0,0)..xorFunc(0,1)..xorFunc(1,0)..xorFunc(1,1))
--print("pokemons[i].layers[1][1].axon[path]"..pokemons[i].layers[1][1].axon[path])
--print("pokemons[i].layers[1][2].axon[path]"..pokemons[i].layers[1][2].axon[path])
xorReal=xorFunc(pokemons[i].layers[1][1].axon[path],pokemons[i].layers[1][2].axon[path])
--print("xorReal success")
xorPred=pokemons[i].layers[#pokemons[i].layers][1].axon[path]
error=xorPred-xorReal
realNot=notFunc(pokemons[i].layers[1][2].axon[path])
predNot=pokemons[i].layers[#pokemons[i].layers][2].axon[path]
--print(""..notFunc(0)..notFunc(1))
--error=predNot-realNot
if testXor then
pokemons[i].score=pokemons[i].score -math.pow(error,2)/2/attacks
behavior.SetClashImportance(
--math.min(1,math.max(0,(pokemons[i].score+10)/10)) --for visual
--squeezeFloat(0,1)
eulerAct(pokemons[i].score+1)
)
else
--alpha for score rectifying, eg. 0.1
pokemons[i].score=
math.max(pokemons[i].score,math.max(0.0*improv,improv))--+komi --
end
print("xorPred "..xorPred)
print(",xorReal "..xorReal)
print("predNot "..predNot)
print("realNot "..realNot)
--structure.WiggleAll(1) --debug
iAttack=iAttack+1
end --iAttack
print("score "..pokemons[i].score..", 0 is best")
--structure.WiggleAll(1) --lag for debug
end
strongest=1
for i=2,#pokemons do
if pokemons[i].score>pokemons[strongest].score then strongest=i end
if pokemons[i].score==pokemons[strongest].score and math.random(2)>1 then
strongest=i end
end
print("strongest "..strongest..", score "..pokemons[strongest].score)
if weakest==strongest then
print("gen"..gen..",carp evolved to dragon success")
dendriteMutation=dendriteMutation*1.2
biasMutation=biasMutation*1.2
if testXor then
timer=os.clock()+5
while (os.clock()<timer) do
structure.WiggleAll(1) --debug
end
end
else
if true or math.random(2)>1 then --chance of tripping, chance of carrying momentum downhill on
mutantDendrite=mutantDendrite+1
--math.random(#pokemons[1].layers[mutantLayer][mutantNeuron].dendrites)
print("if you give a mouse a cookie")
if mutantDendrite>#pokemons[1].layers[mutantLayer][mutantNeuron].dendrites then
print("it's gonna wanna layer")
mutantNeuron=mutantNeuron+1 --math.random(#pokemons[1].layers[mutantLayer])
mutantDendrite=0
if mutantNeuron>#pokemons[1].layers[mutantLayer] then
mutantNeuron=1
mutantLayer=mutantLayer+1
print("if you give a mouse a wafer")
if mutantLayer>#pokemons[1].layers then
mutantLayer=2 --back to first hidden layer
yellowWood=-yellowWood --Road Less Traveled
end
end
end
dendriteMutation=0
biasMutation=0
if mutantDendrite>=1 then
dendriteMutation=yellowWood*math.random(50)/100 --Mozi's precision philosophy
else
biasMutation=yellowWood*math.random(50)/100 --Mozi's precision philosophy
end
end
end
weakest=1
for i=2,#pokemons do
if pokemons[i].score<=pokemons[weakest].score then
weakest=i
end
end
runnerup=weakest --2nd best
secondWeakest=strongest
for i=1,#pokemons do
if i~=strongest and pokemons[i].score>=runnerup then
runnerup=i
end
if i~=weakest and pokemons[i].score<=secondWeakest then
secondWeakest=i
end
end
print("weakest "..weakest..", evolving weakest carp to dragon")
for w=1,1 do --2 do --only 1 for gradient simplicity for now
i=weakest
if w>1 then i=secondWeakest end
shifu=strongest --in Kung Fu Panda, Shifu is the 2nd wisest
--shifu meant tutor; now it means driver/chef
shifustring="shifu: "
--skip copying of first layer (input layer)
for iLayer=2,#pokemons[i].layers do
print("pokemon #"..i..", layer "..iLayer)
--print("layers is "..pokemons[i].layers)
--print("layer length "..#pokemons[i].layers[iLayer])
shifustring=shifustring.."\n layer "
for iNeuron=1,#pokemons[i].layers[iLayer] do
--shifu can be female, shimu means tutor's wife but gender is a hassle to code
--plus most CandyCrush pros are female
--shizhang can mean tutor's husband
local shifuNeuron=pokemons[shifu].layers[iLayer][iNeuron]
local shimuNeuron=pokemons[runnerup].layers[iLayer][iNeuron]
noob=pokemons[i].layers[iLayer][iNeuron]
shifustring=shifustring..", neuron: dendrites: "
--we could do backpropagation, involves finding the policy gradient/slope
for iPrevNeuron=1,#pokemons[i].layers[iLayer-1] do --previous neurons
local shifuDendrite=shifuNeuron.dendrites[iPrevNeuron]
local shimuDendrite=shimuNeuron.dendrites[iPrevNeuron]
--print("shifuDendrite weight "..shifuDendrite)
shifustring=shifustring..shifuDendrite..", "
if math.random(2)>1 then
allele=shifuDendrite
else
allele=shimuDendrite
end
--gradient descent
mutation=0
if iLayer==mutantLayer and iNeuron==mutantNeuron and iPrevNeuron==mutantDendrite then
mutation=dendriteMutation end
pokemons[i].layers[iLayer][iNeuron].dendrites[iPrevNeuron]=
--tryhard disciple method
--noob.dendrites[iPrevNeuron]+(shifuDendrite-noob.dendrites[iPrevNeuron])*2
--pro vs pro
--shimuNeuron.dendrites[iPrevNeuron]
-- +(shifuDendrite-shimuNeuron.dendrites[iPrevNeuron])*2
--valentine method
--(shifuDendrite+shimuDendrite)/2
--other half method
--allele
--unpressured aphid method
shifuDendrite
+mutation
end
--print("shifu's orig bias "..shifuNeuron.bias) --shifu not biased against MSG
shifustring=shifustring..", bias: "..shifuNeuron.bias
local allele
if math.random(2)>1 then
allele=shifuNeuron.bias
else
allele=shimuNeuron.bias
end
mutation=0
if iLayer==mutantLayer and iNeuron==mutantNeuron then
mutation=biasMutation end
pokemons[i].layers[iLayer][iNeuron].bias=
--tryhard disciple method, kinda velocity gradient descent
--noob.bias+(shifuNeuron.bias-noob.bias)*2
--Tutor says to chop a log, chop 2 logs
--tryhard pro method, note that I don't mean tryhard in the derogutory sense
-- but rather that imitation is a fast (albeit not as great as AlphaZero) method
--After all, I guess it's why stories unrealistically have happy endings
--(shimuNeuron.bias+(shifuNeuron.bias-shimuNeuron.bias)*2)
--Eg. What can Starcraft pro Scarlett do to play like #1 Serral but better?
--Double Evo chamber or more creep tumors?
--This method finally got the a.i. to set clash 1
--valentine method, but kinda a social bubble stagnation
--"2 roads diverged in a yellow wood and the a.i. car barged down the middle" -GeoHot
--(shifuNeuron.bias+shimuNeuron.bias)/2
--half of genes method
--allele
--aphid method
shifuNeuron.bias
+mutation
end
end
--backpropagation recurses from the output to the input neurons,
-- updating them according to how responsible they are for the error
-- siraj r.
shifustring=shifustring.."\n " --easier selecting text
structure.SetNote(1,shifustring) --middle for 2 sided interface? --1
--max locked seg for 2 sided? stays on even if a res is del.
--2 sided
--shifu:
--layer , neuron: dendrites: 0.17, 0.578, 0.282, 0.374, , bias: 0.068,
--neuron: dendrites: 0.711, 0.286, 0.947, 0.777, , bias: -0.51
--layer , neuron: dendrites: -0.91, 0.214, , bias: 0.376
--1951 cov linker
--shifu:
--layer , neuron: dendrites: 0.812, 0.855, 0.526, , bias: -0.253, neuron: dendrites: -0.325, -0.97, 0.955, , bias: 0.627
--layer , neuron: dendrites: 0.694, 0.905, , bias: -0.826
end
--print("end carp to dragon?")
--sometimes get bias of -0 negative zero. but -0==0 in lua.
end
--------
-------end NN
---------------
-- Variables --
---------------
AFK = {}
AFK.SaveSlot = 98
AFK.StartScore = current.GetEnergyScore()
AFK.StartCI = behavior.GetClashImportance()
AFK.IsMutable = false
AFK.BounceWiggle = {}
AFK.Init = {}
AFK.Helper = {}
AFK.BounceWiggle.DoShake = false
AFK.BounceWiggle.DoMutate = false
AFK.BounceWiggle.Iterations = 5 --jon testing
AFK.BounceWiggle.IterationCount = 0 --jon
AFK.BounceWiggle.DogDays = 0 --jon
AFK.BounceWiggle.MinGain = 0.1
AFK.BounceWiggle.SkipCIMaximization = true
AFK.BounceWiggle.PrintFailures = true
----------------------
-- Helper Functions --
----------------------
AFK.Helper.IsMutable = function()
for n=1, structure.GetCount() do
if (structure.IsMutable(n)) then
AFK.IsMutable = true
return true
end
end
end
if AFK.Helper.IsMutable() and deferentialNN then
dogdays=0
repeat
prevScore=current.GetEnergyScore()
structure.MutateSidechainsAll(1)
if current.GetEnergyScore()<=prevScore then
dogdays=dogdays+1
else dogdays=0 end
print(dogdays.." dogdays of muta")
until(dogdays>=1)
end
AFK.Helper.PrintStart = function(choice)
if (choice > 2) then
mode = "Mutate"
AFK.BounceWiggle.DoMutate = true
elseif (choice > 1) then
mode = "Shake"
AFK.BounceWiggle.DoShake = true
else
mode = "NoShake"
end
print("AFK3(BounceWiggle"..mode..") started. ")
print(
AFK.BounceWiggle.Iterations..
" consecutive Failed iterations before ending.") --jon
end
AFK.Helper.PrintEnd = function(gain)
if (gain > 0) then
print ("script complete: + "..
(current.GetEnergyScore() - AFK.StartScore)..
" -- "..current.GetEnergyScore())
else
print("script complete:"..current.GetEnergyScore())
end
end
AFK.Helper.SetCI = function(ci)
ci = ci or math.random(50, 900) / 1000
behavior.SetClashImportance(ci)
end
AFK.Helper.SelectRandom = function()
local shakeSelectionCount = math.random(1, structure.GetCount())
for n=1, shakeSelectionCount do
local selectSegment = math.random(1, structure.GetCount())
selection.Select(selectSegment)
end
end
AFK.Helper.PerformFunction = function(func, iters)
local currentScore = current.GetEnergyScore()
local newScore = currentScore
behavior.SetFiltersDisabled(true)
func(iters)
behavior.SetFiltersDisabled(false)
recentbest.Restore()
newScore = current.GetEnergyScore()
if (newScore > (currentScore + AFK.BounceWiggle.MinGain)) then
currentScore = newScore
save.Quicksave(AFK.SaveSlot)
else
save.Quickload(AFK.SaveSlot)
end
end
AFK.Helper.UpdateIterations = function(gain)
-- TODO: option to print, even on failure. (so we know Iterations)
AFK.BounceWiggle.IterationCount=AFK.BounceWiggle.IterationCount+1
if gain > 0 then
print (AFK.BounceWiggle.IterationCount
.." iters. dogdays "..AFK.BounceWiggle.DogDays..": + "..
gain.." -- "..current.GetEnergyScore())
AFK.BounceWiggle.DogDays = 0
elseif (AFK.BounceWiggle.DogDays < AFK.BounceWiggle.Iterations) then
if (AFK.BounceWiggle.PrintFailures == true) then
print(AFK.BounceWiggle.IterationCount
.." iters. dogdays "..AFK.BounceWiggle.DogDays..": "..gain.." -- "..current.GetEnergyScore())
end
AFK.BounceWiggle.DogDays = AFK.BounceWiggle.DogDays+1
end
end
-----------------------
-- Create Dialog Box --
-----------------------
AFK.CreateBounceWiggleDialog = function()
local currentDialog = dialog.CreateDialog("BounceWiggle")
currentDialog.IterationsLabel = dialog.AddLabel(
"Failed Iterations before ending")
currentDialog.IterationsSlider = dialog.AddSlider(
"Failure Iterations", AFK.BounceWiggle.Iterations, -1, 1000, 0)
currentDialog.BlankLabel1 = dialog.AddLabel("")
currentDialog.DiscardLabel = dialog.AddLabel(
"(Sketchbook) Discard gains less than")
currentDialog.DiscardSlider = dialog.AddSlider(
"Discard <", AFK.BounceWiggle.MinGain, 0, 10, 1)
currentDialog.BlankLabel2 = dialog.AddLabel("")
currentDialog.SkipMaximization = dialog.AddCheckbox(
"Skip CI=1 Maximization", AFK.BounceWiggle.SkipCIMaximization)
currentDialog.PrintFailuresOption = dialog.AddCheckbox(
"Print info for Failed Attempts", AFK.BounceWiggle.PrintFailures
)
currentDialog.NoShakeButton = dialog.AddButton("Wiggle Only", 1)
currentDialog.ShakeButton = dialog.AddButton("Shake", 2)
if (AFK.IsMutable) then
currentDialog.MutateButton = dialog.AddButton("Mutate", 3)
end
currentDialog.CancelButton = dialog.AddButton("Skip to endgame", 0) --jon
local choice = dialog.Show(currentDialog)
AFK.BounceWiggle.Iterations = currentDialog.IterationsSlider.value
AFK.BounceWiggle.MinGain = currentDialog.DiscardSlider.value
AFK.BounceWiggle.SkipCIMaximization = currentDialog.SkipMaximization.value
AFK.BounceWiggle.PrintFailures = currentDialog.PrintFailuresOption.value
if (AFK.BounceWiggle.Iterations < 1) then
AFK.BounceWiggle.Iterations = -1
end
if (choice > 0) then
AFK.Helper.PrintStart(choice)
end
return choice
end
-------------------
-- The main dish --
-------------------
AFK.BounceWiggle.Main = function()
AFK.Helper.IsMutable()
local startScore = AFK.StartScore
local choice = AFK.CreateBounceWiggleDialog()
if (choice < 1) then
print("Dialog cancelled.")
return
end
save.Quicksave(AFK.SaveSlot)
recentbest.Save()
if (AFK.BounceWiggle.SkipCIMaximization == false) then
AFK.Helper.PerformFunction(AFK.BounceWiggle.CIMaximization)
startScore = current.GetEnergyScore()
end
print("Script started: "..startScore)
while (AFK.BounceWiggle.DogDays < AFK.BounceWiggle.Iterations) do
startScore = current.GetEnergyScore()
AFK.Helper.PerformFunction(AFK.BounceWiggle.BounceWiggle)
AFK.Helper.UpdateIterations(current.GetEnergyScore() - startScore)
end
AFK.Helper.PrintEnd(current.GetEnergyScore() - startScore)
AFK.Cleanup()
end
-------------------------
-- The BounceWiggliest --
-------------------------
AFK.BounceWiggle.CIMaximization = function()
local currentScore = AFK.StartScore
local newScore = currentScore + AFK.BounceWiggle.MinGain + 0.01
print("Maximizing Wiggle Score at Clashing Importance = 1: "..currentScore)
AFK.Helper.SetCI(1)
while (currentScore + AFK.BounceWiggle.MinGain < newScore) do
structure.WiggleAll(25)
structure.LocalWiggleAll(25)
recentbest.Restore()
currentScore = newScore
newScore = current.GetEnergyScore()
end
if (newScore > AFK.StartScore) then
print ("CI Maximization: + "..(currentScore - AFK.StartScore)..
" -- "..currentScore)
end
end
AFK.BounceWiggle.WiggleAll = function(ci, wiggleIterations)
AFK.Helper.SetCI(ci)
wiggleIterations = wiggleIterations or math.random(1, 3)
local wiggleType = math.random(1, 2)
if (wiggleType > 1) then
structure.WiggleAll(wiggleIterations)
else
structure.LocalWiggleAll(wiggleIterations)
end
end
AFK.BounceWiggle.ShakeityShake = function()
local shakeType = math.random(1, 3)
local shakeIterations = math.random(1, 3)
AFK.Helper.SetCI()
-- 1/3 chance of whole protein
if (shakeType > 2) then
if (AFK.BounceWiggle.DoMutate == true) then
-- When mutating all, we only do one iteration.
-- This is to increase BounceWiggle speed, to explore more
-- configurations faster.
structure.MutateSidechainsAll(1)
else
structure.ShakeSidechainsAll(shakeIterations)
end
-- 2/3 chance of random selection
else
AFK.Helper.SelectRandom()
if (AFK.BounceWiggle.DoMutate == true) then
structure.MutateSidechainsSelected(shakeIterations)
else
structure.ShakeSidechainsSelected(shakeIterations)
end
selection.DeselectAll()
end
end
AFK.BounceWiggle.BounceWiggle = function()
AFK.BounceWiggle.WiggleAll()
if (AFK.BounceWiggle.DoShake == true
or AFK.BounceWiggle.DoMutate == true) then
AFK.BounceWiggle.ShakeityShake()
end
AFK.BounceWiggle.WiggleAll(1, 25)
end
-------------
-- The end --
-------------
function AFK.Cleanup(errorMessage)
behavior.SetClashImportance(AFK.StartCI)
recentbest.Restore()
selection.DeselectAll()
-- Re enable all filters
behavior.SetFiltersDisabled(false)
end
xpcall(AFK.BounceWiggle.Main, AFK.Cleanup)
end --while true
----------------------------------------------------------------- ==jon copy
--Banded Worm Pairs Infinite (& Filter)
------------------------------------------------------------------------------
-- Banded Worm
------------------------------------------------------------------------------
-- Modifies Worm LWS v2 by rav3n_pl
--
-- by KarenCH
------------------------------------------------------------------------------
-- Made infinite and filters optimized by Bruno Kestemont 15/2/2015
-- v 1.1 corrected random contact map 20/9/2015
-- v 1.2 added random use of user bands (and random multiplier of their strength)
-- v 1.2.1 undo.SetUndo
-- v 1.3.0 BAND_TO_SIDECHAINS allowed
-- v 1.3.1 Fixed unideal loop bug (thanks to gitwut) (band= true)
-- v 1.3.2 Second attempt to fix it (added save.Quickload)
-- v 1.4 Dialog for filters
-- v 1.4.1 and tried again to fix GENERICFILTER on recentbest (see feedback discussion, Foldit Bug)
-- replaced by FakeRecentBestSave() and FakeRecentBestRestore() 29/8/2017
-- v 1.4.2 added Ligand dialog
-- v 1.4.3 systematic display of current score (Greg's suggestion), again fixing filter bug
-- v 1.4.4 fixed detect bonusses
-- v 1.4.5 fixed segMeanScore=(scoreboard.GetGroupScore()-8000)/segCnt
--TO DO = probability otions in advanced dialog
recipename= "Banded Worm Pairs Inf Filter 1.4.5"
undo.SetUndo(false)
-- interesting global variables that users might want to modify
PROB_CHOOSE_USERBANDS = 0.10 -- don't put it too high
PROB_CHOOSE_CONTACTMAP = 0.60
PROB_PUTBAND = 1.0 -- how often do we put bands in our wiggle steps?
PROB_BIS_NOT_BETWEEN = 0.25 -- do we prefer BIS or bands between segs
PROB_2ND_IS_BIS = 0.50
PROB_BETWEEN_USES_ATOM = 0.50 -- between: should wiggled seg have band from non-default atom
BAND_STRENGTH_DEFAULT = 1.0
PROB_BAND_TO_LIGAND= 0 -- prob band to ligand if ligand
-- less interesting global variables that users might consider modifying
BIS_LENGTH = 5.0 -- max length of a BIS
SCALE_MAXCI = 1.0
CONTACTMAP_THRESHOLD = 0.25 -- min heat of contacts
USENORMALSCORE = true -- exploration puzzles would set false
DEBUGRUN = false -- mostly goes with DebugPrint, but could get more use later
-- atoms in an amino acid
BETA_CARBON = 5
TERMINAL_BETA = 6 -- not used
CENTER_CARBON = 2 --this is the default atom for bands to attach to
BAND_TO_SIDECHAINS = true -- New BK, some bands to sidechains as well
-- variables users probably don't want to play with (SLOTS)
QS_Start = 1
QS_Best = 3
Qs_Recent = 5 -- for debugging recentbest bug
Qs_Current = 6 -- for debugging recentbest score
-- variables users really shouldn't play with
PuzzleHasContactMap = false
PuzzleHasLockedSegs = false
EndCalled = false
InitialScore = 0.0 -- not important: will be reinitialized in InitializePuzzleState( )
StartTime = 0 -- not important: will be reinitialized in InitializePuzzleState( )
CurrentBestScore = 0 -- not important: will be reinitialized in InitializePuzzleState( )
InitialClashImportance = behavior.GetClashImportance()
NonLockedSegList = {}
segCt = structure.GetCount()
MinUnlockedSeg = 1
MaxUnlockedSeg = segCt
segCnt2=segCt
while structure.GetSecondaryStructure(segCnt2)=="M" do segCnt2=segCnt2-1 end
FirstLigand= segCnt2 -- 0 if no ligand
LastLigand= segCt
InitialBandCount = 0
ubcount = 0 -- user bands
ubandlist={} -- {band number, band strength, goal_length}
USERBANDS=false
PROBABLEFILTER=false
--FILTERMANAGE=false -- default yes during wiggle (will always be activate when scoring)
GENERICFILTER=false
PROBABLELIGAND=false
GENERICLIGAND=false
--identifying explicitly (heavy) filtered puzzles (Contact with remain filter enabled, what is good)
--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=(scoreboard.GetGroupScore()-8000)/segCnt2 -- 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
function DialogForFilters()
ask = dialog.CreateDialog(recipename)
ask.l6 = dialog.AddLabel("Fast = filters off unless for score")
ask.l8 = dialog.AddLabel("Slow = filters always on")
ask.Fast = dialog.AddButton("Fast",1) ask.Slow = dialog.AddButton("Slow",2)
askresult=1 --dialog.Show(ask) --overridden by Jon for seamless transition
if askresult < 2 then GENERICFILTER=true
end
end
function DialogForLigand()
ask = dialog.CreateDialog(recipename)
ask.l6 = dialog.AddLabel("Ligand = move ligand")
ask.l8 = dialog.AddLabel("All = move all")
ask.Fast = dialog.AddButton("Ligand",1) ask.Slow = dialog.AddButton("All",2)
askresult=dialog.Show(ask)
if askresult> 1 then GENERICLIGAND=false
else GENERICLIGAND=true
end
end
if PROBABLEFILTER then DialogForFilters() end
if PROBABLELIGAND then DialogForLigand() end
if GENERICLIGAND and not FirstLigand == 0 then --there should be a ligand but who knows
PROB_BAND_TO_LIGAND=1
end
--START Generic Filter Management by BitSpawn 21/12/2014, updated by Bruno Kestemont 4/1/2019
--Source: http://fold.it/portal/node/1998917
--Note: GENERICFILTER must be defined elsewhere (otherwise, it will not do anything)
-- GENERICFILTER=true
-- 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 filter.AreAllEnabled()==false then
filter.EnableAll()
end
end
function FiltersOff()
if filter.AreAllEnabled() then
filter.DisableAll()
end
end
-- function to overload a function
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)
if GENERICFILTER then -- WARNING: TO VERIFY !! (may be it's irreversible for several funtions bellow)
MutClass(structure, false)
MutClass(band, true) -- if false, you have to enable filter just afterwards (otherwise unideal filter bug)
MutClass(current, true)
MutClass(recentbest, true) -- otherwise, it remembers cut solutions
MutClass(save, true) -- better to save with full score
end
--STOP Generic Filter Management
------------------------------------------------------------------------------
-- FUNCTIONS
------------------------------------------------------------------------------
function BandedWorm( pattern )
startseg=1 --math.random(#NonLockedSegList-pattern[1]+1)
--recentbest.Save( )
FakeRecentBestSave()
SetCI( 1.0 )
SaveBest( )
local ss = getScore()
local idx=1
for w = 1, #pattern do
save.Quickload( QS_Best ) -- new for DEBUG
if puzzle.GetExpirationTime()<os.time() then --jon
print("expired, local break")
break
end
len = pattern[ w ]
local sw = getScore()
local swCurr = sw
print( "Starting BandedWormPairs of len " .. len .. ", score: ".. TrimNum( getScore() ) )
for iNon=startseg, #NonLockedSegList - len + 1 do
s=NonLockedSegList[iNon] -- unlocked unlocked locked locked unlocked unlocked --jon
selection.DeselectAll()
selection.SelectRange( s, s + len - 1 )
if random( ) < PROB_PUTBAND then
if random( ) < PROB_BAND_TO_LIGAND then
idx= random( Firstligand, LastLigand)
else
idx = random( s, s + len - 1 )
end
PutSingleRandomBandToSeg( idx, PROB_BIS_NOT_BETWEEN )
if random( ) < 0.25 then
local idx2 = random( s, s + len - 1 )
PutSingleRandomBandToSeg( idx2, PROB_2ND_IS_BIS )
end
uBandEnabel() -- new v1.2 random adding one of the user bands
structure.LocalWiggleSelected( random(2,4) )
ManageBands( )
structure.WiggleAll( 2 )
end
structure.LocalWiggleSelected( 5 )
local swNew = getScore( )
local gain = swNew - swCurr
if gain > 0 then
structure.LocalWiggleSelected( 20 )
--recentbest.Restore( )
FakeRecentBestRestore()
ManageBands( )
swNew = getScore( )
gain = swNew - swCurr
if TrimNum( gain ) > 0 then
print( ">>>> At " .. s .. ": Gained ".. TrimNum( gain ).." Score: "..TrimNum( swNew ))
end
SaveBest( )
swCurr = swNew
else
--recentbest.Restore( )
FakeRecentBestRestore()
structure.LocalWiggleSelected( 4 )
end
--recentbest.Restore( )
FakeRecentBestRestore()
ManageBands( )
--structure.WiggleAll(1)
--structure.DeleteCut(structure.GetCount())
--jon's intentionally useless functions to bide time to not crash foldit
end
startseg=1
print( "Pattern gain: ".. getScore( ) - sw )
SaveBest( )
end
selection.DeselectAll()
print( "Total BandedWormPairs gain: " .. TrimNum( getScore( ) - ss ) )
end
function PutSingleRandomBandToSeg( idx, probBis )
changeSucceeded = false
local strength = random( 0.5 * BAND_STRENGTH_DEFAULT,
1.5 * BAND_STRENGTH_DEFAULT,
true )
local doBIS = random( ) < probBis
if doBIS then
changeSucceeded = PutBandInSpace( idx, BIS_LENGTH, strength )
else
if SegHasContactData( idx, CONTACTMAP_THRESHOLD ) and
random( ) < PROB_CHOOSE_CONTACTMAP -- changed > to < BK
then
local doSidechain = random( ) < PROB_BETWEEN_USES_ATOM
changeSucceeded = PutSomeContactMapBands( CONTACTMAP_THRESHOLD, strength, 1, doSidechain )
else
local atom = PickAtomNumberForBand( idx )
changeSucceeded = PutBandToRandomSeg( idx, 5, strength, atom )
end
end
return changeSucceeded
end
----------------------------------------------------------------
--
---------------- BOILERPLATE ---------------------
--
----------------------------------------------------------------
----------------------------------------------------------------
-- BASIC FUNCTIONALITY
----------------------------------------------------------------
function DebugPrint( str )
if DEBUGRUN then print( str ) end
end
function TrimNum( val )
return val - val % 0.001
end
-- Not for "external" use - call getScore. This could change if customers want
-- something besides current or recentbest.
function internalGetScore( wantRB )
if wantRB == nil then wantRB = false end
local s=0.0
if not USENORMALSCORE then
if wantRB then
--s = recentbest.GetEnergyScore( )
s= FakeRecentBestGetEnergyScore()
else s=current.GetEnergyScore( )
end
else
if wantRB then
--s = recentbest.GetScore( )
s = FakeRecentBestGetScore()
else s=current.GetScore( )
end
end
return s
end
function getScore( )
return internalGetScore( false )
end
function getRBScore( )
return internalGetScore( true )
end
function SaveBest( )
local score = getScore( )
if score > CurrentBestScore then
save.Quicksave( QS_Best )
CurrentBestScore = score
end
-- CheckFullScore() -- for DEBUG only
end
--START Debugging Recentbest Foldit Bug Temporary solution of Foldit bug (BK 29/8/2017)
function Score() -- for BWPIF only
return current.GetScore()
end
function FakeRecentBestSave()
if PROBABLEFILTER then -- trying to solve the Foldit bug
save.Quicksave(Qs_Recent)
else
recentbest.Save()
end
end
function FakeRecentBestRestore()
if PROBABLEFILTER then -- trying to solve the Foldit bug
local ss=Score()
recentbest.Restore() -- filter disabled (bug)
local se=Score() -- now with the filter
if se > ss then
save.Quicksave(Qs_Recent)
end
save.Quickload(Qs_Recent)
else
recentbest.Restore()
end
end
function FakeRecentBestGetScore()
if PROBABLEFILTER then -- trying to solve the Foldit bug
save.Quicksave(Qs_Current)
recentbest.Restore() -- filter disabled (bug)
local se=Score() -- now with the filter
save.Quickload(Qs_Current)
return se
else
recentbest.GetScore( )
end
end
function FakeRecentBestGetEnergyScore()
if PROBABLEFILTER then -- trying to solve the Foldit bug
save.Quicksave(Qs_Current)
recentbest.Restore() -- filter disabled (bug)
local se=current.GetEnergyScore( ) -- now with the filter
save.Quickload(Qs_Current)
return se
else
recentbest.GetEnergyScore( )
end
end
--END Debugging Recentbest Foldit Bug
--[[
function CheckFullScore() -- check without filter (only for DEBUG)
if filter.AreAllEnabled()==false then
DebugPrint ("DEBUG: filter is off, turning on")
FiltersOn()
end
end
]]--
function SetCI( ci )
behavior.SetClashImportance( SCALE_MAXCI * ci )
end
------------- CONTACTMAP FUNCTIONS ------------
function CheckForContactMap( )
PuzzleHasContactMap = false
local saveval = 0.0
for i=1, segCt-1 do
for j=i+1, segCt do
val = contactmap.GetHeat( i, j )
if saveval ~= 0.0 and val ~= saveval then
PuzzleHasContactMap = true
ContactMapScore = GetContactScore( )
return -- all we wanted to know was whether scores exist
end
if saveval == 0.0 then saveval = val end
end
end
return
end
function SegHasContactData( segIn, heatThreshold )
for i = 1, segCt do
if i < segIn - 1 or i > segIn + 1 then
if contactmap.GetHeat( segIn, i ) >= heatThreshold then return true end
end
end
return false
end
function InitializeContactMapSegList( heatThreshold )
HasContactMapSegList = {}
for i = 1, segCt do
if SegHasContactData( i, heatThreshold ) then
HasContactMapSegList[ #HasContactMapSegList + 1 ] = i
end
end
end
function GetContactScore( )
if not PuzzleHasContactMap then return 0 end
local sum = 0.0
local segCt = structure.GetCount( )
for i = 1,segCt-1 do
for j = i + 1, segCt do
if contactmap.IsContact( i, j ) then sum = sum + contactmap.GetHeat( i, j ) end
end
end
return sum
end
----------------------- MATHY STUFF -----------------------
function seedRandom()
seed=os.time( )/math.abs( getScore( ) )
seed=seed%0.001
seed=1/seed
while seed<10000000 do seed=seed*1000 end
seed=seed-seed%1
DebugPrint( "Seed is: "..seed )
math.randomseed( seed )
-- throw away a couple of randoms
math.random( )
math.random( )
end
function random( n1,n2, forceFloat ) --random function returns int or float depends on input vars
if forceFloat == nil then forceFloat = false end
if n1==nil then
return math.random()
else
if n2==nil then
if n1 == 0 then return 0 end -- a random number between 0 and 0 is 0
if n1%1==0 then -- can't test for "forceFloat", so caller must beware
return math.random( n1) --integer
else
return math.random( ) * n1 --float
end
else
if n1%1==0 and n2%1==0 and not forceFloat then
return math.random( n1, n2 ) --integer between
else
return math.random( ) * (n2 - n1) + n1 --float between
end
end
end
end
function randomSeg( )
return random( segCt )
end
function randomThetaPhi()
return math.acos( random( -1.0, 1.0, true ) ), random( 2 * math.pi )
end
function randomizeIndexList( idxList )
for i=1, #idxList do
j = random( #idxList )
if j ~= i then
idxList[i], idxList[j] = idxList[j], idxList[i]
end
end
end
-- for branched aas, simply picks one (longer, one with donor/acceptor tip, or if no difference then either)
function GetAtomOfTip( aa )
if aa == "a" then return 10
elseif aa == "c" then return 10
elseif aa == "d" then return 8
elseif aa == "e" then return 9
elseif aa == "f" then return 20
elseif aa == "g" then return 0 -- glycine has no tip. just use a backbone atom
elseif aa == "h" then return 17
elseif aa == "i" then return 18
elseif aa == "k" then return 9
elseif aa == "l" then return 16
elseif aa == "m" then return 17
elseif aa == "n" then return 14
elseif aa == "p" then return 13
elseif aa == "q" then return 9
elseif aa == "r" then return 22
elseif aa == "s" then return 11
elseif aa == "t" then return 6
elseif aa == "v" then return 13
elseif aa == "w" then return 24
elseif aa == "y" then return 12
else return 0
end
end
function GetTipAtomOfSeg( idx )
return GetAtomOfTip( structure.GetAminoAcid( idx ))
end
function PickAtomNumberForBand( idx )
if not BAND_TO_SIDECHAINS then return CENTER_CARBON end
local r = random( 1, 4 ) -- consider adjusting probability?
if r == 1 then
return BETA_CARBON
elseif r == 2 then
return CENTER_CARBON
else
return GetTipAtomOfSeg( idx ) -- 50% of the cases
end
end
function IsUnlockedSeg( seg1 )
return not structure.IsLocked( seg1 )
end
function FindAllMovableSegs( )
for i=1, segCt do
if structure.IsLocked( i ) then
PuzzleHasLockedSegs = true
else
NonLockedSegList[ #NonLockedSegList + 1] = i
end
end
if PuzzleHasLockedSegs then
for i=1, segCt do
if IsUnlockedSeg( i ) then
MinUnlockedSeg = i
break
end
end
for i=segCt, 1, -1 do
if IsUnlockedSeg( i ) then
MaxUnlockedSeg = i
break
end
end
end
return false
end
----------------------- BANDY STUFF -----------------------
function uMakeBands() -- list of existing user bands, strength, goal length
ubcount=band.GetCount()
for i=1, ubcount do
ubandlist[i]={i, band.GetStrength(i), band.GetGoalLength(i)} -- {band number, band strength, goal_length}
end
if #ubandlist==0 then
USERBANDS=false
else
USERBANDS=true
end
return ubandlist
end
function uBandEnabel() -- random enable a user band
if USERBANDS and PROB_CHOOSE_USERBANDS >= random(0.0,1.0) then
local maxstrength= 5
local minstrength=0.1
local bandIndex= random(1,ubcount)
local multiplier = random( 0.5,2)
local bandstrength=band.GetStrength(bandIndex)
bandstrength=ubandlist[bandIndex][2]*multiplier
if bandstrength>maxstrength then
bandstrength=maxstrength
elseif bandstrength<minstrength then
bandstrength=minstrength
end
band.SetStrength(bandIndex, bandstrength) -- to do: random length?
band.Enable(bandIndex)
end
end
function ManageBands() --delete recipe bands, disable user bands
if ubcount==0 or ubcount==nil then band.DeleteAll()
else
local bands=band.GetCount()
if bands>ubcount then
for i=bands, ubcount+1, -1 do band.Delete(i) end -- TO DO: il reste peut etre une bande ici
end
end
band.DisableAll()
end
function BandBetweenSegsWithParameters( seg1, seg2, strength, goalLength, atom1, atom2 )
if not ( IsUnlockedSeg( seg1 ) or IsUnlockedSeg( seg2 ) ) then return false end
if atom1 == nil then atom1 = CENTER_CARBON end
if atom2 == nil then atom2 = CENTER_CARBON end
local bIdx = band.AddBetweenSegments( seg1, seg2, atom1, atom2 )
if bIdx ~= band.GetCount( ) then
DebugPrint( "failed to add band from "..seg1.." to "..seg2)
return false
end
if bIdx <= InitialBandCount then return true end -- don't change user-supplied bands
if goalLength ~= nil then
band.SetGoalLength( bIdx, goalLength )
end
if strength ~= nil and strength > 0.0 then
band.SetStrength( bIdx, strength )
end
return true
end
function BandInSpaceWithParameters( seg, segFini, segInit, rho, theta, phi, strength, goalLength, atomIndexOrigin, atomIndexXAxis, atomIndexYAxis)
if not ( IsUnlockedSeg( seg) ) then return false end
local atomIndexOrigin, atomIndexXAxis, atomIndexYAxis = atomIndexOrigin or CENTER_CARBON, atomIndexXAxis or 0, atomIndexYAxis or 0
local bIdx = band.Add( seg, segFini, segInit, rho, theta, phi, atomIndexOrigin, atomIndexXAxis, atomIndexYAxis )
if bIdx ~= band.GetCount( ) then return false end
if bIdx <= InitialBandCount then return true end -- don't change user-supplied bands
if goalLength ~= nil then
band.SetGoalLength( bIdx, goalLength )
end
if strength ~= nil and strength ~= 0.0 then
band.SetStrength( bIdx, strength )
end
return true
end
function PutBandInSpace( idx, maxRho, strength )
local atomIndexOrigin, atomIndexXAxis, atomIndexYAxis = 0,0,0 -- x and y not used actually
local idx2, idx3
if idx < segCt then
idx2 = idx + 1
else
idx2 = idx - 2
end
if idx > 1 then
idx3 = idx - 1
else
idx3 = idx + 2
end
-- random point in sphere of radius maxRho
local theta, phi = randomThetaPhi( )
local rho = (maxRho * random()^(1/3)) + 0.001
-- random atom for the banded (BIS) segment
local MaxatomIndexOrigin = PickAtomNumberForBand( idx ) -- it's the end of the sidechain
atomIndexOrigin = random( 0 , MaxatomIndexOrigin )
return BandInSpaceWithParameters( idx, idx2, idx3, rho, theta, phi, strength, atomIndexOrigin, atomIndexXAxis, atomIndexYAxis )
end
function PutBandToRandomSeg( idx, minGap, strength, atom )
needNew = true
local failedTries = 0
while ( needNew and failedTries < 30 ) do
idx2 = randomSeg( ) -- ok if this one isn't movable (we assume idx is movable)
if idx2 > idx + minGap or idx2 < idx - minGap then
needNew = false
break
else
failedTries = failedTries + 1
end
end
if not needNew then
return BandBetweenSegsWithParameters( idx, idx2, strength, nil, atom, nil )
end
return false
end
function PutSomeContactMapBands( heatThreshold, strength, ctBands, doSidechains )
changeSucceeded = false
local hotList = {}
for i = 1, segCt-2 do
for j = i+2, segCt do
local heat = contactmap.GetHeat(i, j)
if heat >= heatThreshold and not contactmap.IsContact( i , j ) then
hotList[ #hotList + 1] = { i, j, heat }
end
end
end
randomizeIndexList( hotList )
for i=1, math.min( ctBands, #hotList ) do
local atom1 = nil
local atom2 = nil
if BAND_TO_SIDECHAINS and doSidechains then
atom1 = PickAtomNumberForBand( hotList[i][1] )
atom2 = PickAtomNumberForBand( hotList[i][2] )
end
local ch = BandBetweenSegsWithParameters( hotList[i][1], hotList[i][2], strength, nil, doTip1, doTip2 )
changeSucceeded = ch or changeSucceeded
end
return changeSucceeded
end
--------------------------------------------------------------------------
-- SETUP, CLEANUP, and MAIN
--------------------------------------------------------------------------
function CleanPuzzleState( )
SetCI( 1.0 )
selection.DeselectAll()
ManageBands()
end
function PrintState( )
local gain = getScore() - InitialScore
if gain < 0.001 then
print( " No change" )
else
print( " Startscore: "..TrimNum( InitialScore ))
print( " Score: "..TrimNum( getScore() ) )
print( " Total gain: "..TrimNum( gain ))
end
print( " Run time: "..os.time() - StartTime)
end
function End( errstr )
undo.SetUndo(true)
if EndCalled then return end -- no infinite recursion please
EndCalled = true
print( "" )
if errstr ~= nil then
if string.find( errstr, "Cancelled" ) then
print( "User cancel" )
else
print( errstr )
end
end
save.Quickload( QS_Best )
PrintState( )
CleanPuzzleState( )
end
function InitializePuzzleState( )
seedRandom( )
InitialScore = getScore( )
CurrentBestScore = InitialScore
StartTime = os.time()
save.Quicksave( QS_Start )
save.Quicksave( QS_Best )
InitialClashImportance = behavior.GetClashImportance()
SCALE_MAXCI = InitialClashImportance
uMakeBands() -- new v1.2
FindAllMovableSegs( )
CheckForContactMap()
if PuzzleHasContactMap then InitializeContactMapSegList( CONTACTMAP_THRESHOLD ) end
end
function main( )
for i= 1, 1000 do
InitializePuzzleState( )
local gain = 0.0
repeat
local score = getScore( )
pattern={ 2,5,11,3,13,4,7,1,6 }
BandedWorm( pattern )
gain = getScore( ) - score
until gain < 0.01
InitializePuzzleState( )
local gain = 0.0
repeat
local score = getScore( )
pattern={ 14,8,6,7,13,12,2,10,11 }
BandedWorm( pattern )
gain = getScore( ) - score
until gain < 0.01
InitializePuzzleState( )
local gain = 0.0
repeat
local score = getScore( )
pattern={ 5,7,1,3,9,6,2,4,8 }
BandedWorm( pattern )
gain = getScore( ) - score
until gain < 0.01
InitializePuzzleState( )
local gain = 0.0
repeat
local score = getScore( )
pattern={ 3,6,12,4,14,5,8,2,7 }
BandedWorm( pattern )
gain = getScore( ) - score
until gain < 0.01
InitializePuzzleState( )
local gain = 0.0
repeat
local score = getScore( )
pattern={ 3,8,4,5,12,6,10,2,7}
BandedWorm( pattern )
gain = getScore( ) - score
until gain < 0.01 -- or puzzle.GetExpirationTime()<os.time() --jon
--jon
if puzzle.GetExpirationTime()<os.time() then
print("expired")
break
end
end
End( )
end
xpcall( main, End )