From fe9eba77fc7296cdd8ff29c3ec574c62471fd2ad Mon Sep 17 00:00:00 2001 From: bogachev-pa Date: Fri, 23 Nov 2018 01:25:05 +0300 Subject: [PATCH 1/3] fix remaining tiles counting when calling melds #107 --- project/game/table.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) 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) From ad5edb079652b9a9dd868955baaefbc36d7e995c Mon Sep 17 00:00:00 2001 From: bogachev-pa Date: Fri, 23 Nov 2018 01:54:33 +0300 Subject: [PATCH 2/3] correctly determine player from who meld was called #107 In tenhou message, player from who the meld was called is encoded relative to the player who called the meld, not relative to the player to whom message is sent. --- project/tenhou/decoder.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) 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) From 552b0384171085def858872cb66a63b6c7a726bc Mon Sep 17 00:00:00 2001 From: bogachev-pa Date: Fri, 23 Nov 2018 02:24:31 +0300 Subject: [PATCH 3/3] fix tests after melds accouting rework #107 --- project/game/tests/tests_client.py | 31 ++++++++++++++++++++++++--- project/tenhou/tests/tests_decoder.py | 4 ++-- 2 files changed, 30 insertions(+), 5 deletions(-) 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/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 = '