Merge remote-tracking branch 'tech/imple/revise-seq-generator'

This commit is contained in:
MrZ_26
2023-07-20 15:00:40 +08:00
6 changed files with 193 additions and 232 deletions

View File

@@ -43,8 +43,8 @@ function bot_cc:revive()
self.P:loadAI(self.data) self.P:loadAI(self.data)
end end
function bot_cc:pushNewNext(id) function bot_cc:pushNewNext(id)
self.ccBot:addNext(rem(self.bufferedNexts,1))
ins(self.bufferedNexts,id) ins(self.bufferedNexts,id)
self.ccBot:addNext(rem(self.bufferedNexts,1))
end end
function bot_cc:thread() function bot_cc:thread()
local P,keys=self.P,self.keys local P,keys=self.P,self.keys

View File

@@ -1,19 +1,19 @@
local ins=table.insert local ins=table.insert
local yield=coroutine.yield
return { return {
env={ env={
drop=20,lock=60, drop=20,lock=60,
sequence=function(P) sequence=function(seqRND)
for _=1,3 do P:getNext(7) end local field,stat
for _=1,3 do field,stat=yield(7) end
while true do while true do
coroutine.yield()
if not P.nextQueue[1] then
local height=TABLE.new(0,10) local height=TABLE.new(0,10)
local max=#P.field local max=#field
if max>0 then if max>0 then
-- Get heights -- Get heights
for x=1,10 do for x=1,10 do
local h=max local h=max
while P.field[h][x]==0 and h>1 do while field[h][x]==0 and h>1 do
h=h-1 h=h-1
end end
height[x]=h height[x]=h
@@ -30,7 +30,7 @@ return {
for i=1,10 do for i=1,10 do
d=d+height[i] d=d+height[i]
end end
if d<40 or P.stat.row>2*42 then-- Low field or almost win, give SZO if d<40 or stat.row>2*42 then-- Low field or almost win, give SZO
for _=1,4 do for _=1,4 do
ins(wei,1) ins(wei,1)
ins(wei,2) ins(wei,2)
@@ -68,11 +68,10 @@ return {
for _=1,4 do ins(wei,5) end for _=1,4 do ins(wei,5) end
end end
end end
P:getNext(wei[P.seqRND:random(#wei)]) field,stat=yield(wei[seqRND:random(#wei)])
end
end end
end, end,
nextCount=1,holdCount=0, trueNextCount=1,nextCount=1,holdCount=0,
ospin=false, ospin=false,
freshLimit=15, freshLimit=15,
eventSet='checkLine_100', eventSet='checkLine_100',

View File

@@ -33,7 +33,7 @@ return {
bone=false, bone=false,
lockout=false, lockout=false,
fieldH=20,heightLimit=1e99, fieldH=20,heightLimit=1e99,
nextCount=6,nextStartPos=1, trueNextCount=10,nextCount=6,nextStartPos=1,
holdMode='hold',holdCount=1, holdMode='hold',holdCount=1,
infHold=false,phyHold=false, infHold=false,phyHold=false,
ospin=true,deepDrop=false, ospin=true,deepDrop=false,

View File

@@ -328,17 +328,32 @@ local function _applyGameEnv(P)-- Finish gameEnv processing
ENV.nextPos=false ENV.nextPos=false
end end
P.newNext=coroutine.wrap(getSeqGen(P)) local seqGen=coroutine.create(getSeqGen(ENV.sequence))
P:newNext(P.gameEnv.seqData) local seqCalled=false
if ENV.noInitSZO then local initSZOcount=0
for _=1,5 do function P:newNext()
local C=P.nextQueue[1] local status,piece
if C and (C.id==1 or C.id==2 or C.id==6) then if seqCalled then
table.remove(P.nextQueue,1) status,piece=coroutine.resume(seqGen,P.field,P.stat)
else else
break 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
end end
P:getNext(piece)
elseif not status then
assert(piece=='cannot resume dead coroutine')
end
end
for _=1,ENV.trueNextCount do
P:newNext() P:newNext()
end end

View File

@@ -1436,7 +1436,7 @@ function Player:popNext(ifhold)-- Pop nextQueue to hand
if self.nextQueue[1] then if self.nextQueue[1] then
self.cur=rem(self.nextQueue,1) self.cur=rem(self.nextQueue,1)
self.newNext() self:newNext()
self.pieceCount=self.pieceCount+1 self.pieceCount=self.pieceCount+1
local pressing=self.keyPressing local pressing=self.keyPressing

View File

@@ -2,25 +2,20 @@ local ins,rem=table.insert,table.remove
local yield=coroutine.yield local yield=coroutine.yield
local seqGenerators={ local seqGenerators={
none=function() while true do yield() end end, none=function() end,
bag=function(P,seq0) bag=function(rndGen,seq0)
local rndGen=P.seqRND
local len=#seq0 local len=#seq0
local bag={} local bag={}
while true do while true do
while #P.nextQueue<10 do
if #bag==0 then if #bag==0 then
for i=1,len do for i=1,len do
bag[i]=seq0[len-i+1] bag[i]=seq0[len-i+1]
end end
end end
P:getNext(rem(bag,rndGen:random(#bag))) yield(rem(bag,rndGen:random(#bag)))
end
yield()
end end
end, end,
bagES=function(P,seq0) bagES=function(rndGen,seq0)
local rndGen=P.seqRND
local len=#seq0 local len=#seq0
local bag=TABLE.shift(seq0) local bag=TABLE.shift(seq0)
do-- Get a good first-bag do-- Get a good first-bag
@@ -40,28 +35,23 @@ local seqGenerators={
end end
end end
-- Finish -- Finish
for i=1,len do P:getNext(bag[i]) end for i=1,len do yield(bag[i]) end
end end
bag={} bag={}
while true do while true do
while #P.nextQueue<10 do
if #bag==0 then if #bag==0 then
for i=1,len do for i=1,len do
bag[i]=seq0[len-i+1] bag[i]=seq0[len-i+1]
end end
end end
P:getNext(rem(bag,rndGen:random(#bag))) yield(rem(bag,rndGen:random(#bag)))
end
yield()
end end
end, end,
his=function(P,seq0) his=function(rndGen,seq0)
local rndGen=P.seqRND
local len=#seq0 local len=#seq0
local hisLen=math.ceil(len*.5) local hisLen=math.ceil(len*.5)
local history=TABLE.new(0,hisLen) local history=TABLE.new(0,hisLen)
while true do while true do
while #P.nextQueue<10 do
local r local r
for _=1,hisLen do-- Reroll up to [hisLen] times for _=1,hisLen do-- Reroll up to [hisLen] times
r=rndGen:random(len) r=rndGen:random(len)
@@ -76,16 +66,13 @@ local seqGenerators={
-- ::CONTINUE_rollAgain:: -- ::CONTINUE_rollAgain::
end end
if history[1]~=0 then if history[1]~=0 then
P:getNext(seq0[r]) yield(seq0[r])
end end
rem(history,1) rem(history,1)
ins(history,r) ins(history,r)
end end
yield()
end
end, end,
hisPool=function(P,seq0) hisPool=function(rndGen,seq0)
local rndGen=P.seqRND
local len=#seq0 local len=#seq0
local hisLen=math.ceil(len*.5) local hisLen=math.ceil(len*.5)
local history=TABLE.new(0,hisLen)-- Indexes of mino-index local history=TABLE.new(0,hisLen)-- Indexes of mino-index
@@ -126,7 +113,6 @@ local seqGenerators={
end end
while true do while true do
while #P.nextQueue<10 do
-- print"======================" -- print"======================"
-- Pick a mino from pool -- Pick a mino from pool
local tryTime=0 local tryTime=0
@@ -148,7 +134,7 @@ local seqGenerators={
-- Give mino to player & update history -- Give mino to player & update history
if history[1]~=0 then if history[1]~=0 then
P:getNext(seq0[r]) yield(seq0[r])
end end
rem(history,1) rem(history,1)
ins(history,r) ins(history,r)
@@ -158,16 +144,12 @@ local seqGenerators={
-- for _,v in next,pool do L[v]=L[v].."+" end -- for _,v in next,pool do L[v]=L[v].."+" end
-- for i=1,#L do print(i,droughtTimes[i],L[i]) end -- for i=1,#L do print(i,droughtTimes[i],L[i]) end
end end
yield()
end
end, end,
c2=function(P,seq0) c2=function(rndGen,seq0)
local rndGen=P.seqRND
local len=#seq0 local len=#seq0
local weight=TABLE.new(0,len) local weight=TABLE.new(0,len)
while true do while true do
while #P.nextQueue<10 do
local maxK=1 local maxK=1
for i=1,len do for i=1,len do
weight[i]=weight[i]*.5+rndGen:random() weight[i]=weight[i]*.5+rndGen:random()
@@ -176,49 +158,36 @@ local seqGenerators={
end end
end end
weight[maxK]=weight[maxK]/3.5 weight[maxK]=weight[maxK]/3.5
P:getNext(seq0[maxK]) yield(seq0[maxK])
end
yield()
end end
end, end,
rnd=function(P,seq0) rnd=function(rndGen,seq0)
if #seq0==1 then if #seq0==1 then
local i=seq0[1] local i=seq0[1]
while true do while true do
while #P.nextQueue<10 do P:getNext(i) end yield(i)
yield()
end end
else else
local rndGen=P.seqRND
local len=#seq0 local len=#seq0
local last=0 local last=0
while true do while true do
while #P.nextQueue<10 do
local r=rndGen:random(len-1) local r=rndGen:random(len-1)
if r>=last then if r>=last then
r=r+1 r=r+1
end end
P:getNext(seq0[r]) yield(seq0[r])
last=r last=r
end end
yield()
end
end end
end, end,
mess=function(P,seq0) mess=function(rndGen,seq0)
local rndGen=P.seqRND
while true do while true do
while #P.nextQueue<10 do yield(seq0[rndGen:random(#seq0)])
P:getNext(seq0[rndGen:random(#seq0)])
end
yield()
end end
end, end,
reverb=function(P,seq0) reverb=function(rndGen,seq0)
local rndGen=P.seqRND
local bufferSeq,bag={},{} local bufferSeq,bag={},{}
while true do while true do
while #P.nextQueue<10 do
if #bag==0 then if #bag==0 then
for i=1,#seq0 do bufferSeq[i]=seq0[i] end for i=1,#seq0 do bufferSeq[i]=seq0[i] end
repeat repeat
@@ -233,44 +202,27 @@ local seqGenerators={
bufferSeq[i]=bag[i] bufferSeq[i]=bag[i]
end end
end end
P:getNext(rem(bag,rndGen:random(#bag))) yield(rem(bag,rndGen:random(#bag)))
end
yield()
end end
end, end,
loop=function(P,seq0) loop=function(rndGen,seq0)
local len=#seq0 local len=#seq0
local bag={} local bag={}
while true do while true do
while #P.nextQueue<10 do
if #bag==0 then if #bag==0 then
for i=1,len do for i=1,len do
bag[i]=seq0[len-i+1] bag[i]=seq0[len-i+1]
end end
end end
P:getNext(rem(bag)) yield(rem(bag))
end
yield()
end end
end, end,
fixed=function(P,seq0) fixed=function(rndGen,seq0)
local seq={}
for i=#seq0,1,-1 do for i=#seq0,1,-1 do
ins(seq,seq0[i]) yield(seq0[i])
end
while true do
while #P.nextQueue<10 do
if seq[1] then
P:getNext(rem(seq))
else
break
end
end
yield()
end end
end, end,
bagP1inf=function(P,seq0) bagP1inf=function(rndGen,seq0)
local rndGen=P.seqRND
local len=#seq0 local len=#seq0
local function new() local function new()
local res={} local res={}
@@ -331,24 +283,20 @@ local seqGenerators={
end end
local dist=new() local dist=new()
while true do while true do
while #P.nextQueue<10 do
local sum,mydist=dist.next_dist() local sum,mydist=dist.next_dist()
local r=rndGen:random(sum) local r=rndGen:random(sum)
for i=1,len do for i=1,len do
r=r-mydist[i] r=r-mydist[i]
if r<=0 then if r<=0 then
P:getNext(seq0[i]) yield(seq0[i])
dist.update(i) dist.update(i)
break break
end end
end end
end end
yield()
end
end, end,
} }
return function(P)-- Return a piece-generating function for player P return function(s)-- Return a piece-generating function for player P
local s=P.gameEnv.sequence
if type(s)=='function' then if type(s)=='function' then
return s return s
elseif type(s)=='string' and seqGenerators[s] then 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 "No sequence mode called "..s or
"Wrong sequence generator" "Wrong sequence generator"
) )
P.gameEnv.sequence='bag'
return seqGenerators.bag return seqGenerators.bag
end end
end end