diff --git a/project/game/table.py b/project/game/table.py index fd7c6bfe..1f12a5f0 100644 --- a/project/game/table.py +++ b/project/game/table.py @@ -98,13 +98,17 @@ def init_round(self, def add_called_meld(self, player_seat, meld): self.meld_was_called = True - # when opponent called meld it is means - # that he discards tile from hand, not from wall - self.count_of_remaining_tiles += 1 - - # we will decrease count of remaining tiles after called kan - # because we had to complement dead wall - if meld.type == Meld.KAN or meld.type == meld.CHANKAN: + # if meld was called from the other player, then we skip one draw from the wall + if meld.opened: + # but if it's an opened kan, player will get a tile from + # a dead wall, so total number of tiles in the wall is the same + # as if he just draws a tile + if meld.type != Meld.KAN: + self.count_of_remaining_tiles += 1 + else: + # can't have a pon or chi from the hand + assert meld.type == Meld.KAN or meld.type == meld.CHANKAN + # player draws additional tile from the wall in case of closed kan or chankan self.count_of_remaining_tiles -= 1 self.get_player(player_seat).add_called_meld(meld) diff --git a/project/game/tests/tests_client.py b/project/game/tests/tests_client.py index d80d07ea..faaacb67 100644 --- a/project/game/tests/tests_client.py +++ b/project/game/tests/tests_client.py @@ -25,7 +25,7 @@ def test_discard_tile(self): self.assertFalse(tile in client.table.player.tiles) self.assertEqual(client.table.count_of_remaining_tiles, 69) - def test_call_meld(self): + def test_call_meld_closed_kan(self): client = Client() client.table.init_round(0, 0, 0, 0, 0, [0, 0, 0, 0]) @@ -41,13 +41,38 @@ def test_call_meld(self): meld = Meld() meld.type = Meld.KAN # closed kan + meld.tiles = [0, 1, 2, 3] meld.called_tile = None meld.opened = False client.table.add_called_meld(0, meld) self.assertEqual(len(client.player.melds), 2) - # +1 for called meld - # -1 for called kan + # kan was closed, so -1 + self.assertEqual(client.table.count_of_remaining_tiles, 70) + + def test_call_meld_kan_from_player(self): + client = Client() + + client.table.init_round(0, 0, 0, 0, 0, [0, 0, 0, 0]) + self.assertEqual(client.table.count_of_remaining_tiles, 70) + + meld = Meld() + client.table.add_called_meld(0, meld) + + self.assertEqual(len(client.player.melds), 1) + self.assertEqual(client.table.count_of_remaining_tiles, 71) + + client.player.tiles = [0] + meld = Meld() + meld.type = Meld.KAN + # closed kan + meld.tiles = [0, 1, 2, 3] + meld.called_tile = 0 + meld.opened = True + client.table.add_called_meld(0, meld) + + self.assertEqual(len(client.player.melds), 2) + # kan was called from another player, total number of remaining tiles stays the same self.assertEqual(client.table.count_of_remaining_tiles, 71) def test_enemy_discard(self): diff --git a/project/tenhou/decoder.py b/project/tenhou/decoder.py index e73c85a4..156f3f04 100644 --- a/project/tenhou/decoder.py +++ b/project/tenhou/decoder.py @@ -167,7 +167,9 @@ def parse_meld(self, message): meld = Meld() meld.who = int(self.get_attribute_content(message, 'who')) - meld.from_who = data & 0x3 + # 'from_who' is encoded relative the the 'who', so we want + # to convert it to be relative to our player + meld.from_who = ((data & 0x3) + meld.who) % 4 if data & 0x4: self.parse_chi(data, meld) diff --git a/project/tenhou/tests/tests_decoder.py b/project/tenhou/tests/tests_decoder.py index 28ace4d3..660750dc 100644 --- a/project/tenhou/tests/tests_decoder.py +++ b/project/tenhou/tests/tests_decoder.py @@ -124,7 +124,7 @@ def test_parse_called_opened_kan(self): meld = decoder.parse_meld('') self.assertEqual(meld.who, 3) - self.assertEqual(meld.from_who, 1) + self.assertEqual(meld.from_who, 0) self.assertEqual(meld.type, Meld.KAN) self.assertEqual(meld.opened, True) self.assertEqual(meld.tiles, [52, 53, 54, 55]) @@ -174,7 +174,7 @@ def test_parse_who_called_riichi(self): def test_reconnection_information(self): message = '