ai协程化
This commit is contained in:
130
parts/ai.lua
130
parts/ai.lua
@@ -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
|
||||||
@@ -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>--------------------------
|
||||||
|
|
||||||
|
|||||||
@@ -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])
|
||||||
|
|||||||
Reference in New Issue
Block a user