Code
-- Converted from v1 lua by Rav3n_pl v1 to v2 converter
--[[
Random Hydro Puller v1.0
Pulling all hydrophobes to center segment
on request by Primalsoul :)
]]--
--- OPTIONS
qLoops=50 --number of tries
minBS=0.3 --starning minimum bands strenght
maxBS=1.0 --maximum bads str
maxLoss=1 --minimum percentage loss when pulling. ie 5% of 10000 is 500pts
pullingCI=1.0 --clash importance while pulling
fastQstab=false --true for 1s1w as stabilize (faster)
doFuze=-1 --run fuze when score after qstabilize is close to best. If negative run fuze only if gain after qstab
energy=false --set true for exploration puzzles if want seek stability
pullDist=4 --make bands shorter by that many units
-- end of options
math.randomseed(recipe.GetRandomSeed())
p=print
CI=behavior.SetClashImportance
segCnt=structure.GetCount()
while structure.GetSecondaryStructure(segCnt)=="M" do segCnt=segCnt-1 end
function Score()
local s=0
if energy==true then
s=current.GetEnergyScore()
else
s=current.GetScore()
end
return s
end
function round(x)--cut all afer 3-rd place
return x-x%0.001
end
function abs(x)
if x<0 then x=-x end
return x
end
function Wiggle(how, iters, minppi) --score conditioned recursive wiggle/shake
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
local sp=Score()
if how == "s" then structure.ShakeSidechainsSelected(1)
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
if Score()-sp > minppi then return Wiggle(how, iters, minppi) end
end
end
function AllLoop() --turning entire structure to loops
local ok=false
for i=1, segCnt do
local s=structure.GetSecondaryStructure(i)
if s~="L" then
save.SaveSecondaryStructure()
ok=true
break
end
end
if ok then
selection.SelectAll()
structure.SetSecondaryStructureSelected("L")
end
end
function FastCenter() --by Rav3n_pl based on Tlaloc`s
p('Filling distances table...')
local distances={}
local segmentCount = structure.GetCount()
local minDistance = 1000000
local distance=0
local indexCenter=0
for i=1,segmentCount-1 do --filling table
distances[i]={} --need to delclare second dimension
for j=i+1,segmentCount do --not counting from beginning - not need :)
distances[i][j]=structure.GetDistance(i,j)
end
end
p("Calculating distances...")
for i=1,segmentCount do
distance = 0
for j=1,segmentCount do
if i~=j then
local x=i
local y=j
if x>y then x,y=y,x end
distance = distance + distances[x][y]
end
end
if(distance < minDistance) then
minDistance = distance
indexCenter = i
end
end
p("Done, center= "..indexCenter)
return indexCenter
end
function RandomInt(high)
return math.random(high)
end
bestScore=Score()
function SaveBest()
local s=Score()
local g=s-bestScore
if g>0 then
if g>0.01 then p("Gained another "..round(g).." pts.") end
bestScore=s
save.Quicksave(3)
end
end
function bandstr(str) --set all band strengt
for i=1, band.GetCount() do
band.SetStrength(i, str)
end
end
function delBands() --delete all bands
band.DeleteAll()
end
function down(x)--cut all after comma
return x-x%1
end
function round(x)--cut all afer 3-rd place
return x-x%0.001
end
function SaveRB()
save.Quicksave(4)
recentbest.Restore()
SaveBest()
save.Quickload(4)
end
function qStab()
selection.SelectAll()
CI(0.1)
Wiggle("s",1)
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 MakeBands(center)
for i=1,segCnt do
if structure.IsHydrophobic(i) then
local bn1=band.GetCount()
band.AddBetweenSegments(i,center)
bn1=band.GetCount()-bn1
if bn1>0 then
local d=structure.GetDistance(i,center)
d=d-pullDist
if d<1 then d=1 end
band.SetGoalLength(band.GetCount(),d)
end
end
end
end
function HP()
center=0 --FastCenter()
lastBS=minBS
local qsc=Score()
save.Quicksave(3)
p("Starting Hydro Puller v1.0 , "..qLoops.." tries. Start score: "..round(qsc))
local dd=down(segCnt/10)
for x=1, qLoops do
center=RandomInt(segCnt)
local ls=Score()
local loss=round(ls*(maxLoss/100))
p("Pass "..x.." of "..qLoops.." pulling to: "..center)
MakeBands(center)
p("Made "..band.GetCount().." bands, pulling until loss of "..loss.." pts.")
selection.SelectAll()
CI(pullingCI)
recentbest.Save()
for str=lastBS,maxBS,0.07 do--search enough band strenght to move
recentbest.Restore() --because sometimes it makes points during pull :D
ss=Score()
bandstr(str)
structure.WiggleAll(1, true,false)
if ss-Score()>loss then
lastBS=str-0.1
if lastBS<minBS then lastBS=minBS end
break
end
end
delBands()
SaveRB() --because sometimes it missing fractions
p("Stabilizing...")
CI(1)
recentbest.Save() --after pulling
qStab()
if Score()>ls+doFuze then
SaveBest()
Fuze(4)
end
SaveBest()
save.Quickload(3) --load best state
p("Current score: "..round(Score()).." Total gain: "..round(Score()-qsc))
end
p("Total HP gain: "..round(Score()-qsc))
end
--main call
HP()
-- end of script