Esempio n. 1
0
 def reset(self) -> torch.Tensor: # (num_worker, 3, SIZE, SIZE)
     self.historys = [[] for _ in range(self.num_workers)]        
     self.end = [False for _ in range(self.num_workers)]
     black = Reversi()
     white = Reversi()
     white.place(Minimax.brain(white, 1), 1)
     self.reversis = [deepcopy(black) for _ in range(self.num_workers // 2)] + [deepcopy(white) for _ in range(self.num_workers // 2)]
     states = self.pool.map(getBoardState, self.reversis)
     return torch.Tensor(states)
Esempio n. 2
0
def play(reversi: Reversi, player1: Callable[[Reversi, int], Coordinate],
         player2: Callable[[Reversi, int], Coordinate]) -> int:
    while True:
        # 黑棋下子
        while reversi.next == 1:
            position = player1(reversi, 1)
            status = reversi.place(position, 1)

            if status.startswith('end'):
                return int(status[-1])
            elif status != 'ok':
                raise Exception('Should not reach here!')

        # 白棋下子
        while reversi.next == 2:
            position = player2(reversi, 2)
            status = reversi.place(position, 2)

            if status.startswith('end'):
                return int(status[-1])
            elif status != 'ok':
                raise Exception('Should not reach here!')
Esempio n. 3
0
    def play(self, reversi: Reversi, who: int, brain: Callable[[Reversi, int],
                                                               Coordinate]):
        ai = 2 if who == 1 else 1

        # 辅助函数:绘制最近一个棋子的虚线框,并重绘整个棋盘上的棋子(懒得判断翻转)
        def draw():
            if reversi.recent:
                self.canvas.delete('hint-recent')
                y, x = reversi.recent
                yy, xx = y * WIDTH, x * WIDTH
                self.canvas.create_rectangle(
                    xx,
                    yy,
                    xx + (WIDTH - 1),
                    yy + (WIDTH - 1),
                    fill='',
                    outline=self.colors[reversi.board[y][x]],
                    width=LINE,
                    tag='hint-recent')

            for (y, x) in itertools.product(range(self.size), repeat=2):
                if reversi.board[y][x]:
                    self.canvas.delete(f'chess-{y}-{x}')
                    yy, xx = y * WIDTH, x * WIDTH
                    self.canvas.create_oval(
                        xx + PADDING,
                        yy + PADDING,
                        xx + (WIDTH - 1 - PADDING),
                        yy + (WIDTH - 1 - PADDING),
                        fill=self.colors[reversi.board[y][x]],
                        tag=f'chess-{y}-{x}')
            self.window.update()

        # 鼠标单击事件的绑定函数,整个GUI游戏过程靠鼠标单击事件驱动
        def turn(event: tkinter.Event):
            y, x = event.y // WIDTH, event.x // WIDTH
            if y < 0 or y >= self.size or x < 0 or x > self.size:
                return

            status = reversi.place((y, x), who)

            if status == 'no':
                return

            self.canvas.delete('mouse-hint')  # 清除鼠标位置提示
            draw()
            print('You place at {}, black: {}, white: {}'.format(
                (x, y), reversi.number[1], reversi.number[2]))

            if status.startswith('end'):
                msg = 'Draw' if status == 'end 0' else f'Player {status[-1]} wins!'
                tkinter.messagebox.showinfo(title='Game Over', message=msg)
                self.canvas.unbind('<Motion>')
                self.canvas.unbind('<Button-1>')
                return

            # 轮到AI下棋

            aiPlayed = False  # 记录AI是否已经下过一次(再下说明刚刚玩家没位置下),以判断是否打印提示

            while reversi.next == ai:
                if aiPlayed:
                    print(
                        'You have no position to place your chess, so it\'s still AI\'s turn.'
                    )

                position = brain(reversi, ai)
                status = reversi.place(position, ai)

                if status == 'no':
                    raise Exception('F**K! THIS AI IS SHIT!')

                print('AI place at {}, black: {}, white: {}'.format(
                    (position[1], position[0]), reversi.number[1],
                    reversi.number[2]))
                draw()

                if status.startswith('end'):
                    msg = 'Draw' if status == 'end 0' else f'Player {status[-1]} wins!'
                    tkinter.messagebox.showinfo(title='Game Over', message=msg)
                    self.canvas.unbind('<Motion>')
                    self.canvas.unbind('<Button-1>')
                    return

                aiPlayed = True

            if not aiPlayed:
                print(
                    'AI have no position to place chess, it\'s still your turn.'
                )

        # 需要一个辅助函数来绑定鼠标移动事件,来提示鼠标位置
        def hint(event: tkinter.Event):
            self.canvas.delete('mouse-hint')

            y, x = event.y // WIDTH, event.x // WIDTH
            if y < 0 or y >= self.size or x < 0 or x > self.size or not reversi.good[
                    y][x]:  # assert reversi.next == who
                return

            yy, xx = y * WIDTH, x * WIDTH
            self.canvas.create_rectangle(xx,
                                         yy,
                                         xx + (WIDTH - 1),
                                         yy + (WIDTH - 1),
                                         fill='#A2C8AE',
                                         outline='',
                                         tag='mouse-hint')

        draw()  # 绘制初始棋局

        if ai == 1:  # AI 先手
            position = brain(reversi, ai)
            _ = reversi.place(position, ai)

            draw()
            print('AI place at {}, black: {}, white: {}'.format(
                (position[1], position[0]), reversi.number[1],
                reversi.number[2]))

        self.canvas.bind('<Motion>', hint)
        self.canvas.bind('<Button-1>', turn)

        self.window.mainloop()