1. 程式人生 > >【機器學習實戰】製作五子棋AI之四:基本規則的建立【2】

【機器學習實戰】製作五子棋AI之四:基本規則的建立【2】

在上一次,我們建立了棋盤的狀態類GameStatus,用來存取和顯示每一步走完後的棋盤上黑白子的狀態。想一想,為了像真實的五子棋遊戲一樣執行,還缺了遊戲勝負的判定,那麼我們定義一個函式對遊戲勝負進行判斷。

def check_win(black,white):#黑色白色棋子的索引值列表
    if xxx:
        # 黑方勝利
        return 0
    if xxx:
        # 白方勝利
        return 1
    if xxx:
        # 平局
        return 2    

五子棋是順序進行的,黑方白方依次落子,所以不需要每次對整個棋盤狀態進行掃描,只需要對最後一枚落下的子進行判斷即可。

def check_win(black,white):#黑色白色棋子的索引值列表
    if len(black) > len(white):#黑棋先下 黑棋多最後一枚為黑子
        # 提取最後一枚棋子索引值
        index = black[-1]
        if xxx:
            # 黑方勝利
            return 0
    else:
        index = black[-1]
        if xxx:
            # 白方勝利
            return 1
    if len(black)+len(white) == 225
: # 平局 return 2

現在考慮一下,如何判斷是否五子(或者更多)連珠。首先,因為橫縱或者斜線都可以形成五子連珠,所以我們要先定義一下方向的問題。
這裡寫圖片描述
這樣我們就可以把這個任務拆分在1,2,3,4四根軸上

首先先在1號橫軸上進行判斷,思路是先找出所在橫軸的所有格子,然後找有哪些棋子在這些格子上,最後判斷是否有五個連續的棋子。

def five_pieces(pieces_list):
    # 提取最後一顆棋子
    index = pieces_list[-1]
    # 最後一個棋子的座標值
    piece_i,piece_j = index2array(index)

    # 1號軸上所有的格點
row_pieces_list = list() row_grid_list = [(piece_i,j) for j in range(1,16)] for p,q in row_grid_list: if array2index((p,q)) in pieces_list: row_pieces_list.append(array2index((p,q))) row_pieces_list.sort() # 判斷1號橫軸上有沒有五個連續的棋子 if len(row_pieces_list) >= 5: for n in range(len(row_pieces_list)-5+1): # 判斷是否連續 if row_pieces_list[n+4]-row_pieces_list[n] == 4: return 1

類似的可以得到豎軸的檢測方法

    # 3號豎軸上所有的格點
    line_pieces_list = list()
    line_grid_list = [(i,piece_j) for i in range(1,16)]
    for p,q in line_grid_list:
        if array2index((p,q)) in pieces_list:
            line_pieces_list.append(array2index((p,q)))
            line_pieces_list.sort()
    # 判斷3號豎軸上有沒有五個連續的棋子
    if len(line_pieces_list) >= 5:
        for n in range(len(line_pieces_list)-5+1):
            # 判斷是否連續
            if line_pieces_list[n+4]-line_pieces_list[n] == 4*15:
                return 1

然後通過計算2,4號軸上的起始和終止點,從而得到軸上所有的格點,然後剩下的按照處理橫軸和豎軸的方法就可以了。

    # 2號左斜軸上所有的格點
    left_pieces_list = list()
    # 計算2號軸上左上起始點
    d_ij = min(piece_i,piece_j)-1
    start_grid_i = piece_i-d_ij
    start_grid_j = piece_j-d_ij
    # 計算2號軸上右下終止點
    end_grid_i = start_grid_i+(14-abs(piece_i-piece_j))
    end_grid_j = start_grid_j+(14-abs(piece_i-piece_j))

    left_grid_list = [(i,j)for i,j in zip(range(start_grid_i,end_grid_i+1),range(start_grid_j,end_grid_j+1))]
    for p,q in left_grid_list:
        if array2index((p,q)) in pieces_list:
            left_pieces_list.append(array2index((p,q)))
            left_pieces_list.sort()
    # 判斷2號左斜軸上有沒有五個連續的棋子
    if len(left_pieces_list) >= 5:
        for n in range(len(left_pieces_list)-5+1):
            # 判斷是否連續
            if left_pieces_list[n+4]-left_pieces_list[n] == 4*(15+1):
                return 1

    # 3號右斜軸上所有的格點
    right_pieces_list = list()
    # 計算3號軸上右上起始點
    d_ij = min(piece_i,piece_j)-1
    start_grid_i = piece_i-d_ij
    start_grid_j = piece_j+d_ij
    # 計算3號軸上左下終止點
    end_grid_i = start_grid_i+abs(piece_i-piece_j)
    end_grid_j = start_grid_j-abs(piece_i-piece_j)
    right_i_list = list(range(start_grid_i,end_grid_i+1))
    right_j_list = list(range(end_grid_j,start_grid_j+1))
    right_j_list.reverse()
    right_grid_list = [(i,j )for i,j in zip(right_i_list,right_j_list)]
    for p,q in right_grid_list:
        if array2index((p,q)) in pieces_list:
            right_pieces_list.append(array2index((p,q)))
            right_pieces_list.sort()
    # 判斷3號右斜軸上有沒有五個連續的棋子
    if len(right_pieces_list) >= 5:
        for n in range(len(right_pieces_list)-5+1):
            # 判斷是否連續
            if right_pieces_list[n+4]-right_pieces_list[n] == 4*(15-1):
                return 1

    return 0

最後一步,就很簡單了,呼叫一下我們檢測五子連珠的程式,就可以判定勝負了

def check_win(black,white):#黑色白色棋子的索引值列表
    if five_pieces(black):
        # 黑方勝利
        return 0
    if five_pieces(white):
        # 白方勝利
        return 1
    if len(black)+len(white) == 225:
        # 平局
        return 2

這樣就大功告成了,得到了一個預期的判斷勝負的函式,把它新增進上次使用的gamerule.py裡面,方便以後使用。

判斷的邏輯感覺稍微有點繁瑣,如果有更簡潔的方法,請不吝賜教。

由於本人水平有限,難免出現錯漏之處,歡迎批評指正