Skip to content

Commit 02f4ae7

Browse files
committed
整理paperArtist代码
1 parent 7be54cb commit 02f4ae7

File tree

2 files changed

+38
-62
lines changed

2 files changed

+38
-62
lines changed

assets/ai/paperArtist.lua

Lines changed: 34 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -33,80 +33,48 @@ local simulateDrop=require'assets.ai.util'.simulateDrop
3333
local lockPiece=require'assets.ai.util'.lockPiece
3434
local clearLine=require'assets.ai.util'.clearLine
3535
local getBoundCount=paperArtist.getBoundCount
36-
local directions={'0','R','F','L'}
3736

3837
---@param F Mat<boolean> Field (read)
3938
---@param shape Mat<boolean>
40-
---@return number x, number y, string dir
41-
function paperArtist.findPosition(F,shape)
42-
local best={
43-
score=-1e99,
44-
x=4,y=4,dir='0',
45-
}
46-
local w=F[1] and #F[1] or 10
47-
for d=1,4 do
48-
for cx=1,w-#shape[1]+1 do
49-
local F1=TABLE.copy(F,1)
50-
local cy,colH=simulateDrop(F1,shape,cx)
51-
52-
lockPiece(F1,shape,cx,cy)
53-
local clear=clearLine(F1,cy,cy+#shape-1)
54-
local score
55-
if #F1==0 then
56-
-- Nobody can refuse AC
57-
score=1e99
58-
else
59-
local HBC,VBC=getBoundCount(F1)
60-
score=clear*2-HBC*3-VBC*2-cy
61-
end
62-
63-
local minH=math.min(unpack(colH))
64-
for i=1,#colH do
65-
score=score-(colH[i]-minH)*1.26
66-
end
67-
68-
if score>best.score then
69-
best.x,best.y,best.dir=cx,cy,directions[d]
70-
best.score=score
71-
end
72-
end
73-
if d<4 then shape=TABLE.rotate(shape,'R') end
39+
---@param X number
40+
function paperArtist.getSimScore(F,shape,X)
41+
F=TABLE.copy(F,1)
42+
local cy,colH=simulateDrop(F,shape,X)
43+
lockPiece(F,shape,X,cy)
44+
local linesClear=clearLine(F,cy,cy+#shape-1)
45+
local score
46+
if #F==0 then
47+
-- Nobody can refuse AC
48+
score=1e99
49+
else
50+
local HBC,VBC=getBoundCount(F)
51+
local minH=math.min(unpack(colH))
52+
local totalH=MATH.sum(colH)
53+
local shadowCreated=totalH-minH*#colH
54+
score=2*linesClear-cy-shadowCreated*1.26-HBC*3-VBC*2
7455
end
75-
return best.x,best.y,best.dir
56+
return score,cy
7657
end
7758

59+
local rotate=TABLE.rotate
60+
local getSimScore=paperArtist.getSimScore
61+
local directions={'0','R','F','L'}
62+
7863
local floor=math.floor
7964
local ins,rem=table.insert,table.remove
8065

8166
---@param F Mat<boolean> Field (read)
8267
---@param shape Mat<boolean>
8368
---@return {x:number, y:number, dir:string}[]
84-
function paperArtist.findBestPositions(F,shape,counts)
69+
function paperArtist.search(F,shape,dirCount,bestCount)
8570
local posList={{
8671
score=-1e99,
8772
x=4,y=4,dir='0',
8873
}}
8974
local w=F[1] and #F[1] or 10
90-
for d=1,4 do
75+
for d=1,dirCount do
9176
for cx=1,w-#shape[1]+1 do
92-
local F1=TABLE.copy(F,1)
93-
local cy,colH=simulateDrop(F1,shape,cx)
94-
95-
lockPiece(F1,shape,cx,cy)
96-
local clear=clearLine(F1,cy,cy+#shape-1)
97-
local score
98-
if #F1==0 then
99-
-- Nobody can refuse AC
100-
score=1e99
101-
else
102-
local HBC,VBC=getBoundCount(F1)
103-
score=clear*2-HBC*3-VBC*2-cy
104-
end
105-
106-
local minH=math.min(unpack(colH))
107-
for i=1,#colH do
108-
score=score-(colH[i]-minH)*1.26
109-
end
77+
local score,cy=getSimScore(F,shape,cx)
11078

11179
local pos={
11280
score=score,
@@ -122,13 +90,21 @@ function paperArtist.findBestPositions(F,shape,counts)
12290
end
12391
end
12492
ins(posList,i,pos)
125-
if #posList>counts then
93+
if #posList>bestCount then
12694
rem(posList)
12795
end
12896
end
129-
if d<4 then shape=TABLE.rotate(shape,'R') end
97+
if d<4 then shape=rotate(shape,'R') end
13098
end
13199
return posList
132100
end
133101

102+
---@param F Mat<boolean> Field (read)
103+
---@param shape Mat<boolean>
104+
---@return number x, number y, string dir
105+
function paperArtist.getBestPosition(F,shape)
106+
local best=paperArtist.search(F,shape,4,1)[1]
107+
return best.x,best.y,best.dir
108+
end
109+
134110
return paperArtist

assets/ai/util.lua

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ local Util={}
55
---@param field Mat<boolean> Field (read)
66
---@param shape Mat<boolean>
77
---@param X number
8-
---@return number Y, number[] delta
8+
---@return number Y, number[] colH the height of the piece if only check collision with this column
99
function Util.simulateDrop(field,shape,X)
1010
local w=#shape[1]
1111
local shapeBottom,fieldTop={},{}
@@ -18,11 +18,11 @@ function Util.simulateDrop(field,shape,X)
1818
while y>0 and not field[y][X+x-1] do y=y-1 end
1919
fieldTop[x]=y
2020
end
21-
local delta={}
21+
local colH={}
2222
for i=1,w do
23-
delta[i]=fieldTop[i]-shapeBottom[i]
23+
colH[i]=fieldTop[i]-shapeBottom[i]
2424
end
25-
return math.max(unpack(delta))+1,delta
25+
return math.max(unpack(colH))+1,colH
2626
end
2727

2828
---@param field Mat<boolean> Field (write)

0 commit comments

Comments
 (0)