嘿,我正在尝试制作一个国际象棋引擎,但是当我运行它运行良好的代码时,问题是有时它没有设置最佳移动并且它显示错误,因为搜索没有返回一个移动来玩。我的 negamax 包括 AB pruning、MD Pruning、QSearch、ID 和 TT 表。这是我的实现。
Entry=namedtuple('Entry', 'score depth flag')
class Search():
def __init__(self):
self.nodes=0
self.tt_score={}
def search(self,position,api):
self.nodes=0
for depth in range(1,1000):
ret=self.negamax(position,api,-INFINITY,INFINITY,depth,ply=1)
yield ret
def negamax(self,position,api,alpha,beta,depth=3,ply=1):
best,bmove=-INFINITY,()
for move in position.moves():
score=self.negasearch(position.move(move),-beta,-alpha,depth-1,ply+1)
if score>=beta: return [move,score,self.nodes]
if score>best:
best,bmove=score,move
#api.arrow("clear")
#api.arrow(coordinates[move[0]]+coordinates[move[1]])
if score>alpha: alpha=score
return [bmove,best,self.nodes]
def negasearch(self,position,alpha,beta,depth,ply):
best,aorig=-INFINITY,alpha
self.nodes+=1
if MATE-ply<beta:
beta=MATE-ply
if alpha>=MATE-ply: return MATE-ply
if -MATE+ply>alpha:
alpha=-MATE+ply
if beta<=-MATE+ply: return -MATE+ply
entry=self.tt_score.get(position.hash(),Entry(0,-1,'exact'))
if entry.depth>=depth:
if entry.flag=='exact': return entry.score
elif entry.flag=='lower': alpha=max(alpha,entry.score)
elif entry.flag=='upper': beta=min(beta,entry.score)
if alpha>=beta: return entry.score
if depth<=0: return self.qsearch(position,alpha,beta,ply+1)
for move in position.moves():
score=self.negasearch(position.move(move),-beta,-alpha,depth-1,ply+1)
if score>=beta:
best=score
break
if score>best:
best=score
if score>alpha: alpha=score
if best<=aorig: self.tt_score[position.hash()]=Entry(best,depth,'upper')
elif best>=beta: self.tt_score[position.hash()]=Entry(best,depth,'lower')
else: self.tt_score[position.hash()]=Entry(best,depth,'exact')
return best
def qsearch(self,position,alpha,beta,ply):
stand_pat=position.score
if stand_pat>=beta: return beta
if alpha<stand_pat: alpha=stand_pat
self.nodes+=1
for move in position.moves():
if move[2]==0: continue
score=self.qsearch(position.move(move),-beta,-alpha,ply+1)
if score>=beta: return beta
if score>alpha: alpha=score
return alpha
您可能已经注意到我并没有按应有的方式否定每回合的得分。原因是因为当您调用 move 函数时,它会返回分数已经被否定的位置。例如,
def move(self,move):
# copy the current position board, turn, and score
# if move is a capture then preform:
# score+=pvs[pieceBeingCaptured]
# preform move
# if the next player is mated after this move then set score to MATE
return Position(board,-score,self.turn*-1)
它不是移动生成,因为它返回每个位置状态的正确移动。最佳值是 -INFINITY 和 negamax,它应该始终设置最佳移动。任何帮助都会有所帮助。