1

嘿,我正在尝试制作一个国际象棋引擎,但是当我运行它运行良好的代码时,问题是有时它没有设置最佳移动并且它显示错误,因为搜索没有返回一个移动来玩。我的 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,它应该始终设置最佳移动。任何帮助都会有所帮助。

4

0 回答 0