Example #1
0
class TestTurnKanFlow(unittest.TestCase):
    def setUp(self):
        self.player_1 = Player('player 1', 0)
        self.player_2 = Player('player 2', 1)
        self.player_3 = Player('player 3', 2)
        self.player_4 = Player('player 4', 3)
        self.players = [
            self.player_1, self.player_2, self.player_3, self.player_4
        ]
        self.tile_stack = Stack()
        self.logger = KyokuLogger()

        for player in self.players:
            for i in range(13):
                player.hand[self.tile_stack.draw().index] += 1

        self.turn = Turn(self.players, self.tile_stack, Jihai.TON, self.logger)

    def test_kan_flow_no_act(self):
        kan_player = self.player_1
        kan_tile = Tile(0, 1)
        kan_type = Naki.CHAKAN
        self.player_2.action_with_chakan = MagicMock(return_value=Action.NOACT)
        self.player_3.action_with_chakan = MagicMock(return_value=Action.NOACT)
        self.player_4.action_with_chakan = MagicMock(return_value=Action.NOACT)

        state = self.turn.kan_flow(kan_player, kan_tile, kan_type)
        self.assertEqual(state, 0)

    def test_kan_flow_chakan(self):
        kan_player = self.player_1
        kan_tile = Tile(0, 1)
        kan_type = Naki.CHAKAN
        self.player_2.action_with_chakan = MagicMock(return_value=Action.RON)
        self.player_3.action_with_chakan = MagicMock(return_value=Action.NOACT)
        self.player_4.action_with_chakan = MagicMock(return_value=Action.RON)

        state, t, pos, act = self.turn.kan_flow(kan_player, kan_tile, kan_type)
        self.assertEqual(state, 1)
        self.assertEqual(self.turn.winners_pos, [1, 3])
Example #2
0
class TestTurnDiscardFlow(unittest.TestCase):
    def setUp(self):
        self.player_1 = Player('player 1', 0)
        self.player_2 = Player('player 2', 1)
        self.player_3 = Player('player 3', 2)
        self.player_4 = Player('player 4', 3)
        self.players = [
            self.player_1, self.player_2, self.player_3, self.player_4
        ]
        self.tile_stack = Stack()
        self.logger = KyokuLogger()

        for player in self.players:
            for i in range(13):
                player.hand[self.tile_stack.draw().index] += 1

        self.turn = Turn(self.players, self.tile_stack, Jihai.TON, self.logger)

    def test_all_noact(self):
        self.turn.ensemble_actions = MagicMock(return_value=(2, (Action.NOACT,
                                                                 Naki.NONE)))
        self.turn.draw_flow = MagicMock(return_value=(0, Tile(0, 1), 0,
                                                      Action.NOACT))
        state, discard_tile, discard_pos, act = self.turn.discard_flow(
            Tile(0, 2), self.player_1.seating_position)
        self.assertEqual(state, 0)
        self.assertEqual(discard_tile, Tile(0, 1))
        self.assertEqual(discard_pos, 0)

    def test_all_noact_then_tsumo(self):
        self.turn.ensemble_actions = MagicMock(return_value=(2, (Action.NOACT,
                                                                 Naki.NONE)))
        self.turn.draw_flow = MagicMock(return_value=(1, None, None,
                                                      Action.TSUMO))
        state, discard_tile, discard_pos, act = self.turn.discard_flow(
            Tile(0, 2), self.player_1.seating_position)
        self.assertEqual(state, 1)
        self.assertEqual(discard_tile, None)
        self.assertEqual(discard_pos, None)

    def test_call_naki(self):
        self.turn.ensemble_actions = MagicMock(return_value=(2, (Action.NAKI,
                                                                 Naki.CHII)))
        self.turn.naki_flow = MagicMock(return_value=(0, Tile(0, 1), 2,
                                                      Action.NAKI))
        state, discard_tile, discard_pos, act = self.turn.discard_flow(
            Tile(1, 1), self.player_1.seating_position)
        self.assertEqual(state, 0)
        self.assertEqual(discard_tile, Tile(0, 1))
        self.assertEqual(discard_pos, 2)

    def test_ron(self):
        self.turn.ensemble_actions = MagicMock(return_value=(2, (Action.RON,
                                                                 Naki.NONE)))
        state, discard_tile, discard_pos, act = self.turn.discard_flow(
            Tile(1, 1), self.player_1.seating_position)
        self.assertEqual(state, 1)
        self.assertEqual(discard_tile, None)
        self.assertEqual(discard_pos, 0)

    def test_normal_ryuukyoku(self):
        self.tile_stack.playing_wall = self.tile_stack.playing_wall[-1:]
        self.player_1.action_with_new_tile = MagicMock(
            return_value=((Action.NOACT, Naki.NONE), Tile(0, 1)))
        _, action_tile, discard_pos, _ = self.turn.draw_flow(self.player_1)
        self.assertEqual(self.turn.discard_flow(action_tile, discard_pos),
                         (-1, action_tile, discard_pos, Action.NOACT))
Example #3
0
class TestTurnNakiFlow(unittest.TestCase):
    def setUp(self):
        self.player_1 = Player('player 1', 0)
        self.player_2 = Player('player 2', 1)
        self.player_3 = Player('player 3', 2)
        self.player_4 = Player('player 4', 3)
        self.players = [
            self.player_1, self.player_2, self.player_3, self.player_4
        ]
        self.tile_stack = Stack()
        self.logger = KyokuLogger()
        for player in self.players:
            for i in range(13):
                player.hand[self.tile_stack.draw().index] += 1

        self.turn = Turn(self.players, self.tile_stack, Jihai.TON, self.logger)

    def test_daminkan(self):
        self.player_1.action_with_naki = MagicMock(return_value=None)
        self.turn.draw_flow = MagicMock(return_value=(0, Tile(0, 1), 0,
                                                      Action.NAKI))
        state, discard_tile, discard_pos, act = self.turn.naki_flow(
            self.player_1, Naki.DAMINKAN)
        self.assertEqual(state, 0)
        self.assertEqual(discard_tile, Tile(0, 1))
        self.assertEqual(discard_pos, 0)
        self.assertEqual(len(self.tile_stack.doras), 2)

    def test_suukaikan(self):
        for _ in range(3):
            self.tile_stack.add_dora_indicator()
        self.player_1.action_with_naki = MagicMock(return_value=None)
        self.turn.draw_flow = MagicMock(return_value=(0, Tile(0, 1), 0,
                                                      Action.NOACT))
        state, discard_tile, pos, act = self.turn.naki_flow(
            self.player_1, Naki.DAMINKAN)

        self.assertEqual(state, 0)
        self.assertEqual(discard_tile, Tile(0, 1))
        self.assertEqual(self.turn.suukaikan, True)
        self.assertEqual(len(self.tile_stack.doras), 5)

    def test_suukantsu(self):
        for _ in range(3):
            self.tile_stack.add_dora_indicator()
        naki_tile_1 = Tile(Suit.SOUZU.value, 5)
        naki_tile_1.owner = self.player_1.seating_position
        naki_tile_2 = Tile(Suit.SOUZU.value, 6)
        naki_tile_2.owner = self.player_1.seating_position
        naki_tile_3 = Tile(Suit.SOUZU.value, 7)
        naki_tile_3.owner = self.player_1.seating_position
        naki_tile_4 = Tile(Suit.SOUZU.value, 8)
        naki_tile_4.owner = self.player_1.seating_position
        kan_1 = Huro(Naki.ANKAN, naki_tile_1,
                     [Tile(Suit.SOUZU.value, 5) for i in range(4)])
        kan_2 = Huro(Naki.ANKAN, naki_tile_2,
                     [Tile(Suit.SOUZU.value, 6) for i in range(4)])
        kan_3 = Huro(Naki.ANKAN, naki_tile_3,
                     [Tile(Suit.SOUZU.value, 7) for i in range(4)])
        kan_4 = Huro(Naki.ANKAN, naki_tile_4,
                     [Tile(Suit.SOUZU.value, 8) for i in range(4)])
        self.player_1.kabe.append(kan_1)
        self.player_1.kabe.append(kan_2)
        self.player_1.kabe.append(kan_3)
        self.player_1.action_with_naki = MagicMock(
            self.player_1.kabe.append(kan_4))
        self.turn.draw_flow = MagicMock(return_value=(0, Tile(0, 1), 0,
                                                      Action.NAKI))
        state, discard_tile, discard_pos, act = self.turn.naki_flow(
            self.player_1, Naki.DAMINKAN)
        self.assertEqual(state, 0)
        self.assertEqual(discard_tile, Tile(0, 1))
        self.assertEqual(discard_pos, 0)
        self.assertEqual(len(self.tile_stack.doras), 5)

    def test_chii(self):
        self.player_1.action_with_naki = MagicMock(return_value=None)
        self.player_1.discard_after_naki = MagicMock(return_value=Tile(0, 1))
        state, discard_tile, discard_pos, act = self.turn.naki_flow(
            self.player_1, Naki.CHII)
        self.assertEqual(state, 0)
        self.assertEqual(discard_tile, Tile(0, 1))
        self.assertEqual(discard_pos, 0)
Example #4
0
class TestTurnEnsembleActions(unittest.TestCase):
    def setUp(self):
        self.player_1 = Player('player 1', 0)
        self.player_2 = Player('player 2', 1)
        self.player_3 = Player('player 3', 2)
        self.player_4 = Player('player 4', 3)
        self.players = [
            self.player_1, self.player_2, self.player_3, self.player_4
        ]
        self.tile_stack = Stack()
        self.logger = KyokuLogger()
        for player in self.players:
            for i in range(13):
                player.hand[self.tile_stack.draw().index] += 1

        self.turn = Turn(self.players, self.tile_stack, Jihai.TON, self.logger)

    def test_all_noact(self):
        discard_player = self.player_1
        discard_tile = Tile(0, 1)
        self.player_2.action_with_discard_tile = MagicMock(
            return_value=(Action.NOACT, Naki.NONE))
        self.player_3.action_with_discard_tile = MagicMock(
            return_value=(Action.NOACT, Naki.NONE))
        self.player_4.action_with_discard_tile = MagicMock(
            return_value=(Action.NOACT, Naki.NONE))
        pos, (action, naki) = self.turn.ensemble_actions(
            discard_tile, discard_player.seating_position)
        self.assertEqual(pos, 1)
        self.assertEqual(action, Action.NOACT)
        self.assertEqual(naki, Naki.NONE)

    def test_shimocha_chii(self):
        discard_player = self.player_1
        discard_tile = Tile(0, 1)
        self.player_2.action_with_discard_tile = MagicMock(
            return_value=(Action.NAKI, Naki.CHII))
        self.player_3.action_with_discard_tile = MagicMock(
            return_value=(Action.NOACT, Naki.NONE))
        self.player_4.action_with_discard_tile = MagicMock(
            return_value=(Action.NOACT, Naki.NONE))
        pos, (action, naki) = self.turn.ensemble_actions(
            discard_tile, discard_player.seating_position)
        self.assertEqual(pos, 1)
        self.assertEqual(action, Action.NAKI)
        self.assertEqual(naki, Naki.CHII)

    def test_toimen_pon(self):
        discard_player = self.player_1
        discard_tile = Tile(0, 1)
        self.player_2.action_with_discard_tile = MagicMock(
            return_value=(Action.NAKI, Naki.CHII))
        self.player_3.action_with_discard_tile = MagicMock(
            return_value=(Action.NAKI, Naki.PON))
        self.player_4.action_with_discard_tile = MagicMock(
            return_value=(Action.NOACT, Naki.NONE))
        pos, (action, naki) = self.turn.ensemble_actions(
            discard_tile, discard_player.seating_position)
        self.assertEqual(pos, 2)
        self.assertEqual(action, Action.NAKI)
        self.assertEqual(naki, Naki.PON)

    def test_kamicha_pon(self):
        discard_player = self.player_1
        discard_tile = Tile(0, 1)
        self.player_2.action_with_discard_tile = MagicMock(
            return_value=(Action.NOACT, Naki.NONE))
        self.player_3.action_with_discard_tile = MagicMock(
            return_value=(Action.NOACT, Naki.NONE))
        self.player_4.action_with_discard_tile = MagicMock(
            return_value=(Action.NAKI, Naki.PON))
        pos, (action, naki) = self.turn.ensemble_actions(
            discard_tile, discard_player.seating_position)
        self.assertEqual(pos, 3)
        self.assertEqual(action, Action.NAKI)
        self.assertEqual(naki, Naki.PON)

    def test_shimocha_ron(self):
        discard_player = self.player_1
        discard_tile = Tile(0, 1)
        self.player_2.action_with_discard_tile = MagicMock(
            return_value=(Action.RON, Naki.NONE))
        self.player_3.action_with_discard_tile = MagicMock(
            return_value=(Action.NOACT, Naki.NONE))
        self.player_4.action_with_discard_tile = MagicMock(
            return_value=(Action.NOACT, Naki.DAMINKAN))
        pos, (action, naki) = self.turn.ensemble_actions(
            discard_tile, discard_player.seating_position)
        self.assertEqual(pos, 1)
        self.assertEqual(action, Action.RON)
        self.assertEqual(naki, Naki.NONE)

    def test_kamicha_ron(self):
        discard_player = self.player_1
        discard_tile = Tile(0, 1)
        self.player_2.action_with_discard_tile = MagicMock(
            return_value=(Action.NAKI, Naki.CHII))
        self.player_3.action_with_discard_tile = MagicMock(
            return_value=(Action.NAKI, Naki.PON))
        self.player_4.action_with_discard_tile = MagicMock(
            return_value=(Action.RON, Naki.NONE))
        pos, (action, naki) = self.turn.ensemble_actions(
            discard_tile, discard_player.seating_position)
        self.assertEqual(pos, 3)
        self.assertEqual(action, Action.RON)
        self.assertEqual(naki, Naki.NONE)

    def test_multiple_winners(self):
        discard_player = self.player_1
        discard_tile = Tile(0, 1)
        self.turn.atamahane = False
        self.player_2.action_with_discard_tile = MagicMock(
            return_value=(Action.NOACT, Naki.NONE))
        self.player_3.action_with_discard_tile = MagicMock(
            return_value=(Action.RON, Naki.NONE))
        self.player_4.action_with_discard_tile = MagicMock(
            return_value=(Action.RON, Naki.NONE))

        pos, (action, naki) = self.turn.ensemble_actions(
            discard_tile, discard_player.seating_position)
        self.assertEqual(pos, 2)
        self.assertEqual(action, Action.RON)
        self.assertEqual(naki, Naki.NONE)
        self.assertEqual(self.turn.winners_pos, [2, 3])
Example #5
0
class TestTurnDrawFlow(unittest.TestCase):
    def setUp(self):
        self.player_1 = Player('player 1', 0)
        self.player_2 = Player('player 2', 1)
        self.player_3 = Player('player 3', 2)
        self.player_4 = Player('player 4', 3)
        self.players = [
            self.player_1, self.player_2, self.player_3, self.player_4
        ]
        self.tile_stack = Stack()
        self.logger = KyokuLogger()
        for player in self.players:
            for i in range(13):
                player.hand[self.tile_stack.draw().index] += 1

        self.turn = Turn(self.players, self.tile_stack, Jihai.TON, self.logger)

    def test_riichi(self):
        self.player_1.action_with_new_tile = MagicMock(
            return_value=((Action.RIICHI, Naki.NONE), None))
        self.assertEqual(self.turn.draw_flow(self.player_1),
                         (0, None, 0, Action.RIICHI))

    def test_tsumo(self):
        self.player_1.action_with_new_tile = MagicMock(
            return_value=((Action.TSUMO, Naki.NONE), None))
        self.assertEqual(self.turn.draw_flow(self.player_1),
                         (1, None, None, Action.TSUMO))

    def test_ankan(self):
        naki_tile = Tile(Suit.SOUZU.value, 5)
        naki_tile.owner = self.player_1.seating_position
        kan = Huro(Naki.ANKAN, naki_tile,
                   [Tile(Suit.SOUZU.value, 5) for i in range(4)])

        self.player_1.tmp_huro = kan

        self.player_1.action_with_new_tile = MagicMock()
        self.player_1.action_with_new_tile.side_effect = [
            ((Action.NAKI, Naki.CHAKAN), None),
            ((Action.NOACT, Naki.NONE), Tile(0, 1))
        ]
        self.turn.kan_flow = MagicMock(return_value=0)

        state, discard_tile, discard_pos, act = self.turn.draw_flow(
            self.player_1)
        self.assertEqual(state, 0)
        self.assertEqual(discard_tile, Tile(0, 1))
        self.assertEqual(discard_pos, 0)
        self.assertEqual(self.player_1.kawa[0], Tile(0, 1))
        self.assertEqual(len(self.tile_stack.doras), 2)

    def test_chakan(self):
        # change type from PON to KAN, what's tmp_huro in this case?
        naki_tile = Tile(Suit.SOUZU.value, 5)
        naki_tile.owner = self.player_1.seating_position
        kan = Huro(Naki.ANKAN, naki_tile,
                   [Tile(Suit.SOUZU.value, 5) for i in range(4)])

        self.player_1.tmp_huro = kan

        self.player_1.action_with_new_tile = MagicMock()
        self.player_1.action_with_new_tile.side_effect = [
            ((Action.NAKI, Naki.CHAKAN), None),
            ((Action.NOACT, Naki.NONE), Tile(0, 1))
        ]
        self.turn.kan_flow = MagicMock(return_value=0)
        state, discard_tile, discard_pos, act = self.turn.draw_flow(
            self.player_1)
        self.assertEqual(state, 0)
        self.assertEqual(discard_tile, Tile(0, 1))
        self.assertEqual(discard_pos, 0)
        self.assertEqual(self.player_1.kawa[0], Tile(0, 1))
        self.assertEqual(len(self.tile_stack.doras), 2)

    def test_chakan_chankan(self):
        naki_tile = Tile(Suit.SOUZU.value, 5)
        naki_tile.owner = self.player_1.seating_position
        kan = Huro(Naki.ANKAN, naki_tile,
                   [Tile(Suit.SOUZU.value, 5) for i in range(4)])

        self.player_1.tmp_huro = kan

        self.player_1.action_with_new_tile = MagicMock()
        self.player_1.action_with_new_tile.side_effect = [
            ((Action.NAKI, Naki.CHAKAN), None),
            ((Action.NOACT, Naki.NONE), Tile(0, 1))
        ]
        self.turn.kan_flow = MagicMock(return_value=1)
        state, discard_tile, discard_pos = self.turn.draw_flow(self.player_1)
        self.assertEqual(state, 1)
        self.assertEqual(discard_tile, None)
        self.assertEqual(discard_pos, None)

    def test_ankan_twice(self):
        naki_tile_1 = Tile(Suit.SOUZU.value, 5)
        naki_tile_1.owner = self.player_1.seating_position
        naki_tile_2 = Tile(Suit.SOUZU.value, 6)
        naki_tile_2.owner = self.player_1.seating_position
        kan_1 = Huro(Naki.ANKAN, naki_tile_1,
                     [Tile(Suit.SOUZU.value, 5) for i in range(4)])
        kan_2 = Huro(Naki.ANKAN, naki_tile_2,
                     [Tile(Suit.SOUZU.value, 6) for i in range(4)])

        self.player_1 = Mock()
        self.player_1.seating_position = 0
        self.player_1.get_shimocha = lambda: 1 % 4
        self.player_1.hand = defaultdict(int)
        self.player_1.kawa = []
        self.player_1.add_kawa = lambda tile: self.player_1.kawa.append(tile)
        p = PropertyMock(side_effect=[kan_1, kan_2])
        type(self.player_1).tmp_huro = p

        self.player_1.action_with_new_tile = MagicMock()
        self.player_1.action_with_new_tile.side_effect = [
            ((Action.NAKI, Naki.ANKAN), None),
            ((Action.NAKI, Naki.ANKAN), None),
            ((Action.NOACT, Naki.NONE), Tile(0, 1))
        ]
        state, discard_tile, discard_pos, act = self.turn.draw_flow(
            self.player_1)
        self.assertEqual(state, 0)
        self.assertEqual(discard_tile, Tile(0, 1))
        self.assertEqual(discard_pos, 0)
        self.assertEqual(self.player_1.kawa[0], Tile(0, 1))
        self.assertEqual(len(self.tile_stack.doras), 3)

    def test_draw_flow_suukaikan(self):
        # is declared when four quads are formed by different players.
        for _ in range(3):
            self.tile_stack.add_dora_indicator()
        naki_tile = Tile(Suit.SOUZU.value, 5)
        naki_tile.owner = self.player_1.seating_position

        kan = Huro(Naki.ANKAN, naki_tile,
                   [Tile(Suit.SOUZU.value, 5) for i in range(4)])
        self.player_1.action_with_new_tile = MagicMock()
        self.player_1.action_with_new_tile.side_effect = [
            ((Action.NAKI, Naki.ANKAN), None),
            ((Action.NOACT, Naki.NONE), Tile(0, 1))
        ]
        self.player_1.action_with_naki = MagicMock(
            self.player_1.kabe.append(kan))
        state, discard_tile, discard_pos, _ = self.turn.draw_flow(
            self.player_1)
        self.assertEqual(state, 0)
        self.assertEqual(discard_tile, Tile(0, 1))
        self.assertEqual(discard_pos, self.player_1.seating_position)
        self.assertEqual(len(self.tile_stack.doras), 5)
        self.assertEqual(self.turn.suukaikan, True)

    def test_draw_flow_suukantsu(self):
        for _ in range(3):
            self.tile_stack.add_dora_indicator()
        naki_tile_1 = Tile(Suit.SOUZU.value, 5)
        naki_tile_1.owner = self.player_1.seating_position
        naki_tile_2 = Tile(Suit.SOUZU.value, 6)
        naki_tile_2.owner = self.player_1.seating_position
        naki_tile_3 = Tile(Suit.SOUZU.value, 7)
        naki_tile_3.owner = self.player_1.seating_position
        naki_tile_4 = Tile(Suit.SOUZU.value, 8)
        naki_tile_4.owner = self.player_1.seating_position
        kan_1 = Huro(Naki.ANKAN, naki_tile_1,
                     [Tile(Suit.SOUZU.value, 5) for i in range(4)])
        kan_2 = Huro(Naki.ANKAN, naki_tile_2,
                     [Tile(Suit.SOUZU.value, 6) for i in range(4)])
        kan_3 = Huro(Naki.ANKAN, naki_tile_3,
                     [Tile(Suit.SOUZU.value, 7) for i in range(4)])
        kan_4 = Huro(Naki.ANKAN, naki_tile_4,
                     [Tile(Suit.SOUZU.value, 8) for i in range(4)])
        self.player_1.kabe.append(kan_1)
        self.player_1.kabe.append(kan_2)
        self.player_1.kabe.append(kan_3)
        self.player_1.action_with_new_tile = MagicMock()
        self.player_1.action_with_new_tile.side_effect = [
            ((Action.NAKI, Naki.ANKAN), None),
            ((Action.NOACT, Naki.NONE), Tile(0, 1))
        ]
        self.player_1.action_with_naki = MagicMock()

        def m(_):
            self.player_1.kabe.append(kan_4)

        self.player_1.action_with_naki.side_effect = m
        state, discard_tile, discard_pos, act = self.turn.draw_flow(
            self.player_1)
        self.assertEqual(state, 0)
        self.assertEqual(discard_tile, Tile(0, 1))
        self.assertEqual(discard_pos, 0)
        self.assertEqual(len(self.tile_stack.doras), 5)

    def test_suukantsu_other_player(self):
        for _ in range(3):
            self.tile_stack.add_dora_indicator()
        naki_tile = Tile(Suit.SOUZU.value, 5)
        naki_tile.owner = self.player_1.seating_position
        kan = Huro(Naki.DAMINKAN, naki_tile,
                   [Tile(Suit.SOUZU.value, 5) for i in range(4)])
        kabe = [kan]
        self.turn.check_suukaikan(kabe)
        self.assertEqual(len(self.tile_stack.doras), 5)
        self.assertEqual(self.turn.suukaikan, True)

    def test_suukaikan(self):
        for _ in range(3):
            self.tile_stack.add_dora_indicator()
        naki_tile = Tile(Suit.SOUZU.value, 5)
        naki_tile.owner = self.player_1.seating_position
        kan = Huro(Naki.DAMINKAN, naki_tile,
                   [Tile(Suit.SOUZU.value, 5) for i in range(4)])
        kabe = [kan]
        self.turn.check_suukaikan(kabe)
        self.assertEqual(len(self.tile_stack.doras), 5)
        self.assertEqual(self.turn.suukaikan, True)

    def test_suukantsu(self):
        for _ in range(3):
            self.tile_stack.add_dora_indicator()
        naki_tile_1 = Tile(Suit.SOUZU.value, 5)
        naki_tile_1.owner = self.player_1.seating_position
        naki_tile_2 = Tile(Suit.SOUZU.value, 6)
        naki_tile_2.owner = self.player_1.seating_position
        naki_tile_3 = Tile(Suit.SOUZU.value, 7)
        naki_tile_3.owner = self.player_1.seating_position
        naki_tile_4 = Tile(Suit.SOUZU.value, 8)
        naki_tile_4.owner = self.player_1.seating_position
        kan_1 = Huro(Naki.ANKAN, naki_tile_1,
                     [Tile(Suit.SOUZU.value, 5) for i in range(4)])
        kan_2 = Huro(Naki.ANKAN, naki_tile_2,
                     [Tile(Suit.SOUZU.value, 6) for i in range(4)])
        kan_3 = Huro(Naki.ANKAN, naki_tile_3,
                     [Tile(Suit.SOUZU.value, 7) for i in range(4)])
        kan_4 = Huro(Naki.ANKAN, naki_tile_4,
                     [Tile(Suit.SOUZU.value, 8) for i in range(4)])
        kabe = [kan_1, kan_2, kan_3, kan_4]
        self.turn.check_suukaikan(kabe)
        self.assertEqual(len(self.tile_stack.doras), 5)
        self.assertEqual(self.turn.suukaikan, False)

    def test_no_suukaikan(self):
        self.tile_stack.add_dora_indicator()
        naki_tile = Tile(Suit.SOUZU.value, 5)
        naki_tile.owner = self.player_1.seating_position
        kan = Huro(Naki.ANKAN, naki_tile,
                   [Tile(Suit.SOUZU.value, 5) for i in range(4)])
        kabe = [kan]
        self.turn.check_suukaikan(kabe)
        self.assertEqual(self.turn.suukaikan, False)

    def test_rinshan_kaihou(self):
        naki_tile = Tile(Suit.SOUZU.value, 5)
        naki_tile.owner = self.player_1.seating_position
        kan = Huro(Naki.ANKAN, naki_tile,
                   [Tile(Suit.SOUZU.value, 5) for i in range(4)])

        self.player_1.tmp_huro = kan
        self.player_1.action_with_new_tile = MagicMock()
        self.player_1.action_with_new_tile.side_effect = [
            ((Action.NAKI, Naki.ANKAN), None),
            ((Action.TSUMO, Naki.NONE), None)
        ]
        state, discard_tile, discard_pos, act = self.turn.draw_flow(
            self.player_1)
        self.assertEqual(state, 1)
        self.assertEqual(discard_tile, None)
        self.assertEqual(discard_pos, None)

    def test_suufon_renda(self):
        tile_ton = Tile(Suit.JIHAI.value, Jihai.TON.value)
        self.player_1.add_kawa(tile_ton)
        self.player_2.add_kawa(tile_ton)
        self.player_3.add_kawa(tile_ton)
        self.player_4.add_kawa(tile_ton)

        self.assertEqual(self.turn.check_suufon_renda(), True)

    def test_suufon_renda_counter_example(self):
        tile_ton = Tile(Suit.JIHAI.value, Jihai.TON.value)
        tile_nan = Tile(Suit.JIHAI.value, Jihai.NAN.value)
        self.player_1.add_kawa(tile_nan)
        self.player_2.add_kawa(tile_ton)
        self.player_3.add_kawa(tile_ton)
        self.player_4.add_kawa(tile_ton)

        self.assertEqual(self.turn.check_suufon_renda(), False)
Example #6
0
class TestActionLog(unittest.TestCase):
    def setUp(self):
        self.player_1 = Player('player 1', 0)
        self.player_2 = Player('player 2', 1)
        self.player_3 = Player('player 3', 2)
        self.player_4 = Player('player 4', 3)
        self.players = [
            self.player_1, self.player_2, self.player_3, self.player_4
        ]
        self.tile_stack = Stack()
        for player in self.players:
            for i in range(13):
                player.hand[self.tile_stack.draw().index] += 1

    def test_log_naki(self):
        naki_tile = Tile(Suit.SOUZU.value, 5)
        kan = Huro(Naki.ANKAN, naki_tile,
                   [Tile(Suit.SOUZU.value, 5) for i in range(4)])
        logger = KyokuLogger()
        logger.log(
            p_pos=self.player_1.seating_position,
            action=Action.NAKI,
            action_tile=naki_tile,
            naki_type=Naki.ANKAN,
            huro=kan,
        )
        log = logger.logs[0]
        self.assertEqual(log.p_pos, 0)
        self.assertEqual(log.action, Action.NAKI)
        self.assertEqual(log.action_tile, naki_tile)
        self.assertEqual(log.naki_type, Naki.ANKAN)
        self.assertEqual(
            str(log),
            "Player 0 NAKI ANKAN with 5 SOUZU forms "
            "5 SOUZU|5 SOUZU|5 SOUZU|5 SOUZU",
        )

    def test_log_draw(self):
        drown_tile = Tile(Suit.SOUZU.value, 5)
        logger = KyokuLogger()
        logger.log(
            p_pos=self.player_1.seating_position,
            action=Action.DRAW,
            action_tile=drown_tile,
        )
        log = logger.logs[0]
        self.assertEqual(log.p_pos, 0)
        self.assertEqual(log.action, Action.DRAW)
        self.assertEqual(log.action_tile, drown_tile)
        self.assertEqual(
            str(log),
            "Player 0 DRAW with 5 SOUZU",
        )

    def test_log_draw_from_rinshan(self):
        drown_tile = Tile(Suit.MANZU.value, 5)
        logger = KyokuLogger()
        # from linshan
        logger.log(
            p_pos=self.player_2.seating_position,
            action=Action.DRAW_RINSHAN,
            action_tile=drown_tile,
        )
        log = logger.logs[0]
        self.assertEqual(log.p_pos, 1)
        self.assertEqual(log.action, Action.DRAW_RINSHAN)
        self.assertEqual(log.action_tile, drown_tile)
        self.assertEqual(
            str(log),
            "Player 1 DRAW_RINSHAN with 5 MANZU",
        )

    def test_discard(self):
        discard_tile = Tile(Suit.MANZU.value, 5)
        logger = KyokuLogger()
        # from linshan
        logger.log(
            p_pos=self.player_2.seating_position,
            action=Action.DISCARD,
            action_tile=discard_tile,
        )
        log = logger.logs[0]
        self.assertEqual(log.p_pos, 1)
        self.assertEqual(log.action, Action.DISCARD)
        self.assertEqual(log.action_tile, discard_tile)
        self.assertEqual(
            str(log),
            "Player 1 DISCARD with 5 MANZU",
        )
Example #7
0
class TestStack(unittest.TestCase):
    def setUp(self):
        self.test_stack = Stack()

    def test_tiles_in_stack(self):
        self.assertEqual(len(self.test_stack.stack), 136)
        self.assertEqual(len(self.test_stack.dora_indicators), 1)
        self.assertEqual(len(self.test_stack.doras), 1)
        self.assertEqual(len(self.test_stack.uradoras), 1)
        self.assertEqual(self.test_stack.draw(), self.test_stack.stack[0])
        self.assertEqual(self.test_stack.draw(from_rinshan=True),
                         self.test_stack.stack[-1])

    def test_add_dora(self):
        self.test_stack.add_dora_indicator()
        self.assertEqual(len(self.test_stack.dora_indicators), 2)
        self.assertEqual(len(self.test_stack.uradora_indicators), 2)
        self.assertEqual(len(self.test_stack.doras), 2)
        self.assertEqual(len(self.test_stack.uradoras), 2)

    def test_add_dora_value_error(self):
        self.test_stack.add_dora_indicator()
        self.test_stack.add_dora_indicator()
        self.test_stack.add_dora_indicator()
        self.test_stack.add_dora_indicator()
        with self.assertRaises(ValueError):
            self.test_stack.add_dora_indicator()

    def test_get_dora_indicator(self):
        dora_indicator = self.test_stack.get_dora_indicator()
        self.assertEqual(dora_indicator, [self.test_stack.stack[-5]])

    def test_get_unadora_indicator(self):
        unadora_indicator = self.test_stack.get_unadora_indicator()
        self.assertEqual(unadora_indicator, [self.test_stack.stack[-6]])

    def test_get_dora(self):
        [dora] = self.test_stack.get_dora()
        self.assertEqual(dora, self.test_stack.stack[-5].next_tile())

    def test_get_unadora(self):
        [unadora] = self.test_stack.get_unadora()
        self.assertEqual(unadora, self.test_stack.stack[-6].next_tile())

    def test_compute_dora(self):
        dora_indicator1 = Tile(Suit.JIHAI.value, Jihai.HAKU.value)
        dora1 = Tile(Suit.JIHAI.value, Jihai.HATSU.value)
        dora_indicator2 = Tile(Suit.JIHAI.value, Jihai.CHUN.value)
        dora2 = Tile(Suit.JIHAI.value, Jihai.HAKU.value)
        dora_indicator3 = Tile(Suit.JIHAI.value, Jihai.TON.value)
        dora3 = Tile(Suit.JIHAI.value, Jihai.NAN.value)
        dora_indicator4 = Tile(Suit.JIHAI.value, Jihai.PEI.value)
        dora4 = Tile(Suit.JIHAI.value, Jihai.TON.value)
        dora_indicator5 = Tile(Suit.MANZU.value, 1)
        dora5 = Tile(Suit.MANZU.value, 2)
        dora_indicator6 = Tile(Suit.SOUZU.value, 9)
        dora6 = Tile(Suit.SOUZU.value, 1)
        self.assertEqual(Stack.compute_dora(dora_indicator1), dora1)
        self.assertEqual(Stack.compute_dora(dora_indicator2), dora2)
        self.assertEqual(Stack.compute_dora(dora_indicator3), dora3)
        self.assertEqual(Stack.compute_dora(dora_indicator4), dora4)
        self.assertEqual(Stack.compute_dora(dora_indicator5), dora5)
        self.assertEqual(Stack.compute_dora(dora_indicator6), dora6)

    def test_draw_from_rinshan(self):
        self.test_stack.draw(from_rinshan=True)
        self.assertEqual(len(self.test_stack.playing_wall), 121)
Example #8
0
class TestRiichi(unittest.TestCase):
    def setUp(self):
        # tenpai: 3 MANZU 5 SOUZU
        self.player = Player('test', 1)
        for i in range(1, 10):
            self.player.hand[Tile(Suit.PINZU.value, i).index] += 1
        self.player.hand[Tile(Suit.MANZU.value, 3).index] += 2
        self.player.hand[Tile(Suit.SOUZU.value, 5).index] += 2
        self.stack = Stack()

    def test_riichi(self):
        machi = check_tenpai(self.player.hand, self.player.kabe)
        riichi = check_riichi(self.player, machi, self.stack)
        self.assertEqual(riichi, True)

    def test_no_riichi_kabe(self):
        self.player.hand[Tile(Suit.PINZU.value, 1).index] -= 1
        self.player.hand[Tile(Suit.SOUZU.value, 5).index] -= 2
        naki_tile = Tile(Suit.SOUZU.value, 5)
        naki_tile.owner = 0
        self.player.kabe.append(
            Huro(Naki.PON, naki_tile,
                 [Tile(Suit.SOUZU.value, 5) for i in range(3)]))
        self.player.menzenchin = False

        machi = check_tenpai(self.player.hand, self.player.kabe)
        riichi = check_riichi(self.player, machi, self.stack)
        self.assertEqual(riichi, False)

    def test_riichi_stack(self):
        for i in range(120):
            _ = self.stack.draw()
        machi = check_tenpai(self.player.hand, self.player.kabe)
        riichi = check_riichi(self.player, machi, self.stack)
        self.assertEqual(riichi, False)

    def test_ankan_after_riichi(self):
        # tenpai: 5 SOUZU
        self.player.hand[Tile(Suit.MANZU.value, 3).index] += 1
        self.player.hand[Tile(Suit.SOUZU.value, 5).index] -= 1
        self.player.is_riichi = True

        ankan_tile = Tile(Suit.MANZU.value, 3)
        ankan_tile.owner = 1

        pyinput.inputNum = MagicMock(side_effect=[1, 0])
        pyinput.inputChoice = MagicMock(return_value=5)

        (action, naki), discard_tile = self.player.action_with_new_tile(
            ankan_tile, False, self.stack, False)

        self.assertEqual(action, Action.NAKI)
        self.assertEqual(naki, Naki.ANKAN)
        self.assertEqual(discard_tile, None)

    def test_no_ankan_after_riichi(self):
        # tenpai: 7 PINZU
        self.player = Player('test', 1)
        self.player.hand[Tile(Suit.MANZU.value, 1).index] += 4
        self.player.hand[Tile(Suit.MANZU.value, 2).index] += 2
        self.player.hand[Tile(Suit.MANZU.value, 3).index] += 2
        self.player.hand[Tile(Suit.MANZU.value, 4).index] += 1
        for i in range(4, 7):
            self.player.hand[Tile(Suit.SOUZU.value, i).index] += 1
        self.player.hand[Tile(Suit.PINZU.value, 7).index] += 1

        self.player.is_riichi = True

        ankan_tile = Tile(Suit.SOUZU.value, 1)
        ankan_tile.owner = 1

        pyinput.inputNum = MagicMock(side_effect=[0])

        (action, naki), discard_tile = self.player.action_with_new_tile(
            ankan_tile, False, self.stack, False)

        self.assertEqual(action, Action.NOACT)
        self.assertEqual(naki, Naki.NONE)
        self.assertEqual(discard_tile, ankan_tile)