Merge remote-tracking branch 'tech/imple/revise-seq-generator'
This commit is contained in:
@@ -43,8 +43,8 @@ function bot_cc:revive()
|
||||
self.P:loadAI(self.data)
|
||||
end
|
||||
function bot_cc:pushNewNext(id)
|
||||
self.ccBot:addNext(rem(self.bufferedNexts,1))
|
||||
ins(self.bufferedNexts,id)
|
||||
self.ccBot:addNext(rem(self.bufferedNexts,1))
|
||||
end
|
||||
function bot_cc:thread()
|
||||
local P,keys=self.P,self.keys
|
||||
|
||||
@@ -1,78 +1,77 @@
|
||||
local ins=table.insert
|
||||
local yield=coroutine.yield
|
||||
return {
|
||||
env={
|
||||
drop=20,lock=60,
|
||||
sequence=function(P)
|
||||
for _=1,3 do P:getNext(7) end
|
||||
sequence=function(seqRND)
|
||||
local field,stat
|
||||
for _=1,3 do field,stat=yield(7) end
|
||||
while true do
|
||||
coroutine.yield()
|
||||
if not P.nextQueue[1] then
|
||||
local height=TABLE.new(0,10)
|
||||
local max=#P.field
|
||||
if max>0 then
|
||||
-- Get heights
|
||||
for x=1,10 do
|
||||
local h=max
|
||||
while P.field[h][x]==0 and h>1 do
|
||||
h=h-1
|
||||
end
|
||||
height[x]=h
|
||||
end
|
||||
else
|
||||
for x=1,10 do
|
||||
height[x]=0
|
||||
local height=TABLE.new(0,10)
|
||||
local max=#field
|
||||
if max>0 then
|
||||
-- Get heights
|
||||
for x=1,10 do
|
||||
local h=max
|
||||
while field[h][x]==0 and h>1 do
|
||||
h=h-1
|
||||
end
|
||||
height[x]=h
|
||||
end
|
||||
height[11]=999
|
||||
|
||||
local wei={1,1,2,2,3,4}
|
||||
local d=0
|
||||
for i=1,10 do
|
||||
d=d+height[i]
|
||||
else
|
||||
for x=1,10 do
|
||||
height[x]=0
|
||||
end
|
||||
if d<40 or P.stat.row>2*42 then-- Low field or almost win, give SZO
|
||||
for _=1,4 do
|
||||
ins(wei,1)
|
||||
ins(wei,2)
|
||||
ins(wei,6)
|
||||
end
|
||||
else
|
||||
-- Give I when no hole
|
||||
local tempDeltaHei=-999-- Height difference
|
||||
for x=2,11 do
|
||||
local deltaHei=height[x]-height[x-1]
|
||||
if tempDeltaHei<-2 and deltaHei>2 then
|
||||
break
|
||||
elseif x==11 then
|
||||
for _=1,3 do ins(wei,7) end
|
||||
else
|
||||
tempDeltaHei=deltaHei
|
||||
end
|
||||
end
|
||||
|
||||
-- Give O when no d=0/give T when no d=1
|
||||
local flatCount=0-- d=0 count
|
||||
local stairCount=0-- d=1 count
|
||||
for x=2,10 do
|
||||
local _=height[x]-height[x-1]
|
||||
if _==0 then
|
||||
flatCount=flatCount+1
|
||||
elseif _==1 or _==-1 then
|
||||
stairCount=stairCount+1
|
||||
end
|
||||
end
|
||||
if flatCount<3 then
|
||||
for _=1,3 do ins(wei,6) end
|
||||
end
|
||||
if stairCount<3 then
|
||||
for _=1,4 do ins(wei,5) end
|
||||
end
|
||||
end
|
||||
P:getNext(wei[P.seqRND:random(#wei)])
|
||||
end
|
||||
height[11]=999
|
||||
|
||||
local wei={1,1,2,2,3,4}
|
||||
local d=0
|
||||
for i=1,10 do
|
||||
d=d+height[i]
|
||||
end
|
||||
if d<40 or stat.row>2*42 then-- Low field or almost win, give SZO
|
||||
for _=1,4 do
|
||||
ins(wei,1)
|
||||
ins(wei,2)
|
||||
ins(wei,6)
|
||||
end
|
||||
else
|
||||
-- Give I when no hole
|
||||
local tempDeltaHei=-999-- Height difference
|
||||
for x=2,11 do
|
||||
local deltaHei=height[x]-height[x-1]
|
||||
if tempDeltaHei<-2 and deltaHei>2 then
|
||||
break
|
||||
elseif x==11 then
|
||||
for _=1,3 do ins(wei,7) end
|
||||
else
|
||||
tempDeltaHei=deltaHei
|
||||
end
|
||||
end
|
||||
|
||||
-- Give O when no d=0/give T when no d=1
|
||||
local flatCount=0-- d=0 count
|
||||
local stairCount=0-- d=1 count
|
||||
for x=2,10 do
|
||||
local _=height[x]-height[x-1]
|
||||
if _==0 then
|
||||
flatCount=flatCount+1
|
||||
elseif _==1 or _==-1 then
|
||||
stairCount=stairCount+1
|
||||
end
|
||||
end
|
||||
if flatCount<3 then
|
||||
for _=1,3 do ins(wei,6) end
|
||||
end
|
||||
if stairCount<3 then
|
||||
for _=1,4 do ins(wei,5) end
|
||||
end
|
||||
end
|
||||
field,stat=yield(wei[seqRND:random(#wei)])
|
||||
end
|
||||
end,
|
||||
nextCount=1,holdCount=0,
|
||||
trueNextCount=1,nextCount=1,holdCount=0,
|
||||
ospin=false,
|
||||
freshLimit=15,
|
||||
eventSet='checkLine_100',
|
||||
|
||||
@@ -33,7 +33,7 @@ return {
|
||||
bone=false,
|
||||
lockout=false,
|
||||
fieldH=20,heightLimit=1e99,
|
||||
nextCount=6,nextStartPos=1,
|
||||
trueNextCount=10,nextCount=6,nextStartPos=1,
|
||||
holdMode='hold',holdCount=1,
|
||||
infHold=false,phyHold=false,
|
||||
ospin=true,deepDrop=false,
|
||||
|
||||
@@ -328,17 +328,32 @@ local function _applyGameEnv(P)-- Finish gameEnv processing
|
||||
ENV.nextPos=false
|
||||
end
|
||||
|
||||
P.newNext=coroutine.wrap(getSeqGen(P))
|
||||
P:newNext(P.gameEnv.seqData)
|
||||
if ENV.noInitSZO then
|
||||
for _=1,5 do
|
||||
local C=P.nextQueue[1]
|
||||
if C and (C.id==1 or C.id==2 or C.id==6) then
|
||||
table.remove(P.nextQueue,1)
|
||||
else
|
||||
break
|
||||
end
|
||||
local seqGen=coroutine.create(getSeqGen(ENV.sequence))
|
||||
local seqCalled=false
|
||||
local initSZOcount=0
|
||||
function P:newNext()
|
||||
local status,piece
|
||||
if seqCalled then
|
||||
status,piece=coroutine.resume(seqGen,P.field,P.stat)
|
||||
else
|
||||
status,piece=coroutine.resume(seqGen,P.seqRND,P.gameEnv.seqData)
|
||||
seqCalled=true
|
||||
end
|
||||
if status and piece then
|
||||
if ENV.noInitSZO and initSZOcount<5 then
|
||||
initSZOcount=initSZOcount+1
|
||||
if piece==1 or piece==2 or piece==6 then
|
||||
return self:newNext()
|
||||
else
|
||||
initSZOcount=5
|
||||
end
|
||||
end
|
||||
P:getNext(piece)
|
||||
elseif not status then
|
||||
assert(piece=='cannot resume dead coroutine')
|
||||
end
|
||||
end
|
||||
for _=1,ENV.trueNextCount do
|
||||
P:newNext()
|
||||
end
|
||||
|
||||
|
||||
@@ -1436,7 +1436,7 @@ function Player:popNext(ifhold)-- Pop nextQueue to hand
|
||||
|
||||
if self.nextQueue[1] then
|
||||
self.cur=rem(self.nextQueue,1)
|
||||
self.newNext()
|
||||
self:newNext()
|
||||
self.pieceCount=self.pieceCount+1
|
||||
|
||||
local pressing=self.keyPressing
|
||||
|
||||
@@ -2,25 +2,20 @@ local ins,rem=table.insert,table.remove
|
||||
local yield=coroutine.yield
|
||||
|
||||
local seqGenerators={
|
||||
none=function() while true do yield() end end,
|
||||
bag=function(P,seq0)
|
||||
local rndGen=P.seqRND
|
||||
none=function() end,
|
||||
bag=function(rndGen,seq0)
|
||||
local len=#seq0
|
||||
local bag={}
|
||||
while true do
|
||||
while #P.nextQueue<10 do
|
||||
if #bag==0 then
|
||||
for i=1,len do
|
||||
bag[i]=seq0[len-i+1]
|
||||
end
|
||||
if #bag==0 then
|
||||
for i=1,len do
|
||||
bag[i]=seq0[len-i+1]
|
||||
end
|
||||
P:getNext(rem(bag,rndGen:random(#bag)))
|
||||
end
|
||||
yield()
|
||||
yield(rem(bag,rndGen:random(#bag)))
|
||||
end
|
||||
end,
|
||||
bagES=function(P,seq0)
|
||||
local rndGen=P.seqRND
|
||||
bagES=function(rndGen,seq0)
|
||||
local len=#seq0
|
||||
local bag=TABLE.shift(seq0)
|
||||
do-- Get a good first-bag
|
||||
@@ -40,52 +35,44 @@ local seqGenerators={
|
||||
end
|
||||
end
|
||||
-- Finish
|
||||
for i=1,len do P:getNext(bag[i]) end
|
||||
for i=1,len do yield(bag[i]) end
|
||||
end
|
||||
bag={}
|
||||
while true do
|
||||
while #P.nextQueue<10 do
|
||||
if #bag==0 then
|
||||
for i=1,len do
|
||||
bag[i]=seq0[len-i+1]
|
||||
end
|
||||
if #bag==0 then
|
||||
for i=1,len do
|
||||
bag[i]=seq0[len-i+1]
|
||||
end
|
||||
P:getNext(rem(bag,rndGen:random(#bag)))
|
||||
end
|
||||
yield()
|
||||
yield(rem(bag,rndGen:random(#bag)))
|
||||
end
|
||||
end,
|
||||
his=function(P,seq0)
|
||||
local rndGen=P.seqRND
|
||||
his=function(rndGen,seq0)
|
||||
local len=#seq0
|
||||
local hisLen=math.ceil(len*.5)
|
||||
local history=TABLE.new(0,hisLen)
|
||||
while true do
|
||||
while #P.nextQueue<10 do
|
||||
local r
|
||||
for _=1,hisLen do-- Reroll up to [hisLen] times
|
||||
r=rndGen:random(len)
|
||||
local rollAgain
|
||||
for i=1,hisLen do
|
||||
if r==history[i] then
|
||||
rollAgain=true
|
||||
break-- goto CONTINUE_rollAgain
|
||||
end
|
||||
local r
|
||||
for _=1,hisLen do-- Reroll up to [hisLen] times
|
||||
r=rndGen:random(len)
|
||||
local rollAgain
|
||||
for i=1,hisLen do
|
||||
if r==history[i] then
|
||||
rollAgain=true
|
||||
break-- goto CONTINUE_rollAgain
|
||||
end
|
||||
if not rollAgain then break end
|
||||
-- ::CONTINUE_rollAgain::
|
||||
end
|
||||
if history[1]~=0 then
|
||||
P:getNext(seq0[r])
|
||||
end
|
||||
rem(history,1)
|
||||
ins(history,r)
|
||||
if not rollAgain then break end
|
||||
-- ::CONTINUE_rollAgain::
|
||||
end
|
||||
yield()
|
||||
if history[1]~=0 then
|
||||
yield(seq0[r])
|
||||
end
|
||||
rem(history,1)
|
||||
ins(history,r)
|
||||
end
|
||||
end,
|
||||
hisPool=function(P,seq0)
|
||||
local rndGen=P.seqRND
|
||||
hisPool=function(rndGen,seq0)
|
||||
local len=#seq0
|
||||
local hisLen=math.ceil(len*.5)
|
||||
local history=TABLE.new(0,hisLen)-- Indexes of mino-index
|
||||
@@ -126,151 +113,116 @@ local seqGenerators={
|
||||
end
|
||||
|
||||
while true do
|
||||
while #P.nextQueue<10 do
|
||||
-- print"======================"
|
||||
-- Pick a mino from pool
|
||||
local tryTime=0
|
||||
local r
|
||||
repeat-- ::REPEAT_pickAgain::
|
||||
local pickAgain
|
||||
r=_poolPick()-- Random mino-index in pool
|
||||
for i=1,len do
|
||||
if r==history[i] then
|
||||
tryTime=tryTime+1
|
||||
if tryTime<hisLen then
|
||||
pickAgain=true
|
||||
break-- goto REPEAT_pickAgain
|
||||
end
|
||||
-- print"======================"
|
||||
-- Pick a mino from pool
|
||||
local tryTime=0
|
||||
local r
|
||||
repeat-- ::REPEAT_pickAgain::
|
||||
local pickAgain
|
||||
r=_poolPick()-- Random mino-index in pool
|
||||
for i=1,len do
|
||||
if r==history[i] then
|
||||
tryTime=tryTime+1
|
||||
if tryTime<hisLen then
|
||||
pickAgain=true
|
||||
break-- goto REPEAT_pickAgain
|
||||
end
|
||||
end
|
||||
if not pickAgain then break end
|
||||
until true
|
||||
|
||||
-- Give mino to player & update history
|
||||
if history[1]~=0 then
|
||||
P:getNext(seq0[r])
|
||||
end
|
||||
rem(history,1)
|
||||
ins(history,r)
|
||||
-- print("Player GET: "..r)
|
||||
-- print("History: "..table.concat(history,","))
|
||||
-- local L=TABLE.new("",len)
|
||||
-- for _,v in next,pool do L[v]=L[v].."+" end
|
||||
-- for i=1,#L do print(i,droughtTimes[i],L[i]) end
|
||||
if not pickAgain then break end
|
||||
until true
|
||||
|
||||
-- Give mino to player & update history
|
||||
if history[1]~=0 then
|
||||
yield(seq0[r])
|
||||
end
|
||||
yield()
|
||||
rem(history,1)
|
||||
ins(history,r)
|
||||
-- print("Player GET: "..r)
|
||||
-- print("History: "..table.concat(history,","))
|
||||
-- local L=TABLE.new("",len)
|
||||
-- for _,v in next,pool do L[v]=L[v].."+" end
|
||||
-- for i=1,#L do print(i,droughtTimes[i],L[i]) end
|
||||
end
|
||||
end,
|
||||
c2=function(P,seq0)
|
||||
local rndGen=P.seqRND
|
||||
c2=function(rndGen,seq0)
|
||||
local len=#seq0
|
||||
local weight=TABLE.new(0,len)
|
||||
|
||||
while true do
|
||||
while #P.nextQueue<10 do
|
||||
local maxK=1
|
||||
for i=1,len do
|
||||
weight[i]=weight[i]*.5+rndGen:random()
|
||||
if weight[i]>weight[maxK] then
|
||||
maxK=i
|
||||
end
|
||||
local maxK=1
|
||||
for i=1,len do
|
||||
weight[i]=weight[i]*.5+rndGen:random()
|
||||
if weight[i]>weight[maxK] then
|
||||
maxK=i
|
||||
end
|
||||
weight[maxK]=weight[maxK]/3.5
|
||||
P:getNext(seq0[maxK])
|
||||
end
|
||||
yield()
|
||||
weight[maxK]=weight[maxK]/3.5
|
||||
yield(seq0[maxK])
|
||||
end
|
||||
end,
|
||||
rnd=function(P,seq0)
|
||||
rnd=function(rndGen,seq0)
|
||||
if #seq0==1 then
|
||||
local i=seq0[1]
|
||||
while true do
|
||||
while #P.nextQueue<10 do P:getNext(i) end
|
||||
yield()
|
||||
yield(i)
|
||||
end
|
||||
else
|
||||
local rndGen=P.seqRND
|
||||
local len=#seq0
|
||||
local last=0
|
||||
while true do
|
||||
while #P.nextQueue<10 do
|
||||
local r=rndGen:random(len-1)
|
||||
if r>=last then
|
||||
r=r+1
|
||||
end
|
||||
P:getNext(seq0[r])
|
||||
last=r
|
||||
local r=rndGen:random(len-1)
|
||||
if r>=last then
|
||||
r=r+1
|
||||
end
|
||||
yield()
|
||||
yield(seq0[r])
|
||||
last=r
|
||||
end
|
||||
end
|
||||
end,
|
||||
mess=function(P,seq0)
|
||||
local rndGen=P.seqRND
|
||||
mess=function(rndGen,seq0)
|
||||
while true do
|
||||
while #P.nextQueue<10 do
|
||||
P:getNext(seq0[rndGen:random(#seq0)])
|
||||
end
|
||||
yield()
|
||||
yield(seq0[rndGen:random(#seq0)])
|
||||
end
|
||||
end,
|
||||
reverb=function(P,seq0)
|
||||
local rndGen=P.seqRND
|
||||
reverb=function(rndGen,seq0)
|
||||
local bufferSeq,bag={},{}
|
||||
while true do
|
||||
while #P.nextQueue<10 do
|
||||
if #bag==0 then
|
||||
for i=1,#seq0 do bufferSeq[i]=seq0[i] end
|
||||
if #bag==0 then
|
||||
for i=1,#seq0 do bufferSeq[i]=seq0[i] end
|
||||
repeat
|
||||
local r=rem(bufferSeq,rndGen:random(#bag))
|
||||
local p=1
|
||||
repeat
|
||||
local r=rem(bufferSeq,rndGen:random(#bag))
|
||||
local p=1
|
||||
repeat
|
||||
ins(bag,r)
|
||||
p=p-.15-rndGen:random()
|
||||
until p<0
|
||||
until #bufferSeq==0
|
||||
for i=1,#bag do
|
||||
bufferSeq[i]=bag[i]
|
||||
end
|
||||
ins(bag,r)
|
||||
p=p-.15-rndGen:random()
|
||||
until p<0
|
||||
until #bufferSeq==0
|
||||
for i=1,#bag do
|
||||
bufferSeq[i]=bag[i]
|
||||
end
|
||||
P:getNext(rem(bag,rndGen:random(#bag)))
|
||||
end
|
||||
yield()
|
||||
yield(rem(bag,rndGen:random(#bag)))
|
||||
end
|
||||
end,
|
||||
loop=function(P,seq0)
|
||||
loop=function(rndGen,seq0)
|
||||
local len=#seq0
|
||||
local bag={}
|
||||
while true do
|
||||
while #P.nextQueue<10 do
|
||||
if #bag==0 then
|
||||
for i=1,len do
|
||||
bag[i]=seq0[len-i+1]
|
||||
end
|
||||
if #bag==0 then
|
||||
for i=1,len do
|
||||
bag[i]=seq0[len-i+1]
|
||||
end
|
||||
P:getNext(rem(bag))
|
||||
end
|
||||
yield()
|
||||
yield(rem(bag))
|
||||
end
|
||||
end,
|
||||
fixed=function(P,seq0)
|
||||
local seq={}
|
||||
fixed=function(rndGen,seq0)
|
||||
for i=#seq0,1,-1 do
|
||||
ins(seq,seq0[i])
|
||||
end
|
||||
while true do
|
||||
while #P.nextQueue<10 do
|
||||
if seq[1] then
|
||||
P:getNext(rem(seq))
|
||||
else
|
||||
break
|
||||
end
|
||||
end
|
||||
yield()
|
||||
yield(seq0[i])
|
||||
end
|
||||
end,
|
||||
bagP1inf=function(P,seq0)
|
||||
local rndGen=P.seqRND
|
||||
bagP1inf=function(rndGen,seq0)
|
||||
local len=#seq0
|
||||
local function new()
|
||||
local res={}
|
||||
@@ -331,24 +283,20 @@ local seqGenerators={
|
||||
end
|
||||
local dist=new()
|
||||
while true do
|
||||
while #P.nextQueue<10 do
|
||||
local sum,mydist=dist.next_dist()
|
||||
local r=rndGen:random(sum)
|
||||
for i=1,len do
|
||||
r=r-mydist[i]
|
||||
if r<=0 then
|
||||
P:getNext(seq0[i])
|
||||
dist.update(i)
|
||||
break
|
||||
end
|
||||
local sum,mydist=dist.next_dist()
|
||||
local r=rndGen:random(sum)
|
||||
for i=1,len do
|
||||
r=r-mydist[i]
|
||||
if r<=0 then
|
||||
yield(seq0[i])
|
||||
dist.update(i)
|
||||
break
|
||||
end
|
||||
end
|
||||
yield()
|
||||
end
|
||||
end,
|
||||
}
|
||||
return function(P)-- Return a piece-generating function for player P
|
||||
local s=P.gameEnv.sequence
|
||||
return function(s)-- Return a piece-generating function for player P
|
||||
if type(s)=='function' then
|
||||
return s
|
||||
elseif type(s)=='string' and seqGenerators[s] then
|
||||
@@ -359,7 +307,6 @@ return function(P)-- Return a piece-generating function for player P
|
||||
"No sequence mode called "..s or
|
||||
"Wrong sequence generator"
|
||||
)
|
||||
P.gameEnv.sequence='bag'
|
||||
return seqGenerators.bag
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user