Alpha-Beta 剪枝搜索實現黑白棋AI

完整代碼可以在 我的AI學習筆記 - github 中獲取

遊戲規則

棋局開始時黑棋位於 E4 和 D5 ,白棋位於 D4 和 E5,如圖所示。
在這裏插入圖片描述

黑方先行,雙方交替下棋。
一步合法的棋步包括:
在一個空格處落下一個棋子,並且翻轉對手一個或多個棋子;
新落下的棋子必須落在可夾住對方棋子的位置上,對方被夾住的所有棋子都要翻轉過來,
可以是橫着夾,豎着夾,或是斜着夾。夾住的位置上必須全部是對手的棋子,不能有空格;
一步棋可以在數個(橫向,縱向,對角線)方向上翻棋,任何被夾住的棋子都必須被翻轉過來,棋手無權選擇不去翻某個棋子。
如果一方沒有合法棋步,也就是說不管他下到哪裏,都不能至少翻轉對手的一個棋子,那他這一輪只能棄權,而由他的對手繼續落子直到他有合法棋步可下。
如果一方至少有一步合法棋步可下,他就必須落子,不得棄權。
棋局持續下去,直到棋盤填滿或者雙方都無合法棋步可下。
如果某一方落子時間超過 1 分鐘 或者 連續落子 3 次不合法,則判該方失敗。

使用Alpha-Beta 剪枝搜索實現

class AIPlayer:
    """
    AI 玩家
    """
    weight = [
        [70, -20, 20, 20, 20, 20, -15, 70], 
	    [-20,-30,5,5,5,5,-30,-15], 
	    [20,5,1,1,1,1,5,20],
	    [20,5,1,1,1,1,5,20],
	    [20,5,1,1,1,1,5,20],
        [20,5,1,1,1,1,5,20],
	    [-20,-30,5,5,5,5,-30,-15],
	    [70,-15,20,20,20,20,-15,70]
    ]

    deepth = 0

    maxdeepth = 6
    emptylistFlag = 10000000

    def __init__(self, color):
        """
        玩家初始化
        :param color: 下棋方,'X' - 黑棋,'O' - 白棋
        """

        self.color = color

    def calculate(self,board,color):
        if color == 'X':
            colorNext ='O'
        else:
            colorNext ='X'
        count = 0
        for i in range(8):
            for j in range(8):
                if color == board[i][j]: 
                    count += self.weight[i][j]
                elif colorNext == board[i][j]:
                    count -= self.weight[i][j]
        return count

    def alphaBeta(self,board,color,a,b):
        # 遞歸終止
        if self.deepth > self.maxdeepth:
                return None, self.calculate(board,self.color)

        if color == 'X':
            colorNext ='O'
        else:
            colorNext ='X'
        action_list = list(board.get_legal_actions(color))
        if len(action_list) == 0:
            if len(list(board.get_legal_actions(colorNext))) == 0:
                return None,self.calculate(board,self.color)
            return self.alphaBeta(board,colorNext,a,b)
        
        max = -9999999
        min = 9999999
        action = None

        for p in action_list:

            flipped_pos = board._move(p,color)
            self.deepth += 1
            p1, current = self.alphaBeta(board,colorNext,a,b)
            self.deepth -= 1
            board.backpropagation(p,flipped_pos,color)
            # print(p,current)
            # alpha-beta 剪枝
            if color == self.color:
                if current > a:
                    if current > b:
                        return p,current
                    a = current
                if current > max:
                    max = current
                    action = p

            else:
                if current < b:
                    if current < a:
                        return p,current
                    b = current
                if current < min:
                    min = current
                    action = p

        # print(color,action,max,min)

        if color == self.color:
            return action,max
        else:
            return action,min         


    def get_move(self, board):
        """
        根據當前棋盤狀態獲取最佳落子位置
        :param board: 棋盤
        :return: action 最佳落子位置, e.g. 'A1'
        """
        if self.color == 'X':
            player_name = '黑棋'
        else:
            player_name = '白棋'
        print("請等一會,對方 {}-{} 正在思考中...".format(player_name, self.color))

        # -----------------請實現你的算法代碼--------------------------------------
        action_list = list(board.get_legal_actions(self.color))
        
        # action, weight = self.maxMin(board,self.color)
        action, weight = self.alphaBeta(board,self.color,-9999999,9999999)

        if len(action_list) == 0:
            return None
        print(action_list)
        print(action)
        return action
        # ------------------------------------------------------------------------



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章