Ejemplo n.º 1
0
 def test_window_init_screen(self):
     root = tk.Tk()
     b = ['Easy1', 'Normal1', 'Hard1']
     w = ['Easy2', 'Normal2', 'Hard2']
     window = Window(root=root, black_players=b, white_players=w)
     window.init_screen()
     # board
     self.assertEqual(window.board.size, reversi.window.DEFAULT_BOARD_SIZE)
     self.assertEqual(window.board.cputime, reversi.window.CPU_TIME)
     self.assertEqual(window.board.assist, reversi.window.ASSIST_MENU[1])
     self.assertEqual(window.board._squares,
                      [[None for _ in range(window.board.size)]
                       for _ in range(window.board.size)])
     self.assertEqual(window.board._xlines,
                      [6, 10, 14, 18, 22, 26, 30, 38, 40])
     self.assertEqual(window.board._ylines,
                      [4, 8, 12, 16, 20, 24, 28, 36, 39])
     self.assertEqual(window.board.move, None)
     self.assertEqual(window.board.event.is_set(), False)
     # info
     self.assertEqual(window.info.player, {'black': b[0], 'white': w[0]})
     self.assertEqual(window.info.language, reversi.window.LANGUAGE_MENU[0])
     # start
     self.assertEqual(window.start.language,
                      reversi.window.LANGUAGE_MENU[0])
     self.assertEqual(window.start.event.is_set(), False)
Ejemplo n.º 2
0
    def test_window_extradialog_select_extra_file(self):
        import os
        test_filetypes = None
        test_initialdir = None
        extra_file_ok = 'extra_file_ok'

        def test_askopenfilename_ok(filetypes, initialdir):
            nonlocal test_filetypes, test_initialdir, extra_file_ok
            test_filetypes = filetypes
            test_initialdir = initialdir
            return extra_file_ok

        def test_askopenfilename_ng(filetypes, initialdir):
            return False

        window = Window(root=tk.Tk(), black_players=['b'], white_players=['w'])
        extradialog = reversi.window.ExtraDialog(window, threading.Event(),
                                                 'Japanese')
        # OK
        extradialog.askopenfilename = test_askopenfilename_ok
        extradialog.button1.invoke()
        self.assertEqual(test_filetypes, [("", "*.json")])
        self.assertEqual(test_initialdir,
                         os.path.abspath(os.path.dirname('./extra/')))
        self.assertEqual(extradialog.extra_file.get(), extra_file_ok)
        # NG
        extradialog.askopenfilename = test_askopenfilename_ng
        extradialog.button1.invoke()
        self.assertEqual(extradialog.extra_file.get(), extra_file_ok)
        extradialog.dialog.destroy()
Ejemplo n.º 3
0
    def test_window_menu_set_state(self):
        window = Window(root=tk.Tk(), black_players=['b'], white_players=['w'])

        # initial
        expected = ['normal' for _ in window.menu.menu_items.keys()]
        result = []
        for name in window.menu.menu_items.keys():
            index = window.menu.index(name.title())
            result.append(window.menu.entrycget(index, 'state'))
        self.assertEqual(result, expected)

        # disable
        window.menu.set_state('disable')
        expected = ['disabled' for _ in window.menu.menu_items.keys()]
        expected[-1] = 'normal'
        result = []
        for name in window.menu.menu_items.keys():
            index = window.menu.index(name.title())
            result.append(window.menu.entrycget(index, 'state'))
        self.assertEqual(result, expected)

        # normal
        window.menu.set_state('normal')
        expected = ['normal' for _ in window.menu.menu_items.keys()]
        expected[-1] = 'disabled'
        result = []
        for name in window.menu.menu_items.keys():
            index = window.menu.index(name.title())
            result.append(window.menu.entrycget(index, 'state'))
        self.assertEqual(result, expected)
Ejemplo n.º 4
0
 def test_window_menu_create_menu_items(self):
     window = Window(root=tk.Tk(), black_players=['b'], white_players=['w'])
     for item in [
             'size', 'black', 'white', 'cputime', 'extra', 'assist',
             'language', 'cancel'
     ]:
         self.assertIsInstance(window.menu.menus[item], tk.Menu)
Ejemplo n.º 5
0
 def test_window_menu_init(self):
     root = tk.Tk()
     b = ['Easy1', 'Normal1', 'Hard1']
     w = ['Easy2', 'Normal2', 'Hard2']
     window = Window(root=root, black_players=b, white_players=w)
     self.assertIsInstance(window.menu.window, Window)
     self.assertEqual(window.menu.size, reversi.window.DEFAULT_BOARD_SIZE)
     self.assertEqual(window.menu.black_player, b[0])
     self.assertEqual(window.menu.white_player, w[0])
     self.assertEqual(window.menu.assist, reversi.window.ASSIST_MENU[1])
     self.assertEqual(window.menu.language, reversi.window.LANGUAGE_MENU[0])
     self.assertEqual(window.menu.cancel, reversi.window.CANCEL_MENU[0])
     self.assertIsNone(window.menu.cputimedialog)
     self.assertIsNone(window.menu.extradialog)
     self.assertIsInstance(window.menu.event, threading.Event)
     self.assertEqual(
         window.menu.menu_items['size'],
         range(reversi.board.MIN_BOARD_SIZE,
               reversi.board.MAX_BOARD_SIZE + 1, 2))
     self.assertEqual(window.menu.menu_items['black'], b)
     self.assertEqual(window.menu.menu_items['white'], w)
     self.assertEqual(window.menu.menu_items['cputime'],
                      reversi.window.CPUTIME_MENU)
     self.assertEqual(window.menu.menu_items['extra'],
                      reversi.window.EXTRA_MENU)
     self.assertEqual(window.menu.menu_items['assist'],
                      reversi.window.ASSIST_MENU)
     self.assertEqual(window.menu.menu_items['language'],
                      reversi.window.LANGUAGE_MENU)
     self.assertEqual(window.menu.menu_items['cancel'],
                      reversi.window.CANCEL_MENU)
Ejemplo n.º 6
0
 def test_window_extradialog_set_parameter(self):
     new_extra_file = 'new_extra_file'
     window = Window(root=tk.Tk(), black_players=['b'], white_players=['w'])
     extradialog = reversi.window.ExtraDialog(window, threading.Event(),
                                              'Japanese')
     extradialog.extra_file.set(new_extra_file)
     extradialog.button2.invoke()
     self.assertEqual(window.extra_file, new_extra_file)
     self.assertTrue(extradialog.event.is_set())
Ejemplo n.º 7
0
    def test_window_set_state(self):
        window = Window(root=tk.Tk(), black_players=['b'], white_players=['w'])
        window.init_screen()

        class TestState:
            def __init__(self):
                self.state = None

            def set_state(self, state):
                self.state = state

        window.start = TestState()
        window.menu = TestState()

        window.set_state('Normal')
        self.assertEqual(window.start.state, 'Normal')
        self.assertEqual(window.menu.state, 'Normal')

        window.set_state('Disable')
        self.assertEqual(window.start.state, 'Disable')
        self.assertEqual(window.menu.state, 'Disable')
Ejemplo n.º 8
0
    def __init__(self, players_info={}, turn_disc_wait=0.1, sleep_time_play=1.5, sleep_time_end=0.01, sleep_time_turn=0.3, sleep_time_move=0.3):
        root = tk.Tk()
        root.withdraw()  # 表示が整うまで隠す

        self.state = Reversi.INIT

        b = ['User1'] + list(players_info.keys())
        w = ['User2'] + list(players_info.keys())
        self.window = Window(root=root, black_players=b, white_players=w)

        players_info['User1'] = strategies.WindowUserInput(self.window)
        players_info['User2'] = strategies.WindowUserInput(self.window)
        self.players_info = players_info

        self.err_msg = ErrorMessage()

        # wait or sleep time (sec)
        self.turn_disc_wait = turn_disc_wait
        self.sleep_time_play = sleep_time_play
        self.sleep_time_end = sleep_time_end
        self.sleep_time_turn = sleep_time_turn
        self.sleep_time_move = sleep_time_move
Ejemplo n.º 9
0
 def test_window_cputimedialog_init(self):
     window = Window(root=tk.Tk(), black_players=['b'], white_players=['w'])
     event = 'event'
     language = 'Japanese'
     cputimedialog = reversi.window.CpuTimeDialog(window, event, language)
     self.assertEqual(cputimedialog.window, window)
     self.assertEqual(cputimedialog.event, event)
     self.assertEqual(cputimedialog.dialog.master, window.root)
     self.assertEqual(cputimedialog.parameter.get(), str(window.cputime))
     self.assertEqual(cputimedialog.label1['text'],
                      reversi.window.TEXTS[language]['CPU_WAIT_TEXT'])
     self.assertEqual(cputimedialog.entry['textvariable'],
                      str(cputimedialog.parameter))
     self.assertEqual(cputimedialog.label2['text'],
                      reversi.window.TEXTS[language]['CPU_SECOND_TEXT'])
     self.assertEqual(cputimedialog.button['text'],
                      reversi.window.TEXTS[language]['CPU_SETTING_TEXT'])
     cputimedialog.dialog.destroy()
Ejemplo n.º 10
0
 def test_window_extradialog_init(self):
     window = Window(root=tk.Tk(), black_players=['b'], white_players=['w'])
     event = 'event'
     language = 'Japanese'
     extradialog = reversi.window.ExtraDialog(window, event, language)
     self.assertEqual(extradialog.window, window)
     self.assertEqual(extradialog.event, event)
     self.assertEqual(extradialog.dialog.master, window.root)
     self.assertEqual(extradialog.extra_file.get(), str(window.extra_file))
     self.assertEqual(extradialog.label1['text'],
                      reversi.window.TEXTS[language]['EXTRA_PLAYER_TEXT'])
     self.assertEqual(extradialog.label2['text'],
                      reversi.window.TEXTS[language]['EXTRA_FILE_TEXT'])
     self.assertEqual(extradialog.entry['textvariable'],
                      str(extradialog.extra_file))
     self.assertEqual(extradialog.button1['text'],
                      reversi.window.TEXTS[language]['EXTRA_REF_TEXT'])
     self.assertEqual(extradialog.button2['text'],
                      reversi.window.TEXTS[language]['EXTRA_LOAD_TEXT'])
     extradialog.dialog.destroy()
Ejemplo n.º 11
0
 def test_window_cputimedialog_set_parameter(self):
     window = Window(root=tk.Tk(), black_players=['b'], white_players=['w'])
     cputimedialog = reversi.window.CpuTimeDialog(window, threading.Event(),
                                                  'Japanese')
     # NOT MATCH
     new_cputime = -1.0
     cputimedialog.parameter.set(new_cputime)
     cputimedialog.button.invoke()
     self.assertNotEqual(window.cputime, new_cputime)
     # IS ZERO
     new_cputime = 00.0
     cputimedialog.parameter.set(new_cputime)
     cputimedialog.button.invoke()
     self.assertNotEqual(window.cputime, new_cputime)
     # OK
     new_cputime = 1.0
     cputimedialog.parameter.set(new_cputime)
     cputimedialog.button.invoke()
     self.assertEqual(window.cputime, new_cputime)
     self.assertTrue(cputimedialog.event.is_set())
Ejemplo n.º 12
0
    def test_window_init(self):
        root = tk.Tk()
        b = ['Easy1', 'Normal1', 'Hard1']
        w = ['Easy2', 'Normal2', 'Hard2']
        window = Window(root=root, black_players=b, white_players=w)

        self.assertEqual(window.root, root)
        self.assertEqual(window.size, reversi.window.DEFAULT_BOARD_SIZE)
        self.assertEqual(window.player['black'], 'Easy1')
        self.assertEqual(window.player['white'], 'Easy2')
        self.assertEqual(window.assist, 'OFF')
        self.assertEqual(window.language, 'English')
        self.assertEqual(window.cancel, 'OK')
        self.assertEqual(window.cputime, reversi.window.CPU_TIME)
        self.assertEqual(window.extra_file, '')
        self.assertIsInstance(window.menu, reversi.window.Menu)
        self.assertIsInstance(window.canvas, tk.Canvas)
        self.assertEqual(window.canvas['width'],
                         str(reversi.window.WINDOW_WIDTH))
        self.assertEqual(window.canvas['height'],
                         str(reversi.window.WINDOW_HEIGHT))
        self.assertEqual(window.canvas['bg'],
                         str(reversi.window.COLOR_SLATEGRAY))
Ejemplo n.º 13
0
    def test_window_menu_command(self):
        root = tk.Tk()
        b = ['Easy1', 'Normal1', 'Hard1']
        w = ['Easy2', 'Normal2', 'Hard2']
        window = Window(root=root, black_players=b, white_players=w)

        # size
        test_size = 12
        command = window.menu._command('size', test_size)

        self.assertFalse(window.menu.event.is_set())
        self.assertEqual(window.menu.size, reversi.window.DEFAULT_BOARD_SIZE)

        command()

        self.assertTrue(window.menu.event.is_set())
        self.assertEqual(window.menu.size, test_size)
        window.menu.event.clear()

        # black
        test_black_player = 'Hard1'
        command = window.menu._command('black', test_black_player)

        self.assertFalse(window.menu.event.is_set())
        self.assertEqual(window.menu.black_player, b[0])

        command()

        self.assertTrue(window.menu.event.is_set())
        self.assertEqual(window.menu.black_player, test_black_player)
        window.menu.event.clear()

        # white
        test_white_player = 'Hard2'
        command = window.menu._command('white', test_white_player)

        self.assertFalse(window.menu.event.is_set())
        self.assertEqual(window.menu.white_player, w[0])

        command()

        self.assertTrue(window.menu.event.is_set())
        self.assertEqual(window.menu.white_player, test_white_player)
        window.menu.event.clear()

        # cputime
        command = window.menu._command('cputime', '')

        self.assertFalse(window.menu.event.is_set())

        command()

        self.assertTrue(window.menu.event.is_set())
        window.menu.event.clear()

        self.assertIsInstance(window.menu.cputimedialog,
                              reversi.window.CpuTimeDialog)
        window.menu.cputimedialog.dialog.destroy()

        # extra
        command = window.menu._command('extra', '')

        self.assertFalse(window.menu.event.is_set())

        command()

        self.assertTrue(window.menu.event.is_set())
        window.menu.event.clear()

        self.assertIsInstance(window.menu.extradialog,
                              reversi.window.ExtraDialog)
        window.menu.extradialog.dialog.destroy()

        # assist
        test_assist = 'ON'
        command = window.menu._command('assist', test_assist)

        self.assertFalse(window.menu.event.is_set())
        self.assertEqual(window.menu.assist, reversi.window.ASSIST_MENU[1])

        command()

        self.assertTrue(window.menu.event.is_set())
        self.assertEqual(window.menu.assist, test_assist)
        window.menu.event.clear()

        # language
        test_language = 'JAPANESE'
        command = window.menu._command('language', test_language)

        self.assertFalse(window.menu.event.is_set())
        self.assertEqual(window.menu.language, reversi.window.LANGUAGE_MENU[0])

        command()

        self.assertTrue(window.menu.event.is_set())
        self.assertEqual(window.menu.language, test_language)
        window.menu.event.clear()

        # cancel
        test_cancel = 'TEST_ON'
        command = window.menu._command('cancel', test_cancel)

        self.assertFalse(window.menu.event.is_set())
        self.assertEqual(window.menu.cancel, 'OK')

        command()

        self.assertTrue(window.menu.event.is_set())
        self.assertEqual(window.menu.cancel, test_cancel)
        window.menu.event.clear()
Ejemplo n.º 14
0
class Reversi:
    """
    リバーシゲーム
    """
    INIT, DEMO, PLAY, END, REINIT = 'INIT', 'DEMO', 'PLAY', 'END', 'REINIT'

    def __init__(self, players_info={}, turn_disc_wait=0.1, sleep_time_play=1.5, sleep_time_end=0.01, sleep_time_turn=0.3, sleep_time_move=0.3):
        root = tk.Tk()
        root.withdraw()  # 表示が整うまで隠す

        self.state = Reversi.INIT

        b = ['User1'] + list(players_info.keys())
        w = ['User2'] + list(players_info.keys())
        self.window = Window(root=root, black_players=b, white_players=w)

        players_info['User1'] = strategies.WindowUserInput(self.window)
        players_info['User2'] = strategies.WindowUserInput(self.window)
        self.players_info = players_info

        self.err_msg = ErrorMessage()

        # wait or sleep time (sec)
        self.turn_disc_wait = turn_disc_wait
        self.sleep_time_play = sleep_time_play
        self.sleep_time_end = sleep_time_end
        self.sleep_time_turn = sleep_time_turn
        self.sleep_time_move = sleep_time_move

    @property
    def state(self):
        return self._state

    @state.setter
    def state(self, state):
        self._state = state

        if state == Reversi.INIT:
            self.game = self.__init
        elif state == Reversi.DEMO:
            self.game = self.__demo
        elif state == Reversi.PLAY:
            self.game = self.__play
        elif state == Reversi.END:
            self.game = self.__end
        else:
            self.game = self.__reinit

    def gameloop(self):
        """
        ゲーム処理
        """
        while True:
            if self.game():
                break

    def start(self):
        """
        アプリ開始
        """
        self.game_start()    # ゲーム開始
        self.window_start()  # ウィンドウ開始

    def game_start(self):
        """
        ゲーム開始
        """
        game_thread = threading.Thread(target=self.gameloop)
        game_thread.daemon = True
        self._thread_start(game_thread)

    def _thread_start(self, thread):
        """
        スレッド開始
        """
        thread.start()

    def window_start(self):
        """
        ウィンドウ開始
        """
        self.window.root.deiconify()  # 表示する
        self.window.root.mainloop()

    def __init(self):
        """
        画面初期化(初回、設定変更時)
        """
        self.window.init_screen()
        self.window.set_state('normal')

        # メニューで登録ファイルが読み込まれた場合
        if self.window.extra_file:
            extra_file = self.window.extra_file
            self.window.extra_file = ""
            self._load_extra_file(extra_file)

        self.state = Reversi.DEMO

    def _load_extra_file(self, extra_file):
        """
        登録ファイルを読み込む
        """
        if os.path.isfile(extra_file):
            with open(extra_file, 'r') as f:
                name, cmd, timeouttime = None, None, None
                try:
                    # 設定の読み出し
                    json_dict = json.load(f)
                    name = json_dict['name']
                    cmd = json_dict['cmd']
                    timeouttime = json_dict['timeouttime']

                except Exception:
                    self.err_msg.show('フォーマットエラーのため登録ファイルが読み込めませんでした')

                else:
                    # メニューにAIの名前を追加
                    for color in ('black', 'white'):
                        if name not in self.window.menu.menu_items[color]:
                            self.window.menu.menu_items[color].append(name)
                            self.window.menu.menus[color].add_command(label=str(name), command=self.window.menu._command(color, name))

                    # 戦略を追加
                    self.players_info[name] = strategies.External(cmd, timeouttime)

        else:
            self.err_msg.show('指定された登録ファイルが見つかりませんでした')

    def __demo(self):
        """
        デモ画面
        """
        while True:
            if self.window.start.event.is_set():
                self.window.start.event.clear()
                self.state = Reversi.PLAY
                break

            if not self._demo_animation():
                self.state = Reversi.INIT
                break

    def _demo_animation(self):
        """
        デモアニメーション継続中
        """
        center = self.window.board.size // 2

        target = [
            ('black', center, center-1),
            ('black', center-1, center),
            ('white', center-1, center-1),
            ('white', center, center),
        ]

        ptn = {
            'black': [
                ('black', 'turnblack'),
                ('turnblack', 'white'),
                ('white', 'turnwhite'),
                ('turnwhite', 'black'),
            ],
            'white': [
                ('white', 'turnwhite'),
                ('turnwhite', 'black'),
                ('black', 'turnblack'),
                ('turnblack', 'white'),
            ],
        }

        for color, x, y in target:
            for remove_color, put_color in ptn[color]:
                # メニュー設定変更時
                if self._setting_changed():
                    return False

                # アニメーション処理
                time.sleep(self.turn_disc_wait)
                self.window.board.remove_disc(remove_color, x, y)
                self.window.board.put_disc(put_color, x, y)

        return True

    def __play(self):
        """
        ゲーム画面
        """
        self.window.set_state('disable')

        board = BitBoard(self.window.board.size)
        players = {}

        for color in ('black', 'white'):
            name = self.window.player[color]
            players[color] = Player(color, name, self.players_info[name])

        # ウィンドウの設定をゲームに反映
        strategies.common.Timer.time_limit = self.window.cputime

        Game(
            players['black'],
            players['white'],
            board,
            WindowDisplay(self.window, sleep_time_turn=self.sleep_time_turn, sleep_time_move=self.sleep_time_move),
            cancel=self.window.menu,
        ).play()

        time.sleep(self.sleep_time_play)  # 少し待って終了状態へ
        self.state = Reversi.END

    def __end(self):
        """
        終了画面
        """
        self.window.set_state('normal')

        while True:
            time.sleep(self.sleep_time_end)

            if self.window.start.event.is_set():
                self.window.start.event.clear()
                self.state = Reversi.REINIT
                break

            if self._setting_changed():
                self.state = Reversi.INIT
                break

    def __reinit(self):
        """
        再初期化(ゲーム終了後再スタート時)
        """
        self.window.init_screen()
        self.state = Reversi.PLAY

    def _setting_changed(self):
        """
        ウィンドウの設定が変更されたとき
        """
        if self.window.menu.event.is_set():
            self.window.size = self.window.menu.size
            self.window.player['black'] = self.window.menu.black_player
            self.window.player['white'] = self.window.menu.white_player
            self.window.assist = self.window.menu.assist
            self.window.language = self.window.menu.language
            self.window.menu.event.clear()

            return True

        return False