ai协程化

This commit is contained in:
MrZ626
2021-03-05 15:28:43 +08:00
parent 640403866f
commit 15ecee6767
3 changed files with 66 additions and 71 deletions

View File

@@ -8,6 +8,7 @@
]] ]]
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
-- 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,
@@ -24,23 +25,24 @@ if _CC then
local CCblockID={6,5,4,3,2,1,0} local CCblockID={6,5,4,3,2,1,0}
CC={ CC={
getConf= _CC.get_default_config ,--()options,weights getConf= _CC.get_default_config ,--()options,weights
fastWeights=_CC.fast_weights ,--(weights) fastWeights=_CC.fast_weights ,--(weights)
--setConf= _CC.set_options ,--(options,hold,20g,bag7) --setConf= _CC.set_options ,--(options,hold,20g,bag7)
new= _CC.launch_async ,--(options,weights)bot new= _CC.launch_async ,--(options,weights)bot
addNext= function(bot,id)_CC.add_next_piece_async(bot,CCblockID[id])end ,--(bot,piece) addNext= function(bot,id)_CC.add_next_piece_async(bot,CCblockID[id])end ,--(bot,piece)
update= _CC.reset_async ,--(bot,field,b2b,combo) update= _CC.reset_async ,--(bot,field,b2b,combo)
think= _CC.request_next_move ,--(bot) think= _CC.request_next_move ,--(bot)
getMove= _CC.poll_next_move ,--(bot)success,dest,hold,move getMove= _CC.poll_next_move ,--(bot)success,dest,hold,move
destroy= _CC.destroy_async ,--(bot) destroy= _CC.destroy_async ,--(bot)
setHold= _CC.set_hold ,--(opt,bool) setHold= _CC.set_hold ,--(opt,bool)
set20G= _CC.set_20g ,--(opt,bool) set20G= _CC.set_20g ,--(opt,bool)
-- setPCLoop= _CC.set_pcloop ,--(opt,bool) -- setPCLoop= _CC.set_pcloop ,--(opt,bool)
setBag= _CC.set_bag7 ,--(opt,bool) setBag= _CC.set_bag7 ,--(opt,bool)
setNode= _CC.set_max_nodes ,--(opt,bool) setNode= _CC.set_max_nodes ,--(opt,bool)
free= _CC.free ,--(opt/wei) free= _CC.free ,--(opt/wei)
} }
local CC=CC
function CC.updateField(P) function CC.updateField(P)
local F,i={},1 local F,i={},1
for y=1,#P.field do for y=1,#P.field do
@@ -196,8 +198,10 @@ local function getScore(field,cb,cy)
end end
------------------------------------------------- -------------------------------------------------
return{ return{
["9S"]={ ["9S"]=function(P,keys)
function(P,ctrl) while true do
--Thinking
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
@@ -224,22 +228,18 @@ return{
local cy=#Tfield+1 local cy=#Tfield+1
--Move to bottom --Move to bottom
while true do while cy>1 and not ifoverlapAI(Tfield,cb,cx,cy-1)do
if cy==1 then break end cy=cy-1
if not ifoverlapAI(Tfield,cb,cx,cy-1)then
cy=cy-1
else
break
end
end end
--Simulate lock --Simulate lock
for i=1,#cb do for i=1,#cb do
local y=cy+i-1 local y=cy+i-1
if not Tfield[y]then Tfield[y]=getRow(0)end if not Tfield[y]then Tfield[y]=getRow(0)end
local L=Tfield[y]
for j=1,#cb[1]do for j=1,#cb[1]do
if cb[i][j]then if cb[i][j]then
Tfield[y][cx+j-1]=1 L[cx+j-1]=1
end end
end end
end end
@@ -258,73 +258,67 @@ return{
while #Tfield>0 do while #Tfield>0 do
discardRow(rem(Tfield,1)) discardRow(rem(Tfield,1))
end end
local p=#ctrl+1
if best.hold then if best.hold then
ctrl[p]=8 ins(keys,8)
p=p+1
end end
local l=FCL[best.bn][best.dir+1][best.x] local l=FCL[best.bn][best.dir+1][best.x]
for i=1,#l do for i=1,#l do
ctrl[p]=l[i] ins(keys,l[i])
p=p+1
end end
ctrl[p]=6 ins(keys,6)
return 2
end, --Check if time to change target
function(P) 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
return 1 end
end, end,
}, ["CC"]=CC and function(P,keys)
["CC"]=CC and{ while true do
[0]=function(P) --Start thinking
LOG.print("CC is dead ("..P.id..")","error") YIELD()
end, if not pcall(CC.think,P.AI_bot)then goto ERR end
function(P)--Start thinking
if not pcall(CC.think,P.AI_bot)then --Poll keys
return 0 YIELD()
end while true do
return 2 local success,result,dest,hold,move=pcall(CC.getMove,P.AI_bot)
end, if success then
function(P,ctrl)--Poll keys if result==2 then
local success,result,dest,hold,move=pcall(CC.getMove,P.AI_bot) ins(keys,6)
if success then break
if result==2 then elseif result==0 then
ins(ctrl,6) for i=1,#dest do
return 3 for j=1,#dest[i]do
elseif result==0 then dest[i][j]=dest[i][j]+1
for i=1,#dest do end
for j=1,#dest[i]do
dest[i][j]=dest[i][j]+1
end end
end P.AI_dest=dest
P.AI_dest=dest if hold then keys[1]=8 end--Hold
if hold then ctrl[1]=8 end--Hold while move[1]do
while move[1]do local m=rem(move,1)
local m=rem(move,1) if m<4 then
if m<4 then ins(keys,m+1)
ins(ctrl,m+1) elseif not P.AIdata._20G then
elseif not P.AIdata._20G then ins(keys,13)
ins(ctrl,13) end
end end
ins(keys,6)
break
end end
ins(ctrl,6)
return 3
else else
--Stay this stage goto ERR
return 2
end end
else
return 0
end end
end,
function(P)--Check if time to change target --Check if time to change target
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
return 1 end
end, ::ERR::
}, LOG.print("CC is dead ("..P.id..")","error")
}--AI think stage end,
}--AI brains

View File

@@ -1424,7 +1424,6 @@ do--Player.drop(P)--Place piece
end end
function Player.loadAI(P,data)--Load AI params function Player.loadAI(P,data)--Load AI params
P.AI_mode=data.type P.AI_mode=data.type
P.AI_stage=1
P.AI_keys={} P.AI_keys={}
P.AI_delay=min(int(P.gameEnv.drop*.8),data.delta*rnd()*4) P.AI_delay=min(int(P.gameEnv.drop*.8),data.delta*rnd()*4)
P.AI_delay0=data.delta P.AI_delay0=data.delta
@@ -1462,6 +1461,8 @@ function Player.loadAI(P,data)--Load AI params
else else
P:setRS("TRS") P:setRS("TRS")
end end
P.AI_thread=coroutine.create(AIFUNC[data.type])
coroutine.resume(P.AI_thread,P,P.AI_keys)
end end
--------------------------</Methods>-------------------------- --------------------------</Methods>--------------------------

View File

@@ -145,8 +145,8 @@ function update.alive(P,dt)
local C=P.AI_keys local C=P.AI_keys
P.AI_delay=P.AI_delay-1 P.AI_delay=P.AI_delay-1
if not C[1]then if not C[1]then
if P.AI_stage then if coroutine.status(P.AI_thread)=="suspended"then
P.AI_stage=AIFUNC[P.AI_mode][P.AI_stage](P,C) coroutine.resume(P.AI_thread)
end end
elseif P.AI_delay<=0 then elseif P.AI_delay<=0 then
P:pressKey(C[1])P:releaseKey(C[1]) P:pressKey(C[1])P:releaseKey(C[1])