1. 程式人生 > >python簡單的五子棋ai訓練(第一步,設計棋盤)

python簡單的五子棋ai訓練(第一步,設計棋盤)

import numpy as np

class game:

    def __init__(self, **kwargs):
        self.wight = int(kwargs.get('wight', 15))
        self.height = int(kwargs.get('height', 15))
        '''棋盤原型 self.graphic 操作就是修改該物件'''
        self.graphic = np.zeros((self.height, self.wight))
        self.current_player = 1
        self.finish = False
        self.count = 1

    def move(self, position):
        if position[0] > self.height or position[1] > self.wight:
            print('輸入位置超過棋盤範圍')
            return False
        if self.graphic[position[0], position[1]] != 0:
            print('請在空白位置輸入')
            return False
        if self.current_player == 1:
            self.graphic[position[0], position[1]] = 1
        else:
            self.graphic[position[0], position[1]] = -1
        self.current_player *= -1
        return True

    def iswin(self, location):
        current_value = self.graphic[location[0], location[1]]
        '''豎'''
        max_point = 0
        for i in range(1, 6):
            if location[0]-i < 0 or self.graphic[location[0]-i, location[1]] != current_value:
                break
            max_point = i
        for j in range(1, 6):
            if max_point >= 4:
                return True
            if location[0]+j >= self.height or self.graphic[location[0]+j, location[1]] != current_value:
                break
            max_point += 1
        '''橫'''
        max_point = 0
        for i in range(1, 6):
            if location[1] - i < 0 or self.graphic[location[0], location[1] - i] != current_value:
                break
            max_point = i
        for j in range(1, 6):
            if max_point >= 4:
                return True
            if location[1] + j >= self.wight or self.graphic[location[0], location[1] + j] != current_value:
                break
            max_point += 1
        '''左上至右下斜線'''
        max_point = 0
        for i in range(1, 6):
            if (location[0] - i < 0 or location[1] - i < 0) \
                    or self.graphic[location[0] - i, location[1] - i] != current_value:
                break
            max_point = i
        for j in range(1, 6):
            if max_point >= 4:
                return True
            if (location[0] + j >= self.height or location[1] + j >= self.wight)\
                    or self.graphic[location[0] + j, location[1] + j] != current_value:
                break
            max_point += 1
        '''左下至右上斜線'''
        max_point = 0
        for i in range(1, 6):
            if (location[0] + i >= self.height or location[1] - i < 0) \
                    or self.graphic[location[0] + i, location[1] - i] != current_value:
                break
            max_point = i
        for j in range(1, 6):
            if max_point >= 4:
                return True
            if (location[0] - j < 0 or location[1] + j >= self.wight) \
                    or self.graphic[location[0] - j, location[1] + j] != current_value:
                break
            max_point += 1

    def view(self):
        for x in range(9):
            print("{0:9}".format(x), end='')
        print('\r\n')
        for i in range(9):
            print("{0:4}".format(i), end='')
            for j in range(9):
                if self.graphic[i][j] == 1:
                    print('X'.center(9), end='')
                elif self.graphic[i][j] == -1:
                    print('O'.center(9), end='')
                else:
                    print('_'.center(9), end='')
            print('\r\n')

    def lines(self):
        for i in range(20):
            print('####', end='')
        print('\n', '現在是第%d步' % self.count)
        for i in range(20):
            print('####', end='')
        print('\n')

    def run(self):
        while not self.finish:
            self.view()
            if self.current_player == 1:
                location = input("Player1 move: ")
            else:
                location = input("Player2 move: ")
            try:
                location = [int(n) for n in location.split(" ")]
            except ValueError:
                print("輸出錯誤", '\r\n')
                continue

            if not self.move(location):
                continue
            if self.iswin(location):
                if self.current_player == -1:  # move後就已經交換了玩家
                    print("Player1 win")
                else:
                    print("Player2 win")
                self.view()
                return
            self.view()
            self.lines()
            self.count += 1

a = game(wight = 9,height = 9)
a.run()

設計上儘量追求簡潔,核心資料型別是numpy中的矩陣,其中move方法是下棋步驟,iswin是勝利判定,view是UI介面,line是分界線,UI介面設計比較簡潔,且只設計了9*9規格(太大了控制檯放不下也不好看)。但可以用原始run方法直接展示numpy矩陣,可以做任何介面對映。上面就是一個簡單的例子,下面只需要把run方法將上面的替換就可以使用任意規格遊戲。

    def run(self):
        while not self.finish:
            print(self.graphic)
            if self.current_player == 1:
                location = input("Player1 move: ")
            else:
                location = input("Player2 move: ")
            try:
                location = [int(n) for n in location.split(" ")]
            except ValueError:
                print("輸出錯誤", '\r\n')
                continue

            if not self.move(location):
                continue
            if self.iswin(location):
                if self.current_player == -1:   #move後就已經交換了玩家
                    print("Player1 win")
                else:
                    print("Player2 win")
                print(self.graphic, '\r\n', '第%d步' % self.count)
                return
            print(self.graphic, '\r\n', '第%d步' % self.count)
            self.count += 1

做好遊戲後就可以進行下一步ai訓練了