序列生成器改用协程实现,整理代码

This commit is contained in:
MrZ626
2021-03-15 20:42:03 +08:00
parent 7fd8a23f55
commit 459bd9ad31
10 changed files with 206 additions and 213 deletions

View File

@@ -52,9 +52,8 @@
highCam:是否开启超屏视野 highCam:是否开启超屏视野
nextPos:是否开启生成预览 nextPos:是否开启生成预览
sequence:序列模式,可以使用默认的几个函数用字符串表示也可以自己写 sequence=序列模式,是放一块后对next序列的刷新函数可以使用默认的几个函数用字符串表示也可以自己写一个,注意:使用协程技术
freshMethod=放一块后对next序列的刷新函数不使用默认sequence的话就要自己写 seqData:序列模式使用的"包"数据(本质是生成序列用的数据,会作为参数传进序列生成函数,不一定是包)
bag:一包的方块(本质是基准序列,不一定是包)
mission:包含任务的table,说明暂时略 mission:包含任务的table,说明暂时略
life:生命数, life:生命数,

View File

@@ -1,6 +1,6 @@
local int,ceil,min,abs,rnd,modf=math.floor,math.ceil,math.min,math.abs,math.random,math.modf local int,ceil,min,abs,rnd,modf=math.floor,math.ceil,math.min,math.abs,math.random,math.modf
local ins,rem=table.insert,table.remove local ins,rem=table.insert,table.remove
local YIELD=YIELD local resume,yield=coroutine.resume,coroutine.yield
-- controlname: -- controlname:
-- 1~5:mL,mR,rR,rL,rF, -- 1~5:mL,mR,rR,rL,rF,
-- 6~10:hD,sD,H,A,R, -- 6~10:hD,sD,H,A,R,
@@ -75,7 +75,7 @@ if _CC then
P.cur=rem(P.nextQueue,1) P.cur=rem(P.nextQueue,1)
P.curX,P.curY=blockPos[P.cur.id],int(P.gameEnv.fieldH+1-modf(P.cur.sc[1]))+ceil(P.fieldBeneath/30) P.curX,P.curY=blockPos[P.cur.id],int(P.gameEnv.fieldH+1-modf(P.cur.sc[1]))+ceil(P.fieldBeneath/30)
P:newNext() assert(resume(P.newNext))
local id=CCblockID[P.nextQueue[P.AIdata.next].id] local id=CCblockID[P.nextQueue[P.AIdata.next].id]
if id then if id then
CC.addNext(P.AI_bot,id) CC.addNext(P.AI_bot,id)
@@ -201,7 +201,7 @@ return{
["9S"]=function(P,keys) ["9S"]=function(P,keys)
while true do while true do
--Thinking --Thinking
YIELD() yield()
local Tfield={}--Test field local Tfield={}--Test field
local best={x=1,dir=0,hold=false,score=-1e99}--Best method local best={x=1,dir=0,hold=false,score=-1e99}--Best method
local field_org=P.field local field_org=P.field
@@ -268,7 +268,7 @@ return{
ins(keys,6) ins(keys,6)
--Check if time to change target --Check if time to change target
YIELD() yield()
if P:RND()<.00126 then if P:RND()<.00126 then
P:changeAtkMode(rnd()<.85 and 1 or #P.atker>3 and 4 or rnd()<.3 and 2 or 3) P:changeAtkMode(rnd()<.85 and 1 or #P.atker>3 and 4 or rnd()<.3 and 2 or 3)
end end
@@ -277,13 +277,13 @@ return{
["CC"]=CC and function(P,keys) ["CC"]=CC and function(P,keys)
while true do while true do
--Start thinking --Start thinking
YIELD() yield()
if not pcall(CC.think,P.AI_bot)then break end if not pcall(CC.think,P.AI_bot)then break end
--Poll keys --Poll keys
local success,result,dest,hold,move local success,result,dest,hold,move
repeat repeat
YIELD() yield()
success,result,dest,hold,move=pcall(CC.getMove,P.AI_bot) success,result,dest,hold,move=pcall(CC.getMove,P.AI_bot)
until not success or result==0 or result==2 until not success or result==0 or result==2
if not success then break end if not success then break end
@@ -308,7 +308,7 @@ return{
end end
--Check if time to change target --Check if time to change target
YIELD() yield()
if P:RND()<.00126 then if P:RND()<.00126 then
P:changeAtkMode(rnd()<.85 and 1 or #P.atker>3 and 4 or rnd()<.3 and 2 or 3) P:changeAtkMode(rnd()<.85 and 1 or #P.atker>3 and 4 or rnd()<.3 and 2 or 3)
end end

View File

@@ -583,9 +583,9 @@ function applyCustomGame()--Apply CUSTOMENV, BAG, MISSION
GAME.modeEnv[k]=v GAME.modeEnv[k]=v
end end
if BAG[1]then if BAG[1]then
GAME.modeEnv.bag=BAG GAME.modeEnv.seqData=BAG
else else
GAME.modeEnv.bag=nil GAME.modeEnv.seqData=nil
end end
if MISSION[1]then if MISSION[1]then
GAME.modeEnv.mission=MISSION GAME.modeEnv.mission=MISSION

View File

@@ -5,90 +5,91 @@ return{
drop=20,lock=60, drop=20,lock=60,
sequence=function(P) sequence=function(P)
for _=1,3 do P:getNext(7)end for _=1,3 do P:getNext(7)end
end, while true do
freshMethod=function(P) YIELD()
if not P.nextQueue[1] then if not P.nextQueue[1] then
local height=FREEROW.get(0) local height=FREEROW.get(0)
local max=#P.field local max=#P.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 P.field[h][x]==0 and h>1 do
h=h-1 h=h-1
end
height[x]=h
end
else
for x=1,10 do
height[x]=0
end end
height[x]=h
end end
else height[11]=999
for x=1,10 do
height[x]=0
end
end
height[11]=999
local res={1,1,2,2,3,4} local res={1,1,2,2,3,4}
local d=0 local d=0
local A local A
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 if d<40 or P.stat.row>2*42 then
A=#res+1 A=#res+1
for _=1,4 do for _=1,4 do
res[A]=1 res[A]=1
res[A+1]=2 res[A+1]=2
res[A+2]=6
A=A+3
end
goto END
end
--Give I when no hole
d=-999--Height difference
--A=hole mark
for x=2,11 do
local _=height[x]-height[x-1]
if d<-2 and _>2 then
A=true
end
d=_
end
if not A then
A=#res+1
res[A]=7
res[A+1]=7
res[A+2]=7
end
--Give O when no d=0/give T when no d=1
d=0--d=0 count
A=0--d=1 count
for x=2,10 do
local _=height[x]-height[x-1]
if _==0 then
d=d+1
elseif _==1 or _==-1 then
A=A+1
end
end
if d<3 then
A=#res+1
res[A]=6
res[A+1]=6
res[A+2]=6 res[A+2]=6
A=A+3
end end
goto END if A<3 then
end A=#res+1
res[A]=5
--Give I when no hole res[A+1]=5
d=-999--Height difference res[A+2]=5
--A=hole mark res[A+3]=5
for x=2,11 do res[A+4]=5
local _=height[x]-height[x-1]
if d<-2 and _>2 then
A=true
end end
d=_
end
if not A then
A=#res+1
res[A]=7
res[A+1]=7
res[A+2]=7
end
--Give O when no d=0/give T when no d=1 ::END::
d=0--d=0 count FREEROW.discard(height)
A=0--d=1 count P:getNext(res[P:RND(#res)])
for x=2,10 do
local _=height[x]-height[x-1]
if _==0 then
d=d+1
elseif _==1 or _==-1 then
A=A+1
end
end end
if d<3 then
A=#res+1
res[A]=6
res[A+1]=6
res[A+2]=6
end
if A<3 then
A=#res+1
res[A]=5
res[A+1]=5
res[A+2]=5
res[A+3]=5
res[A+4]=5
end
::END::
FREEROW.discard(height)
P:getNext(res[P:RND(#res)])
end end
end, end,
target=100,dropPiece=PLY.check_lineReach, target=100,dropPiece=PLY.check_lineReach,

View File

@@ -4,7 +4,7 @@ return{
env={ env={
drop=20,lock=60, drop=20,lock=60,
sequence="bag", sequence="bag",
bag={1,1,2,2,3,3,4,4,5,5,6,6}, seqData={1,1,2,2,3,3,4,4,5,5,6,6},
target=100,dropPiece=PLY.check_lineReach, target=100,dropPiece=PLY.check_lineReach,
nextCount=3, nextCount=3,
ospin=false, ospin=false,

View File

@@ -2,7 +2,7 @@ return{
color=COLOR.green, color=COLOR.green,
env={ env={
drop=60,lock=60, drop=60,lock=60,
sequence="bag",bag={8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25}, sequence="bag",seqData={8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25},
target=40,dropPiece=PLY.check_lineReach, target=40,dropPiece=PLY.check_lineReach,
bg="aura",bgm="waterfall", bg="aura",bgm="waterfall",
}, },

View File

@@ -37,8 +37,7 @@ return{
ospin=true,deepDrop=false, ospin=true,deepDrop=false,
RS="TRS", RS="TRS",
sequence="bag", sequence="bag",
freshMethod=NULL, seqData={1,2,3,4,5,6,7},
bag={1,2,3,4,5,6,7},
face=NULL,skin=NULL, face=NULL,skin=NULL,
mission=NULL, mission=NULL,

View File

@@ -142,7 +142,6 @@ local function newEmptyPlayer(id,mini)
P.holdQueue={} P.holdQueue={}
P.holdTime=0 P.holdTime=0
P.nextQueue={} P.nextQueue={}
P.seqData={}
P.freshTime=0 P.freshTime=0
P.spinLast=false P.spinLast=false
@@ -296,10 +295,11 @@ local function applyGameEnv(P)--Finish gameEnv processing
if ENV.sequence~="bag"and ENV.sequence~="loop"then if ENV.sequence~="bag"and ENV.sequence~="loop"then
ENV.bagLine=false ENV.bagLine=false
else else
ENV.bagLen=#ENV.bag ENV.bagLen=#ENV.seqData
end end
if ENV.nextCount==0 then ENV.nextPos=false end if ENV.nextCount==0 then ENV.nextPos=false end
prepareSequence(P)
if P.mini then if P.mini then
ENV.lockFX=false ENV.lockFX=false
@@ -355,7 +355,6 @@ function PLY.newDemoPlayer(id)
GAME.modeEnv=DemoEnv GAME.modeEnv=DemoEnv
loadGameEnv(P) loadGameEnv(P)
applyGameEnv(P) applyGameEnv(P)
prepareSequence(P)
P:loadAI{ P:loadAI{
type="CC", type="CC",
next=5, next=5,
@@ -385,7 +384,6 @@ function PLY.newRemotePlayer(id,mini,playerData)
loadRemoteEnv(P,playerData.conf) loadRemoteEnv(P,playerData.conf)
applyGameEnv(P) applyGameEnv(P)
prepareSequence(P)
end end
function PLY.newAIPlayer(id,AIdata,mini) function PLY.newAIPlayer(id,AIdata,mini)
@@ -397,7 +395,6 @@ function PLY.newAIPlayer(id,AIdata,mini)
ENV.face={0,0,0,0,0,0,0} ENV.face={0,0,0,0,0,0,0}
ENV.skin={1,7,11,3,14,4,9} ENV.skin={1,7,11,3,14,4,9}
applyGameEnv(P) applyGameEnv(P)
prepareSequence(P)
P:loadAI(AIdata) P:loadAI(AIdata)
end end
function PLY.newPlayer(id,mini) function PLY.newPlayer(id,mini)
@@ -407,7 +404,6 @@ function PLY.newPlayer(id,mini)
loadGameEnv(P) loadGameEnv(P)
applyGameEnv(P) applyGameEnv(P)
prepareSequence(P)
end end
--------------------------</Public>-------------------------- --------------------------</Public>--------------------------
return PLY return PLY

View File

@@ -1,13 +1,13 @@
------------------------------------------------------ ------------------------------------------------------
--Notice: anything in this file or in any other file, --Notice: anything in this file or in any other file,
--var P stands for Player object. Don't forget that. --local var P stands for Player object. Don't forget it.
------------------------------------------------------ ------------------------------------------------------
local Player={}--Player class local Player={}--Player class
local int,ceil,rnd=math.floor,math.ceil,math.random local int,ceil,rnd=math.floor,math.ceil,math.random
local max,min,modf=math.max,math.min,math.modf local max,min,modf=math.max,math.min,math.modf
local ins,rem=table.insert,table.remove local ins,rem=table.insert,table.remove
local YIELD=YIELD local resume,yield=coroutine.resume,coroutine.yield
local kickList=require"parts.kickList" local kickList=require"parts.kickList"
@@ -147,7 +147,7 @@ end
local function task_movePosition(P,x,y,size) local function task_movePosition(P,x,y,size)
local x1,y1,size1=P.x,P.y,P.size local x1,y1,size1=P.x,P.y,P.size
while true do while true do
YIELD() yield()
if (x1-x)^2+(y1-y)^2<1 then if (x1-x)^2+(y1-y)^2<1 then
P:setPosition(x,y,size) P:setPosition(x,y,size)
return true return true
@@ -750,7 +750,7 @@ function Player.popNext(P,ifhold)--Pop nextQueue to hand
P.ctrlCount=0 P.ctrlCount=0
P.cur=rem(P.nextQueue,1) P.cur=rem(P.nextQueue,1)
P:newNext() assert(resume(P.newNext))
if P.cur then if P.cur then
P.pieceCount=P.pieceCount+1 P.pieceCount=P.pieceCount+1
if P.AI_mode=="CC"then if P.AI_mode=="CC"then
@@ -1516,7 +1516,7 @@ end
--------------------------<Ticks>-------------------------- --------------------------<Ticks>--------------------------
local function tick_throwBadge(ifAI,sender,time) local function tick_throwBadge(ifAI,sender,time)
while true do while true do
YIELD() yield()
time=time-1 time=time-1
if time%4==0 then if time%4==0 then
local S,R=sender,sender.lastRecv local S,R=sender,sender.lastRecv
@@ -1544,7 +1544,7 @@ local function tick_throwBadge(ifAI,sender,time)
end end
local function tick_finish(P) local function tick_finish(P)
while true do while true do
YIELD() yield()
P.endCounter=P.endCounter+1 P.endCounter=P.endCounter+1
if P.endCounter<40 then if P.endCounter<40 then
--Make field visible --Make field visible
@@ -1558,7 +1558,7 @@ local function tick_finish(P)
end end
local function tick_lose(P) local function tick_lose(P)
while true do while true do
YIELD() yield()
P.endCounter=P.endCounter+1 P.endCounter=P.endCounter+1
if P.endCounter<40 then if P.endCounter<40 then
--Make field visible --Make field visible
@@ -1591,7 +1591,7 @@ end
function tick_autoPause() function tick_autoPause()
local time=0 local time=0
while true do while true do
YIELD() yield()
time=time+1 time=time+1
if SCN.cur~="play"or GAME.frame<180 then if SCN.cur~="play"or GAME.frame<180 then
return return

View File

@@ -1,132 +1,130 @@
local rnd=math.random local rnd=math.random
local ins,rem=table.insert,table.remove local ins,rem=table.insert,table.remove
local yield=coroutine.yield
local freshMethod local sequenceModes={
local freshPrepare={ none=function() while true do yield()end end,
rnd=function(P) bag=function(P,seq0)
local bag=P.gameEnv.bag local len=#seq0
P:getNext(bag[rnd(#bag)]) local bag={}
freshMethod.rnd(P) while true do
end, while #P.nextQueue<6 do
fixed=function(P) if #bag==0 then
local bag=P.gameEnv.bag for i=1,len do
local L=#bag bag[i]=seq0[len-i+1]
for i=1,L do end
P.seqData[i]=bag[L+1-i] end
end P:getNext(rem(bag,rnd(#bag)))
while #P.nextQueue<6 do
if P.seqData[1]then
P:getNext(rem(P.seqData))
else
break
end end
yield()
end end
end, end,
} his4=function(P,seq0)
freshMethod={ local len=#seq0
none=NULL, while true do
bag=function(P) while #P.nextQueue<6 do
local bag=P.seqData for n=1,4 do
while #P.nextQueue<6 do local j,i=0
if #bag==0 then--Copy a new bag
local bag0=P.gameEnv.bag
for i=1,#bag0 do bag[i]=bag0[i]end
end
P:getNext(rem(bag,P:RND(#bag)))
end
end,
his4=function(P)
while #P.nextQueue<6 do
local bag=P.gameEnv.bag
local L=#bag
for n=1,4 do
local j,i=0
repeat
i=bag[P:RND(L)]
j=j+1
until i~=P.seqData[1]and i~=P.seqData[2]and i~=P.seqData[3]and i~=P.seqData[4]or j==4
P.seqData[n]=i
P:getNext(i)
end
end
end,
rnd=function(P)
while #P.nextQueue<6 do
local bag=P.gameEnv.bag
local L=#bag
for i=1,4 do
local count=0
repeat
i=bag[P:RND(L)]
count=count+1
until i~=P.nextQueue[#P.nextQueue].id or count>=L
P:getNext(i)
end
end
end,
reverb=function(P)
local seq=P.seqData
while #P.nextQueue<6 do
if #seq==0 then
local bag0=P.gameEnv.bag
for i=1,#bag0 do seq[i]=bag0[i]end
local bag={}
repeat
local r=rem(seq,P:RND(#bag))
local p=1
repeat repeat
ins(bag,r) i=seq0[P:RND(len)]
p=p-.15-P:RND() j=j+1
until p<0 until i~=seq0[1]and i~=seq0[2]and i~=seq0[3]and i~=seq0[4]or j==4
until #seq==0 seq0[n]=i
for i=1,#bag do P:getNext(i)
seq[i]=bag[i]
end end
end end
P:getNext(rem(seq)) yield()
end end
end, end,
loop=function(P) rnd=function(P,seq0)
while #P.nextQueue<6 do P:getNext(seq0[rnd(#seq0)])
if #P.seqData==0 then while true do
local bag=P.gameEnv.bag while #P.nextQueue<6 do
local L=#bag local len=#seq0
for i=1,L do for i=1,4 do
P.seqData[i]=bag[L+1-i] local count=0
repeat
i=seq0[P:RND(len)]
count=count+1
until i~=P.nextQueue[#P.nextQueue].id or count>=len
P:getNext(i)
end end
end end
P:getNext(rem(P.seqData)) yield()
end end
end, end,
fixed=function(P) reverb=function(P,seq0)
while #P.nextQueue<6 do local bufferSeq,bag={},{}
if P.seqData[1]then while true do
P:getNext(rem(P.seqData)) while #P.nextQueue<6 do
else if #bag==0 then
if not(P.cur or P.holdQueue[1])then P:lose(true)end for i=1,#seq0 do bufferSeq[i]=seq0[i]end
return repeat
local r=rem(bufferSeq,P:RND(#bag))
local p=1
repeat
ins(bag,r)
p=p-.15-P:RND()
until p<0
until #bufferSeq==0
for i=1,#bag do
bufferSeq[i]=bag[i]
end
end
P:getNext(rem(bag,rnd(#bag)))
end end
yield()
end
end,
loop=function(P,seq0)
local len=#seq0
local bag={}
while true do
while #P.nextQueue<6 do
if #bag==0 then
for i=1,len do
bag[i]=seq0[len-i+1]
end
end
P:getNext(rem(bag))
end
yield()
end
end,
fixed=function(P,seq0)
local seq={}
for i=#seq0,1,-1 do
ins(seq,seq0[i])
end
while true do
while #P.nextQueue<6 do
if not(seq[1]or P.cur or P.holdQueue[1])then
P:lose(true)
break
end
P:getNext(rem(seq))
end
yield()
end end
end, end,
} }
local function prepareSequence(P)--Call freshPrepare and set newNext return function(P)--Set newNext funtion for player P
local ENV=P.gameEnv local ENV=P.gameEnv
::tryAgain::
if type(ENV.sequence)=="string"then if type(ENV.sequence)=="string"then
P.newNext=freshMethod[ENV.sequence] if sequenceModes[ENV.sequence]then
if freshPrepare[ENV.sequence]then P.newNext=coroutine.create(sequenceModes[ENV.sequence])
freshPrepare[ENV.sequence](P)
else else
P:newNext() LOG.print("No sequence mode called "..ENV.sequence,"warn")
end
else
if type(ENV.freshMethod)=="function"then
if ENV.sequence then ENV.sequence(P)end
P.newNext=ENV.freshMethod
else
LOG.print("Wrong sequence generator code","warn")
ENV.sequence="bag" ENV.sequence="bag"
prepareSequence(P) goto tryAgain
end end
elseif type(ENV.sequence)=="function"then
P.newNext=coroutine.create(ENV.sequence)
else
LOG.print("Wrong sequence generator","warn")
ENV.sequence="bag"
goto tryAgain
end end
end assert(coroutine.resume(P.newNext,P,ENV.seqData))
return prepareSequence end