Пример #1
0
class GameStrategy_MZhang():
    def __init__(self, startplayer=0):
        model_file = 'models/resnet/output318/current_policy.model'
        policy_param = None
        self.height = 15
        self.width = 15
        '''if model_file is not None:
            print('loading...', model_file)
            try:
                policy_param = pickle.load(open(model_file, 'rb'))
            except:
                policy_param = pickle.load(open(model_file, 'rb'), encoding='bytes')'''
        policy_value_net = PolicyValueNet(self.height,
                                          self.width,
                                          model_file=model_file,
                                          output='output/')
        self.mcts_player = MCTSPlayer(policy_value_net.policy_value_fn,
                                      c_puct=1,
                                      n_playout=1000)
        self.board = Board(width=self.width, height=self.height, n_in_row=5)
        self.board.init_board(startplayer)
        self.game = Game(self.board)
        p1, p2 = self.board.players
        print('players:', p1, p2)
        self.mcts_player.set_player_ind(p1)
        pass

    def play_one_piece(self, user, gameboard):
        print('user:'******'gameboard:', gameboard.move_history)
        lastm = gameboard.get_lastmove()
        if lastm[0] != -1:
            usr, n, row, col = lastm
            mv = (self.height - row - 1) * self.height + col
            # if not self.board.states.has_key(mv):
            self.board.do_move(mv)

        print('board:', self.board.states.items())
        move = self.mcts_player.get_action(self.board)
        self.board.do_move(move)
        self.game.graphic(self.board, *self.board.players)
        outmv = (self.height - move // self.height - 1, move % self.width)

        return outmv
Пример #2
0
def get_mcts_player(player_index=1):
    """
    Get an mcts player, an index of 1 corresponds to first player (typically
    human) and an index of 2 corresponds to the second player (typically AI
    opponent).
    """
    board = Board()
    board.init_board()

    size = 8
    model_file = '../AlphaZero_Gomoku/best_policy_8_8_5.model'

    try:
        policy_param = pickle.load(open(model_file, 'rb'))
    except Exception:
        policy_param = pickle.load(open(model_file, 'rb'), encoding='bytes')

    best_policy = PolicyValueNetNumpy(size, size, policy_param)
    mcts_player = MCTSPlayer(best_policy.policy_value_fn, c_puct=5,
                             n_playout=200)
    mcts_player.set_player_ind(player_index)

    return mcts_player
Пример #3
0
class Chess_Board_Canvas(Tkinter.Canvas):
    # 棋盤繪製
    def __init__(self, master=None, height=0, width=0):
        Tkinter.Canvas.__init__(self, master, height=height, width=width)
        self.step_record_chess_board = Record.Step_Record_Chess_Board()
        # 初始化記步器
        self.height = 15
        self.width = 15
        self.init_chess_board_points()  # 畫點
        self.init_chess_board_canvas()  # 畫棋盤
        self.board = MCTS.Board()
        self.n_in_row = 5
        self.n_playout = 400  # num of simulations for each move
        self.c_puct = 5
        """
        Important 1: Python is pass by reference
        So the self.board will be modified by other operations
        """
        self.AI = MCTS.MonteCarlo(self.board, 1)
        self.AI_1 = MCTS.MonteCarlo(self.board, 0)
        self.clicked = 1
        self.init = True  # first place is given by user (later need to be replaced as a random selection)
        self.train_or_play = True  # True - train, False - play
        self.step = 0
        self.text_id = None

    def init_chess_board_points(self):
        '''
        生成棋盤點,並且對應到像素座標
        保存到 chess_board_points 屬性
        '''
        self.chess_board_points = [[None for i in range(15)]
                                   for j in range(15)]

        for i in range(15):
            for j in range(15):
                self.chess_board_points[i][j] = Point.Point(i, j)
                # 轉換棋盤座標像素座標
        # self.label_step = Label(self, text="Step")

    def init_chess_board_canvas(self):
        '''
        初始化棋盤
        '''

        for i in range(15):  # 直線
            self.create_line(self.chess_board_points[i][0].pixel_x,
                             self.chess_board_points[i][0].pixel_y,
                             self.chess_board_points[i][14].pixel_x,
                             self.chess_board_points[i][14].pixel_y)

        for j in range(15):  # 橫線
            self.create_line(self.chess_board_points[0][j].pixel_x,
                             self.chess_board_points[0][j].pixel_y,
                             self.chess_board_points[14][j].pixel_x,
                             self.chess_board_points[14][j].pixel_y)
        # 邊界
        self.create_line(self.chess_board_points[2][2].pixel_x,
                         self.chess_board_points[2][2].pixel_y,
                         self.chess_board_points[2][12].pixel_x,
                         self.chess_board_points[2][12].pixel_y,
                         fill="red")
        self.create_line(self.chess_board_points[12][2].pixel_x,
                         self.chess_board_points[12][2].pixel_y,
                         self.chess_board_points[12][12].pixel_x,
                         self.chess_board_points[12][12].pixel_y,
                         fill="red")
        self.create_line(self.chess_board_points[2][12].pixel_x,
                         self.chess_board_points[2][12].pixel_y,
                         self.chess_board_points[12][12].pixel_x,
                         self.chess_board_points[12][12].pixel_y,
                         fill="red")
        self.create_line(self.chess_board_points[2][2].pixel_x,
                         self.chess_board_points[2][2].pixel_y,
                         self.chess_board_points[12][2].pixel_x,
                         self.chess_board_points[12][2].pixel_y,
                         fill="red")

        for i in range(15):  # 交點橢圓
            for j in range(15):
                r = 1
                self.create_oval(self.chess_board_points[i][j].pixel_x - r,
                                 self.chess_board_points[i][j].pixel_y - r,
                                 self.chess_board_points[i][j].pixel_x + r,
                                 self.chess_board_points[i][j].pixel_y + r)

    def click1(self, event):  # click關鍵字重複
        if self.train_or_play:
            print("In self training, mouse event is not available")
            return
        '''
        Mouse listener function, for the game played between human and AI
        '''
        if (self.clicked == 1):

            for i in range(15):
                for j in range(15):
                    square_distance = math.pow(
                        (event.x - self.chess_board_points[i][j].pixel_x),
                        2) + math.pow(
                            (event.y - self.chess_board_points[i][j].pixel_y),
                            2)
                    # 計算滑鼠的位置和點的距離
                    # 距離小於14的點

                    if (square_distance <=
                            200) and (self.step_record_chess_board.checkState(
                                i, j) == None):  # 合法落子位置
                        self.clicked = 0
                        if self.step_record_chess_board.who_to_play() == 1:
                            # 奇數次,黑落子
                            self.create_oval(
                                self.chess_board_points[i][j].pixel_x - 10,
                                self.chess_board_points[i][j].pixel_y - 10,
                                self.chess_board_points[i][j].pixel_x + 10,
                                self.chess_board_points[i][j].pixel_y + 10,
                                fill='black')
                            Tkinter.Canvas.update(self)
                        # 偶數次,白落子
                        elif self.step_record_chess_board.who_to_play() == 2:
                            self.create_oval(
                                self.chess_board_points[i][j].pixel_x - 10,
                                self.chess_board_points[i][j].pixel_y - 10,
                                self.chess_board_points[i][j].pixel_x + 10,
                                self.chess_board_points[i][j].pixel_y + 10,
                                fill='white')

                        result = 0
                        if (self.step_record_chess_board.value[1][i][j] >=
                                90000):
                            result = 1
                            self.clicked = 1
                        self.step_record_chess_board.insert_record(i, j)
                        # 落子,最多225

                        #######result = self.step_record_chess_board.check()
                        # 判斷是否有五子連珠

                        if result == 1:
                            self.create_text(240, 475, text='the black wins')
                            # 解除左键绑定
                            self.unbind('<Button-1>')
                            # """Unbind for this widget for event SEQUENCE  the
                            #     function identified with FUNCID."""

                        elif result == 2:
                            self.create_text(240, 475, text='the white wins')
                            # 解除左键绑定
                            self.unbind('<Button-1>')
            # 根據價值網路落子
            if (self.clicked != 1):
                x = 0
                y = 0
                max_value = 0
                for i in range(0, 15):
                    for j in range(0, 15):
                        if (self.step_record_chess_board.value[2][i][j] >=
                                90000):
                            x = i
                            y = j
                            max_value = 99999
                            break
                        elif (self.step_record_chess_board.value[0][i][j] >=
                              max_value):
                            x = i
                            y = j
                            max_value = self.step_record_chess_board.value[0][
                                i][j]
                if (self.step_record_chess_board.value[2][x][y] >= 90000):
                    result = 2

                self.board.state = np.copy(self.step_record_chess_board.state)
                self.AI.value = self.step_record_chess_board.value[0]
                self.AI.update(self.board.state)
                action = self.AI.bestAction()
                x, y = action

                self.step_record_chess_board.insert_record(x, y)
                self.create_oval(self.chess_board_points[x][y].pixel_x - 10,
                                 self.chess_board_points[x][y].pixel_y - 10,
                                 self.chess_board_points[x][y].pixel_x + 10,
                                 self.chess_board_points[x][y].pixel_y + 10,
                                 fill='white')
                #######result = self.step_record_chess_board.check()
                # 判斷是否有五子連珠

                if result == 1:
                    self.create_text(240, 475, text='the black wins')
                    # 解除左键绑定
                    self.unbind('<Button-1>')
                # """Unbind for this widget for event SEQUENCE  the
                #     function identified with FUNCID."""

                elif result == 2:
                    self.create_text(240, 475, text='the white wins')
                    # 解除左键绑定
                    self.unbind('<Button-1>')
                self.clicked = 1

    def click2(self):  # click關鍵字重複
        """
        #   Human vs AI
        #   Have to load trained NN
        """
        self.train_or_play = False  # this will lock the "ai vs human" button

        return

    def loadAI(self, init_model):
        """"
        # load AI
        """

        # return
        # self.buffer_size = 10000
        # self.batch_size = 512  # mini-batch size for training
        # self.data_buffer = deque(maxlen=self.buffer_size)
        init_model = "current_policy.model"
        init_model = "best_policy.model"
        init_model = 'best_policy_12000.pt'
        # init_model = 'best_policy200.pt'

        self.result = False

        # self.policy_value_net = PolicyValueNet(self.width,
        #                                        self.height,
        #                                        model_file=False)
        self.policy_value_net = PolicyValueNet(self.width,
                                               self.height,
                                               model_file=init_model,
                                               use_gpu=False)

        self.mcts_player = MCTSPlayer(self.policy_value_net.policy_value_fn,
                                      c_puct=self.c_puct,
                                      n_playout=self.n_playout,
                                      is_selfplay=0)
        self.board2 = Board2(width=self.width,
                             height=self.height,
                             n_in_row=self.n_in_row)
        self.board2.init_board(1)
        self.game = Game(self.board2)

    def click3(self):
        """
        ##  Training
        ##  make it self play, AI vs AI, no need to click the mouse, so no need to listen the event
        ##  problem: Let two AIs to play, and learn the NN
        """

        self.train_or_play = True  # this will lock the "ai vs human" button
        self.loadAI(False)
        # self.policy_value_net = PolicyValueNet(self.width,
        #                                        self.height)

        # self.mcts_player = MCTSPlayer(self.policy_value_net.policy_value_fn,
        #                               c_puct=self.c_puct,
        #                               n_playout=self.n_playout,
        #                               is_selfplay=1)
        print(self.width, self.height)

        # self.step += 1
        # # self.train_agents()
        # print("agent1: load")
        self.train_nn_agents()

    def train_nn_agents(self):
        self.step += 1
        print("============agents at steps %d ============" % self.step)
        if (self.clicked == 1
            ):  # Black stone, Gomoku agent, using very good heuristic function
            print("Black begins at step %d, %d>>>>>>>>>>>>>>>>>>>>>" %
                  (self.step, self.step_record_chess_board.who_to_play()))
            x = 0
            y = 0
            max_value = 0
            result = 0
            for i in range(0, 15):
                for j in range(0, 15):
                    if (self.step_record_chess_board.value[1][i][j] >= 90000):
                        x = i
                        y = j
                        max_value = 99999
                        break
                    elif (self.step_record_chess_board.value[0][i][j] >=
                          max_value):
                        x = i
                        y = j
                        max_value = self.step_record_chess_board.value[0][i][j]

            if (self.step_record_chess_board.value[1][x][y] >= 90000):
                print("win black in black0!!!!!!!!!!!!!!!!")
                result = 1

            self.board.state = np.copy(self.step_record_chess_board.state)
            self.AI.value = self.step_record_chess_board.value[0]
            self.AI.update(self.board.state)
            # print("temp state, before move", self.AI.value)
            action = self.AI.bestAction()
            x, y = action

            self.create_oval(self.chess_board_points[x][y].pixel_x - 10,
                             self.chess_board_points[x][y].pixel_y - 10,
                             self.chess_board_points[x][y].pixel_x + 10,
                             self.chess_board_points[x][y].pixel_y + 10,
                             fill='black')
            move2 = (self.height - y - 1) * self.width + x

            self.board2.current_player = 1
            self.board2.do_move(move2)
            print("Black, Gomoku takes action: ", move2, x, y,
                  (self.step, self.step_record_chess_board.who_to_play()))
            self.step_record_chess_board.insert_record(
                x, y)  # this function will switch to another player
            # if (self.step_record_chess_board.value[1][x][y] >= 90000):
            #     print("win white in black")
            #     result = 2
            # if (self.step_record_chess_board.value[2][x][y] >= 90000):
            #     print("win black in black")
            #     result = 1
            m6 = self.board.isWin(self.step_record_chess_board.state, (x, y),
                                  1)
            if result == 1 or m6:
                self.create_text(240, 475, text='the black wins, b11')
                return
            elif result == 2:
                self.create_text(240, 475, text='the white wins, b22')
                return
            self.clicked = 0

        if (self.clicked != 1):  # white stone, AlphaZero Angent
            print("White begins at step %d, %d >>>>>>>>>>>>>>>>>>>>>" %
                  (self.step, self.step_record_chess_board.who_to_play()))
            self.clicked = 1
            if self.step_record_chess_board.who_to_play() == 1:
                cur_play = 1
            elif self.step_record_chess_board.who_to_play() == 2:
                cur_play = 2  # current is white, 2

            if (self.step_record_chess_board.value[2][x][y] >= 90000):
                print("win white in white!!!!!!!!!!!!!!!!")
                result = 2

            # NN AI do:
            # get board state information
            temp_board = np.copy(self.step_record_chess_board.state)
            self.board2.update_state(temp_board)

            self.board2.current_player = cur_play
            self.mcts_player.reset_player()
            self.mcts_player.set_player_ind(cur_play)
            test_moved = list(
                set(range(self.width * self.height)) -
                set(self.board2.availables))
            self.mcts_player.reset_player()
            action = self.mcts_player.get_action(self.board2)
            self.board2.do_move(action)
            x = action % self.width
            y = action // self.height
            y = self.height - y - 1
            # print("after action",self.board2.states, len(self.board2.availables))
            # print("White, NN agent want to place at: ", action, x, y, (self.step,self.step_record_chess_board.who_to_play()))
            # self.board2.do_move(action)
            # insert into the record, for the white player to use
            self.step_record_chess_board.insert_record(x, y)
            # print("----------------------------------------")

            self.create_oval(self.chess_board_points[x][y].pixel_x - 10,
                             self.chess_board_points[x][y].pixel_y - 10,
                             self.chess_board_points[x][y].pixel_x + 10,
                             self.chess_board_points[x][y].pixel_y + 10,
                             fill='white')
            if self.result:
                print("white wins")
                return
            # if (self.step_record_chess_board.value[1][x][y] >= 90000):
            #     print("win white in white")
            #     result = 2
            # if (self.step_record_chess_board.value[2][x][y] >= 90000):
            #     print("win black in white")
            #     result = 1
            m6 = self.board.isWin(self.step_record_chess_board.state, (x, y),
                                  2)
            if result == 1:
                self.create_text(240, 475, text='the black wins, w12')
                return

            elif result == 2 or m6:
                self.create_text(240, 475, text='the white wins, w22')
                return
            self.clicked = 1

        if self.text_id:
            print(self.text_id)
            self.delete(self.text_id)
        self.text_id = self.create_text(150, 475, text='Step: %d' % self.step)
        self.after(10, self.train_nn_agents)

    def collect_selfplay_data(self, n_games=1):
        """collect self-play data for training"""
        for i in range(n_games):
            winner, play_data = self.game.start_self_play(self.mcts_player,
                                                          temp=1)
            play_data = list(play_data)[:]
            self.episode_len = len(play_data)
            # augment the data
            play_data = self.get_equi_data(play_data)
            self.data_buffer.extend(play_data)

    def get_equi_data(self, play_data):
        """augment the data set by rotation and flipping
                play_data: [(state, mcts_prob, winner_z), ..., ...]
                """
        extend_data = []
        for state, mcts_porb, winner in play_data:
            for i in [1, 2, 3, 4]:
                # rotate counterclockwise
                equi_state = np.array([np.rot90(s, i) for s in state])
                equi_mcts_prob = np.rot90(
                    np.flipud(mcts_porb.reshape(self.height, self.width)), i)
                extend_data.append(
                    (equi_state, np.flipud(equi_mcts_prob).flatten(), winner))
                # flip horizontally
                equi_state = np.array([np.fliplr(s) for s in equi_state])
                equi_mcts_prob = np.fliplr(equi_mcts_prob)
                extend_data.append(
                    (equi_state, np.flipud(equi_mcts_prob).flatten(), winner))
        return extend_data

    def train_agents(self):
        self.step += 1
        if (self.clicked != 1):
            x = 0
            y = 0
            max_value = 0
            result = 0
            for i in range(0, 15):
                for j in range(0, 15):
                    if (self.step_record_chess_board.value[1][i][j] >= 90000):
                        x = i
                        y = j
                        max_value = 99999
                        break
                    elif (self.step_record_chess_board.value[0][i][j] >=
                          max_value):
                        x = i
                        y = j
                        max_value = self.step_record_chess_board.value[0][i][j]
            if (self.step_record_chess_board.value[1][x][y] >= 90000):
                result = 2
            """
            Important 2:
            Only below 4 line are interact between the AI agent and the board
            self.board.state = np.copy(self.step_record_chess_board.state)  # make a deep copy of state
            self.AI_1.value = self.step_record_chess_board.value[1]         # assign board information, a 15*15 array
            self.AI_1.update(self.board.state)                              # AI function, do some calculations
            action = self.AI_1.bestAction()                                 # Best actions the AI will make
            """
            self.board.state = np.copy(self.step_record_chess_board.state)
            self.AI_1.value = self.step_record_chess_board.value[1]
            self.AI_1.update(self.board.state)
            action = self.AI_1.bestAction()

            x, y = action

            self.step_record_chess_board.insert_record(x, y)

            self.create_oval(self.chess_board_points[x][y].pixel_x - 10,
                             self.chess_board_points[x][y].pixel_y - 10,
                             self.chess_board_points[x][y].pixel_x + 10,
                             self.chess_board_points[x][y].pixel_y + 10,
                             fill='black')
            if result == 1:
                self.create_text(240, 475, text='the black wins')
                return

            elif result == 2:
                self.create_text(240, 475, text='the white wins')
                return
            self.clicked = 1

            # 根據價值網路落子
        if (self.clicked == 1):  # White stone
            x = 0
            y = 0
            max_value = 0
            for i in range(0, 15):
                for j in range(0, 15):
                    if (self.step_record_chess_board.value[2][i][j] >= 90000):
                        x = i
                        y = j
                        max_value = 99999
                        break
                    elif (self.step_record_chess_board.value[0][i][j] >=
                          max_value):
                        x = i
                        y = j
                        max_value = self.step_record_chess_board.value[0][i][j]

            if (self.step_record_chess_board.value[2][x][y] >= 90000):
                result = 2

            self.board.state = np.copy(self.step_record_chess_board.state)
            self.AI.value = self.step_record_chess_board.value[0]
            self.AI.update(self.board.state)
            action = self.AI.bestAction()
            x, y = action

            self.step_record_chess_board.insert_record(x, y)
            self.create_oval(self.chess_board_points[x][y].pixel_x - 10,
                             self.chess_board_points[x][y].pixel_y - 10,
                             self.chess_board_points[x][y].pixel_x + 10,
                             self.chess_board_points[x][y].pixel_y + 10,
                             fill='white')

            if result == 1:
                self.create_text(240, 475, text='the black wins')

                return
            elif result == 2:
                self.create_text(240, 475, text='the white wins')
                return
            self.clicked = 0

        if self.text_id:
            print(self.text_id)
            self.delete(self.text_id)
        self.text_id = self.create_text(150, 475, text='Step: %d' % self.step)
        self.after(10, self.train_agents)
Пример #4
0
class Gobang() :
    #初始化
    def __init__(self) :
        self.board = chessBoard()
        self.game_print = StringVar()
        self.game_print.set("")
        #16*16的二维列表,保证不会out of index
        self.db = [([2] * 9) for i in range(9)]
        #悔棋用的顺序列表
        self.order = []
        #棋子颜色
        self.color_count = 0 
        self.color = 'black'
        #清空与赢的初始化,已赢为1,已清空为1
        self.flag_win = 1
        self.flag_empty = 1

        self.start_player = 0
        width, height, n_in_row = 9, 9, 5
        model_file = 'output/best_policy.model'
        baseline_file = 'output/baseline_policy.model'
        board = Board(width=width, height=height, n_in_row=n_in_row, forbidden_hands=False)
        self.game = Game(board)
        self.game.board.init_board(self.start_player)
        self.best_policy = PolicyValueNetRes30(width, height, 'l+', model_file=model_file)
        self.baseline_policy = PolicyValueNet(width, height, 'l+', model_file=baseline_file)
        self.mcts_player = MCTSPlayer(self.best_policy.policy_value_fn,
                                 c_puct=5,
                                 n_playout=500)  # set larger n_playout for better performance
        self.mcts_baseline_player = MCTSPlayer(self.baseline_policy.policy_value_fn,
                                 c_puct=5,
                                 n_playout=500)  # set larger n_playout for better performance
        self.human_player = Human()
        self.human_player.set_player_ind(1)
        #self.mcts_baseline_player.set_player_ind(1)
        self.mcts_player.set_player_ind(2)
        self.players = {1:self.human_player, 2:self.mcts_player}
        #self.players = {1:self.mcts_baseline_player, 2:self.mcts_player}

        self.options()
        

    #黑白互换
    def change_color(self) :
        self.color_count = (self.color_count + 1 ) % 2
        if self.color_count == 0 :
            self.color = "black"
        elif self.color_count ==1 :
            self.color = "white"
    
    
    #落子
    def chess_moving(self ,event) :
        #不点击“开始”与“清空”无法再次开始落子
        if self.flag_win ==1 or self.flag_empty ==0:
            return
        #坐标转化为下标
        x,y = event.x-25 , event.y-25
        x = round(x/50)
        y = round(y/50)
        #点击位置没用落子,且没有在棋盘线外,可以落子
        while self.db[y][x] == 2 and self.limit_boarder(y,x):
            if len(self.order) > 0:
                last_move = self.order[-1]
                last_y = last_move//9
                last_x = last_move%9
                self.change_color()
                self.board.canvas.delete("chessman_new")
                self.board.canvas.create_oval(25+50*last_x-15 , 25+50*last_y-15 , 25+50*last_x+15 , 25+50*last_y+15 , fill = self.color,tags = "chessman")
                self.change_color()

            self.db[y][x] = self.color_count
            current_move = x+9*y
            self.order.append(current_move)
            self.board.canvas.create_oval(25+50*x-18 , 25+50*y-18 , 25+50*x+18 , 25+50*y+18 , fill = self.color,tags = "chessman_new")
            player_in_turn = self.get_current_player()
            print(self.color, player_in_turn, f"{x}, {y}")
            self.game.board.do_move(current_move)
            end, winner = self.game.board.game_end()
            if end:
                self.flag_win = 1
                self.flag_empty = 0
                print(self.color, player_in_turn, "win!!!")
                self.game_print.set(self.color+"-"+str(player_in_turn)+"获胜")
            else:
                self.change_color()
                player_in_turn = self.get_current_player()
                self.game_print.set("请"+self.color+"-"+str(player_in_turn)+"落子")
                if player_in_turn is self.human_player:
                    return
                self.board.window.update()
                move = player_in_turn.get_action(self.game.board)
                x = move%9
                y = move//9
    

    #保证棋子落在棋盘上
    def limit_boarder(self , y , x) :
        if x<0 or x>8 or y<0 or y>8 :
            return False
        else :
            return True


    #计算连子的数目,并返回最大连子数目
    def chessman_count(self , y , x , color_count ) :
        count1,count2,count3,count4 = 1,1,1,1
        #横计算
        for i in range(-1 , -5 , -1) :
            if self.db[y][x+i] == color_count  :
                count1 += 1
            else:
                break 
        for i in  range(1 , 5 ,1 ) :
            if self.db[y][x+i] == color_count  :
                count1 += 1
            else:
                break 
        #竖计算
        for i in range(-1 , -5 , -1) :
            if self.db[y+i][x] == color_count  :
                count2 += 1
            else:
                break 
        for i in  range(1 , 5 ,1 ) :
            if self.db[y+i][x] == color_count  :
                count2 += 1
            else:
                break 
        #/计算
        for i in range(-1 , -5 , -1) :
            if self.db[y+i][x+i] == color_count  :
                count3 += 1
            else:
                break 
        for i in  range(1 , 5 ,1 ) :
            if self.db[y+i][x+i] == color_count  :
                count3 += 1
            else:
                break 
        #\计算
        for i in range(-1 , -5 , -1) :
            if self.db[y+i][x-i] == color_count :
                count4 += 1
            else:
                break 
        for i in  range(1 , 5 ,1 ) :
            if self.db[y+i][x-i] == color_count :
                count4 += 1
            else:
                break 
            
        return max(count1 , count2 , count3 , count4)


    #判断输赢
    def game_win(self , y , x , color_count ) :
        if self.chessman_count(y,x,color_count) >= 5 :
            self.flag_win = 1
            self.flag_empty = 0
            return True
        else :
            return False
        

    #悔棋,清空棋盘,再画剩下的n-1个棋子
    def withdraw(self ) :
        if len(self.order)==0 or self.flag_win == 1:
            return
        self.board.canvas.delete("chessman")
        z = self.order.pop()
        x = z%9
        y = z//9
        self.db[y][x] = 2
        self.color_count = 1
        for i in self.order :
            ix = i%9
            iy = i//9
            self.change_color()
            self.board.canvas.create_oval(25+50*ix-15 , 25+50*iy-15 , 25+50*ix+15 , 25+50*iy+15 , fill = self.color,tags = "chessman")
        self.change_color()
        self.game_print.set("请"+self.color+"落子")
    

    #清空
    def empty_all(self) :
        self.board.canvas.delete("chessman_new")
        self.board.canvas.delete("chessman")
        print(" Empty all!!!")
        #还原初始化
        self.db = [([2] * 9) for i in range(9)]
        self.order = []
        self.color_count = 0 
        self.color = 'black'
        self.flag_win = 1
        self.flag_empty = 1
        self.game_print.set("")
        self.start_player = (self.start_player+1)%2
        self.game.board.init_board(self.start_player)

    def get_current_player(self):
        current_player = self.game.board.get_current_player()
        player_in_turn = self.players[current_player]
        return player_in_turn

    #将self.flag_win置0才能在棋盘上落子
    def game_start(self) :
        #没有清空棋子不能置0开始
        if self.flag_empty == 0:
            return
        self.flag_win = 0
        print(" New game start...")

        while True:
            player_in_turn = self.get_current_player()
            self.game_print.set("请"+self.color+"-"+str(player_in_turn)+"落子")
            self.board.window.update()
            if player_in_turn is self.human_player:
                return

            if len(self.order) > 0:
                last_move = self.order[-1]
                last_y = last_move//9
                last_x = last_move%9
                self.change_color()
                self.board.canvas.delete("chessman_new")
                self.board.canvas.create_oval(25+50*last_x-15 , 25+50*last_y-15 , 25+50*last_x+15 , 25+50*last_y+15 , fill = self.color,tags = "chessman")
                self.change_color()

            move = player_in_turn.get_action(self.game.board)
            x = move%9
            y = move//9    
            self.db[y][x] = self.color_count
            self.order.append(move)
            self.board.canvas.create_oval(25+50*x-18 , 25+50*y-18 , 25+50*x+18 , 25+50*y+18 , fill = self.color,tags = "chessman_new")
            print(self.color, player_in_turn, f"{x}, {y}")
            self.game.board.do_move(move)
            end, winner = self.game.board.game_end()
            if end:
                self.flag_win = 1
                self.flag_empty = 0
                print(self.color, player_in_turn, "win!!!")
                self.game_print.set(self.color+"-"+str(player_in_turn)+"获胜")
                return
            else:
                self.change_color()

    def options(self) :
        self.board.canvas.bind("<Button-1>",self.chess_moving)
        Label(self.board.window , textvariable = self.game_print , font = ("Arial", 12) ).place(relx = 0, rely = 0 ,x = 475 , y = 200)
        Button(self.board.window , text= "开始游戏" ,command = self.game_start,width = 13, font = ("Verdana", 12)).place(relx=0, rely=0, x=475, y=15)
        #Button(self.board.window , text= "我要悔棋" ,command = self.withdraw,width = 13, font = ("Verdana", 12)).place(relx=0, rely=0, x=475, y=60)
        Button(self.board.window , text= "清空棋局" ,command = self.empty_all,width = 13, font = ("Verdana", 12)).place(relx=0, rely=0, x=475, y=105)
        Button(self.board.window , text= "结束游戏" ,command = self.board.window.destroy,width = 13, font = ("Verdana", 12)).place(relx=0, rely=0, x=475, y=400)
        self.board.window.mainloop()