def _create_table(enemy_seat, discards, riichi_tile): table = Table() table.has_aka_dora = True for discard in discards: table.add_discarded_tile(0, discard, False) enemy_called_riichi_helper(table, enemy_seat, riichi_tile) return table
def test_calculate_our_hand_cost_1_shanten(): table = Table() player = table.player enemy_seat = 2 table.has_open_tanyao = True table.has_aka_dora = False table.add_called_riichi_step_one(enemy_seat) tiles = string_to_136_array(sou="22245677", pin="145", man="67") tile = string_to_136_tile(honors="1") player.init_hand(tiles) player.add_called_meld(make_meld(MeldPrint.PON, sou="222")) player.draw_tile(tile) discard_option = find_discard_option(player, honors="1") cost = discard_option.average_second_level_cost assert cost == 1500 table.add_dora_indicator(string_to_136_tile(sou="6")) discard_option = find_discard_option(player, honors="1") cost = discard_option.average_second_level_cost assert cost == 5850 table.add_dora_indicator(string_to_136_tile(pin="2")) discard_option = find_discard_option(player, honors="1") cost = discard_option.average_second_level_cost assert cost == 8737
def test_dont_open_bad_hand_if_there_are_expensive_threat(): table = Table() table.add_dora_indicator(string_to_136_tile(man="4")) player = table.player player.round_step = 10 table.has_open_tanyao = True table.has_aka_dora = True enemy_seat = 1 table.add_called_riichi_step_one(enemy_seat) table.add_discarded_tile(enemy_seat, string_to_136_tile(honors="4"), True) tiles = string_to_136_array(sou="226", pin="2469", man="3344", honors="4") + [FIVE_RED_MAN] player.init_hand(tiles) # cheap enemy tempai, but this meld is garbage, let's not push tile = string_to_136_array(man="4444")[2] meld, _ = player.try_to_call_meld(tile, True) assert meld is None # cheap enemy tempai, and good chi, let's take this meld tile = string_to_136_tile(man="2") meld, _ = player.try_to_call_meld(tile, True) assert meld is not None table.add_called_meld( enemy_seat, make_meld(MeldPrint.KAN, is_open=False, honors="1111")) # enemy hand is more expensive now (12000) # in this case let's not open this hand tile = string_to_136_tile(man="2") meld, _ = player.try_to_call_meld(tile, True) assert meld is None
def test_skip_cheap_meld_1_shanten_can_move_to_west(): table = Table() player = table.player table.has_aka_dora = True table.has_open_tanyao = True # orasu table.round_wind_number = 7 table.dealer_seat = 1 player.dealer_seat = 1 table.add_dora_indicator(string_to_136_tile(sou="2")) tiles = string_to_136_array(man="3488", sou="334678", pin="268") table.player.init_hand(tiles) table.player.round_step = 12 player.scores = 18000 assert table.players[0] == player table.players[1].scores = 28000 table.players[2].scores = 29000 table.players[3].scores = 31000 # it's cheap, but with ron from first place we can move game to west round, so let's do it tile = string_to_136_tile(sou="2") meld, _ = table.player.try_to_call_meld(tile, True) assert meld is not None # now this is the cost we might win with tile = string_to_136_tile(sou="3") meld, _ = table.player.try_to_call_meld(tile, True) assert meld is not None
def test_discard_tile_force_tsumogiri(self): table = Table() table.has_aka_dora = True player = table.player tiles = self._string_to_136_array(sou='11134567', pin='456', man='45') # 6p tile = 57 player.init_hand(tiles) player.draw_tile(tile) discarded_tile = player.discard_tile() self.assertEqual(discarded_tile, tile) # add not red five pin tiles = self._string_to_136_array(sou='11134567', pin='46', man='45') + [53] tile = FIVE_RED_PIN player.init_hand(tiles) player.draw_tile(tile) discarded_tile = player.discard_tile() # WE DON'T NEED TO DISCARD RED FIVE self.assertNotEqual(discarded_tile, tile)
def test_skip_cheap_meld_2_shanten(): table = Table() player = table.player table.has_aka_dora = True table.has_open_tanyao = True # orasu table.round_wind_number = 7 table.dealer_seat = 1 player.dealer_seat = 1 table.add_dora_indicator(string_to_136_tile(sou="2")) tiles = string_to_136_array(man="34889", sou="33468", pin="268") table.player.init_hand(tiles) table.player.round_step = 12 player.scores = 18000 assert table.players[0] == player table.players[1].scores = 28000 table.players[2].scores = 35000 table.players[3].scores = 40000 # it's too cheap, let's not open tile = string_to_136_tile(sou="2") meld, _ = table.player.try_to_call_meld(tile, True) assert meld is None # now this is the cost we might win with tile = string_to_136_tile(sou="3") meld, _ = table.player.try_to_call_meld(tile, True) assert meld is not None
def test_skip_ron_in_west_4(): table = Table() player = table.player table.has_aka_dora = True table.has_open_tanyao = True # orasu table.round_wind_number = 11 table.dealer_seat = 1 player.dealer_seat = 1 table.add_dora_indicator(string_to_136_tile(sou="1")) tiles = string_to_136_array(man="23488", sou="34678", pin="567") table.player.init_hand(tiles) table.player.add_called_meld(make_meld(MeldPrint.CHI, pin="567")) table.player.round_step = 14 player.scores = 20100 assert table.players[0] == player table.players[1].scores = 22000 table.players[2].scores = 26000 table.players[3].scores = 29900 assert player.should_call_win(string_to_136_tile(sou="5"), False, 1) assert not player.should_call_win(string_to_136_tile(sou="5"), False, 2) assert not player.should_call_win(string_to_136_tile(sou="5"), False, 3)
def test_should_go_for_defence_and_good_hand_with_drawn_tile(self): """ When we have 14 tiles in hand and someone declared a riichi """ table = Table() table.has_aka_dora = True tiles = self._string_to_136_array(sou='2223457899', honors='666') table.player.init_hand(tiles) table.player.draw_tile(self._string_to_136_tile(man='8')) table.player.add_called_meld(self._make_meld(Meld.PON, sou='222')) table.player.add_called_meld(self._make_meld(Meld.PON, honors='666')) self.assertEqual(table.player.ai.defence.should_go_to_defence_mode(), False) table.add_called_riichi(3) results, shanten = table.player.ai.calculate_outs( table.player.tiles, table.player.closed_hand, table.player.open_hand_34_tiles) selected_tile = table.player.ai.process_discard_options_and_select_tile_to_discard( results, shanten) self.assertEqual( table.player.ai.defence.should_go_to_defence_mode(selected_tile), False) result = table.player.discard_tile() self.assertEqual(self._to_string([result]), '8m')
def test_discard_tile_force_tsumogiri(): table = Table() table.has_aka_dora = True player = table.player tiles = string_to_136_array(sou="11134567", pin="456", man="45") # 6p tile = 57 player.init_hand(tiles) player.draw_tile(tile) discarded_tile, _ = player.discard_tile() assert discarded_tile == tile # add not red five pin tiles = string_to_136_array(sou="11134567", pin="46", man="45") + [53] tile = FIVE_RED_PIN player.init_hand(tiles) player.draw_tile(tile) discarded_tile, _ = player.discard_tile() # WE DON'T NEED TO DISCARD RED FIVE assert discarded_tile != tile
def test_tile_danger_early_discard_early(): enemy_seat = 1 table = Table() table.has_aka_dora = True player = table.player tiles = string_to_136_array(man="11345", pin="11289", honors="5", sou="19") tile = string_to_136_tile(man="9") player.init_hand(tiles) player.draw_tile(tile) table.add_discarded_tile(enemy_seat, string_to_136_tile(sou="2"), False) table.add_discarded_tile(enemy_seat, string_to_136_tile(sou="5"), False) table.add_discarded_tile(enemy_seat, string_to_136_tile(pin="7"), True) table.add_discarded_tile(enemy_seat, string_to_136_tile(pin="1"), True) enemy_called_riichi_helper(table, enemy_seat, string_to_136_tile(pin="4")) # too early to judge about early discards _assert_discard_not_equal(player, enemy_seat, TileDanger.BONUS_EARLY_28, sou="1") _assert_discard_not_equal(player, enemy_seat, TileDanger.BONUS_EARLY_5, sou="9") _assert_discard_not_equal(player, enemy_seat, TileDanger.BONUS_EARLY_37, pin="8") _assert_discard_not_equal(player, enemy_seat, TileDanger.BONUS_EARLY_37, pin="9")
def test_must_push_1st_and_4th_place_riichi(): table = Table() player = table.player table.has_aka_dora = True table.has_open_tanyao = True # orasu table.round_wind_number = 7 table.dealer_seat = 1 player.dealer_seat = 1 table.add_dora_indicator(string_to_136_tile(sou="1")) # we have 1-shanten with no doras, but we must push because we have 4th place in oorasu tiles = string_to_136_array(man="3488", sou="334678", pin="456") table.player.init_hand(tiles) table.player.round_step = 5 player.scores = 45000 assert table.players[0] == player table.players[1].scores = 42000 table.players[2].scores = 5000 table.players[3].scores = 8000 enemy_seat = 3 table.add_called_riichi_step_one(enemy_seat) threatening_players = table.player.ai.defence.get_threatening_players() assert len(threatening_players) == 1 assert not player.ai.placement.must_push(threatening_players, 0, 1)
def test_keep_aka_dora_in_hand(): table = Table() table.dora_indicators = [string_to_136_tile(pin="1")] table.has_aka_dora = True player = table.player tiles = string_to_136_array(sou="12346", pin="34578", man="99") # five sou, we can't get it from string (because from string it is always aka dora) tiles += [89] player.init_hand(tiles) player.draw_tile(FIVE_RED_SOU) # we had to keep red five and discard just 5s discarded_tile, _ = player.discard_tile() assert discarded_tile != FIVE_RED_SOU
def test_keep_aka_dora_in_hand(self): table = Table() table.dora_indicators = [self._string_to_136_tile(pin='1')] table.has_aka_dora = True player = table.player tiles = self._string_to_136_array(sou='12346', pin='34578', man='99') # five sou, we can't get it from string (because from string it is always aka dora) tiles += [89] player.init_hand(tiles) player.draw_tile(FIVE_RED_SOU) # we had to keep red five and discard just 5s discarded_tile = player.discard_tile() self.assertNotEqual(discarded_tile, FIVE_RED_SOU)
def test_call_riichi_with_good_wait_against_other_player_riichi(self): table = Table() table.has_aka_dora = True table.count_of_remaining_tiles = 60 table.player.scores = 25000 tiles = self._string_to_136_array(sou='123789', pin='23467', man='55') table.player.init_hand(tiles) table.player.draw_tile(self._string_to_136_tile(man='9')) table.add_called_riichi(3) discard = table.player.discard_tile() self.assertEqual(self._to_string([discard]), '9m') self.assertEqual(table.player.ai.in_defence, False) self.assertEqual(table.player.can_call_riichi(), True)
def test_calculate_suit_tiles_value_and_tanyao_hand(): table = Table() player = table.player table.has_aka_dora = False player.ai.current_strategy = TanyaoStrategy(BaseStrategy.TANYAO, player) # 0 - 8 man # 9 - 17 pin # 18 - 26 sou results = [ [0, 110], [9, 110], [18, 110], [1, 120], [10, 120], [19, 120], [2, 130], [11, 130], [20, 130], [3, 150], [12, 150], [21, 150], [4, 140], [13, 140], [22, 140], [5, 150], [14, 150], [23, 150], [6, 130], [15, 130], [24, 130], [7, 120], [16, 120], [25, 120], [8, 110], [17, 110], [26, 110], ] for item in results: tile = item[0] value = item[1] assert DiscardOption(player, tile * 4, 0, [], 0).valuation == value assert DiscardOption(player, tile * 4 + 1, 0, [], 0).valuation == value assert DiscardOption(player, tile * 4 + 2, 0, [], 0).valuation == value assert DiscardOption(player, tile * 4 + 3, 0, [], 0).valuation == value
def test_choose_best_option_with_melds(self): table = Table() player = table.player table.has_aka_dora = False tiles = self._string_to_136_array(sou='245666789', honors='2266') player.init_hand(tiles) meld = self._make_meld(Meld.PON, sou='666') player.add_called_meld(meld) meld = self._make_meld(Meld.CHI, sou='789') player.add_called_meld(meld) player.draw_tile(self._string_to_136_tile(sou='5')) discarded_tile = player.discard_tile() # we should discard best ukeire option here - 2s self.assertEqual(self._to_string([discarded_tile]), '2s')
def test_choose_best_option_with_melds(): table = Table() player = table.player table.has_aka_dora = False tiles = string_to_136_array(sou="245666789", honors="2266") player.init_hand(tiles) meld = make_meld(MeldPrint.PON, sou="666") player.add_called_meld(meld) meld = make_meld(MeldPrint.CHI, sou="789") player.add_called_meld(meld) player.draw_tile(string_to_136_tile(sou="5")) discarded_tile, _ = player.discard_tile() # we should discard best ukeire option here - 2s assert tiles_to_string([discarded_tile]) == "2s"
def test_calculate_our_hand_cost_1_shanten_karaten(): table = Table() player = table.player enemy_seat = 2 table.has_open_tanyao = True table.has_aka_dora = False table.add_called_riichi_step_one(enemy_seat) tiles = string_to_136_array(sou="22245677", pin="145", man="67") tile = string_to_136_tile(honors="1") player.init_hand(tiles) player.add_called_meld(make_meld(MeldPrint.PON, sou="222")) player.draw_tile(tile) # average cost should not change because of less waits for _ in range(0, 4): table.add_discarded_tile(1, string_to_136_tile(pin="3"), False) discard_option = find_discard_option(player, honors="1") cost = discard_option.average_second_level_cost assert cost == 1500 # average cost should become 0 for karaten, even if just one of the waits is dead for _ in range(0, 4): table.add_discarded_tile(1, string_to_136_tile(pin="6"), False) discard_option = find_discard_option(player, honors="1") cost = discard_option.average_second_level_cost assert cost == 0 # nothing should crash in case all waits are dead as well for _ in range(0, 4): table.add_discarded_tile(1, string_to_136_tile(man="5"), False) table.add_discarded_tile(1, string_to_136_tile(man="8"), False) discard_option = find_discard_option(player, honors="1") cost = discard_option.average_second_level_cost assert cost == 0
def test_threatening_riichi_player_and_not_visible_dora(): table = Table() enemy_seat = 2 table.add_called_riichi_step_one(enemy_seat) table.add_dora_indicator(string_to_136_tile(sou="2")) table.has_aka_dora = True discards = string_to_136_array(sou="33") for discard in discards: table.add_discarded_tile(enemy_seat, discard, False) # +1 scale for riichi on 6+ turn threatening_player = table.player.ai.defence.get_threatening_players()[0] assert threatening_player.enemy.seat == enemy_seat assert threatening_player.get_assumed_hand_cost( string_to_136_tile(man="2")) == 3900 # on dora discard, enemy hand will be on average more expensive assert threatening_player.get_assumed_hand_cost( string_to_136_tile(sou="3")) == 5200
def test_threatening_riichi_player_with_kan_aka(): table = Table() enemy_seat = 2 enemy_called_riichi_helper(table, enemy_seat) table.has_aka_dora = True table.add_called_meld(enemy_seat, make_meld(MeldPrint.KAN, is_open=False, man="5505")) # non dealer threatening_player = table.player.ai.defence.get_threatening_players()[0] assert threatening_player.enemy.seat == enemy_seat assert threatening_player.get_assumed_hand_cost( string_to_136_tile(sou="2")) == 8000 # dealer threatening_player.enemy.dealer_seat = enemy_seat assert threatening_player.get_assumed_hand_cost( string_to_136_tile(sou="2")) == 12000
def test_should_go_for_defence_and_good_hand_with_drawn_tile(self): """ When we have 14 tiles in hand and someone declared a riichi """ table = Table() table.has_aka_dora = True tiles = self._string_to_136_array(sou='2223457899', honors='666') table.player.init_hand(tiles) table.player.draw_tile(self._string_to_136_tile(man='8')) table.player.add_called_meld(self._make_meld(Meld.PON, sou='222')) table.player.add_called_meld(self._make_meld(Meld.PON, honors='666')) self.assertEqual(table.player.ai.defence.should_go_to_defence_mode(), False) table.add_called_riichi(3) result = table.player.discard_tile() self.assertEqual(self._to_string([result]), '8m')
def test_tile_danger_early_discard_normal(): enemy_seat = 1 table = Table() table.has_aka_dora = True player = table.player tiles = string_to_136_array(man="11345", pin="11289", honors="5", sou="19") tile = string_to_136_tile(man="9") player.init_hand(tiles) player.draw_tile(tile) table.add_discarded_tile(enemy_seat, string_to_136_tile(sou="2"), False) table.add_discarded_tile(enemy_seat, string_to_136_tile(pin="7"), True) table.add_discarded_tile(enemy_seat, string_to_136_tile(sou="5"), False) table.add_discarded_tile(enemy_seat, string_to_136_tile(man="3"), False) table.add_discarded_tile(enemy_seat, string_to_136_tile(pin="1"), True) table.add_discarded_tile(enemy_seat, string_to_136_tile(pin="1"), True) table.add_discarded_tile(enemy_seat, string_to_136_tile(pin="4"), False) table.add_called_riichi_step_one(enemy_seat) table.add_discarded_tile(enemy_seat, string_to_136_tile(pin="2"), False) # now that looks like 1 sou is not too dangerous and 9 sou is on the contrary very dangerous _assert_discard(player, enemy_seat, TileDanger.BONUS_EARLY_28, sou="1") _assert_discard(player, enemy_seat, TileDanger.BONUS_EARLY_5, sou="9") _assert_discard(player, enemy_seat, TileDanger.BONUS_EARLY_37, pin="8") _assert_discard(player, enemy_seat, TileDanger.BONUS_EARLY_37, pin="9") # check it's not vice versa _assert_discard_not_equal(player, enemy_seat, TileDanger.BONUS_EARLY_5, sou="1") _assert_discard_not_equal(player, enemy_seat, TileDanger.BONUS_EARLY_28, sou="9") # to be sure that we are not checking other suit _assert_discard_not_equal(player, enemy_seat, TileDanger.BONUS_EARLY_28, man="9")
def test_take_cheap_meld_tempai(): table = Table() player = table.player table.has_aka_dora = True table.has_open_tanyao = True # orasu table.round_wind_number = 7 table.dealer_seat = 1 player.dealer_seat = 1 table.add_dora_indicator(string_to_136_tile(man="2")) tiles = string_to_136_array(man="23789", sou="3789", pin="99", honors="33") table.player.init_hand(tiles) table.player.round_step = 5 player.scores = 20000 assert table.players[0] == player table.players[1].scores = 20900 table.players[2].scores = 35000 table.players[3].scores = 40000 # no yaku, skip tile = string_to_136_tile(man="4") meld, _ = table.player.try_to_call_meld(tile, True) assert meld is None # now this is the cost we might win with tile = string_to_136_tile(man="1") meld, _ = table.player.try_to_call_meld(tile, True) assert meld is not None # now this is not enough player.scores = 20000 assert table.players[0] == player table.players[1].scores = 30900 table.players[2].scores = 35000 table.players[3].scores = 40000 tile = string_to_136_tile(man="1") meld, _ = table.player.try_to_call_meld(tile, True) assert meld is None
def test_take_cheap_meld_tempai_tanyao_not_activated(): table = Table() player = table.player table.has_aka_dora = True table.has_open_tanyao = True # orasu table.round_wind_number = 7 table.dealer_seat = 1 player.dealer_seat = 1 # tanyao is not activated due to tanyao rules but we don't care and take this meld tiles = string_to_136_array(man="23678", sou="3567", pin="2257") table.player.init_hand(tiles) table.player.round_step = 5 player.scores = 20000 assert table.players[0] == player table.players[1].scores = 20900 table.players[2].scores = 35000 table.players[3].scores = 40000 # no yaku, skip tile = string_to_136_tile(man="1") meld, _ = table.player.try_to_call_meld(tile, True) assert meld is None # now this is the cost we might win with tile = string_to_136_tile(man="4") meld, _ = table.player.try_to_call_meld(tile, True) assert meld is not None # now this is not enough player.scores = 20000 assert table.players[0] == player table.players[1].scores = 30900 table.players[2].scores = 35000 table.players[3].scores = 40000 tile = string_to_136_tile(man="4") meld, _ = table.player.try_to_call_meld(tile, True) assert meld is None
def test_tile_danger_aidayonken_after_riichi(): enemy_seat = 1 table = Table() table.has_aka_dora = True player = table.player tiles = string_to_136_array(man="11345", pin="11256", honors="5", sou="25") tile = string_to_136_tile(sou="5") player.init_hand(tiles) player.draw_tile(tile) table.add_discarded_tile(enemy_seat, string_to_136_tile(sou="1"), True) table.add_called_riichi_step_one(enemy_seat) table.add_discarded_tile(enemy_seat, string_to_136_tile(honors="7"), False) table.add_discarded_tile(enemy_seat, string_to_136_tile(sou="2"), True) table.add_discarded_tile(enemy_seat, string_to_136_tile(sou="6"), True) table.add_discarded_tile(enemy_seat, string_to_136_tile(pin="1"), True) table.add_discarded_tile(enemy_seat, string_to_136_tile(pin="6"), True) _assert_discard_not_equal(player, enemy_seat, TileDanger.BONUS_AIDAYONKEN, sou="5") _assert_discard_not_equal(player, enemy_seat, TileDanger.BONUS_AIDAYONKEN, sou="2") _assert_discard_not_equal(player, enemy_seat, TileDanger.BONUS_AIDAYONKEN, pin="2") _assert_discard_not_equal(player, enemy_seat, TileDanger.BONUS_AIDAYONKEN, pin="5") _assert_discard_not_equal(player, enemy_seat, TileDanger.BONUS_AIDAYONKEN, man="5")
def test_skip_ron(): table = Table() player = table.player table.has_aka_dora = True table.has_open_tanyao = True # orasu table.round_wind_number = 7 table.dealer_seat = 1 player.dealer_seat = 1 table.add_dora_indicator(string_to_136_tile(sou="1")) # 1900 to 3rd place player.scores = 20100 assert table.players[0] == player table.players[1].scores = 22000 table.players[2].scores = 26000 table.players[3].scores = 30900 minimal_cost = player.ai.placement.get_minimal_cost_needed() assert minimal_cost == 1900 tiles = string_to_136_array(man="23488", sou="34678", pin="567") table.player.init_hand(tiles) table.player.add_called_meld(make_meld(MeldPrint.CHI, pin="567")) table.player.round_step = 14 # we should not call ron 1000 from 2nd place as it leaves us on 4th assert not player.should_call_win(string_to_136_tile(sou="5"), False, 2) # ron 2000 from 2nd place is ok, it's enough to get to 3rd assert player.should_call_win(string_to_136_tile(sou="2"), False, 2) # ron 1000 from 3rd place is ok too assert player.should_call_win(string_to_136_tile(sou="5"), False, 1) # ron 1000 from 1st place is ok too as it moves us to west round assert player.should_call_win(string_to_136_tile(sou="5"), False, 3) # ron 2000 from 1st place is ok, checking just to be sure assert player.should_call_win(string_to_136_tile(sou="2"), False, 3)
def test_choose_best_wait_with_melds(self): table = Table() player = table.player table.has_aka_dora = False tiles = self._string_to_136_array(sou='1222233455599') player.init_hand(tiles) meld = self._make_meld(Meld.CHI, sou='123') player.add_called_meld(meld) meld = self._make_meld(Meld.PON, sou='222') player.add_called_meld(meld) meld = self._make_meld(Meld.PON, sou='555') player.add_called_meld(meld) player.draw_tile(self._string_to_136_tile(sou='4')) discarded_tile = player.discard_tile() # double-pairs wait becomes better, because it has 4 tiles to wait for # against just 1 in ryanmen self.assertEqual(self._to_string([discarded_tile]), '3s')
def test_choose_best_wait_with_melds(): table = Table() player = table.player table.has_aka_dora = False tiles = string_to_136_array(sou="3499222555123") player.init_hand(tiles) meld = make_meld(MeldPrint.PON, sou="222") table.add_called_meld(0, meld) # 123s, we can't automatically chose correct index for fourth 2s meld = make_meld(MeldPrint.CHI, tiles=[72, 79, 80]) table.add_called_meld(0, meld) meld = make_meld(MeldPrint.PON, sou="555") table.add_called_meld(0, meld) player.draw_tile(string_to_136_tile(sou="4")) discarded_tile, _ = player.discard_tile() # double-pairs wait becomes better, because it has 4 tiles to wait for # against just 1 in ryanmen assert tiles_to_string([discarded_tile]) == "3s"
def test_skip_ron_wind_placement(): table = Table() player = table.player table.has_aka_dora = True table.has_open_tanyao = True # orasu table.round_wind_number = 7 table.dealer_seat = 1 player.dealer_seat = 1 table.add_dora_indicator(string_to_136_tile(sou="1")) tiles = string_to_136_array(man="23488", sou="34678", pin="567") table.player.init_hand(tiles) table.player.add_called_meld(make_meld(MeldPrint.CHI, pin="567")) table.player.round_step = 14 player.scores = 21000 assert table.players[0] == player table.players[1].scores = 22000 table.players[2].scores = 30100 table.players[3].scores = 31000 player.first_seat = 0 table.players[1].first_seat = 1 assert player.ai.placement.get_minimal_cost_needed() == 1000 assert player.should_call_win(string_to_136_tile(sou="5"), False, 1) assert player.should_call_win(string_to_136_tile(sou="5"), False, 2) assert player.should_call_win(string_to_136_tile(sou="5"), False, 3) player.first_seat = 1 table.players[1].first_seat = 0 assert player.ai.placement.get_minimal_cost_needed() == 1100 assert player.should_call_win(string_to_136_tile(sou="5"), False, 1) assert not player.should_call_win(string_to_136_tile(sou="5"), False, 2) assert not player.should_call_win(string_to_136_tile(sou="5"), False, 3)
def test_take_cheap_meld_yakuhai_1_shanten(): table = Table() player = table.player table.has_aka_dora = True table.has_open_tanyao = True # orasu table.round_wind_number = 7 table.dealer_seat = 1 player.dealer_seat = 1 tiles = string_to_136_array(man="236778", sou="357", pin="22", honors="55") table.player.init_hand(tiles) table.player.round_step = 5 player.scores = 20000 assert table.players[0] == player table.players[1].scores = 20900 table.players[2].scores = 35000 table.players[3].scores = 40000 # bad atodzuke - skip tile = string_to_136_tile(pin="2") meld, _ = table.player.try_to_call_meld(tile, True) assert meld is None # now this is the cost we might win with tile = string_to_136_tile(honors="5") meld, _ = table.player.try_to_call_meld(tile, True) assert meld is not None # now this is not enough player.scores = 20000 assert table.players[0] == player table.players[1].scores = 30900 table.players[2].scores = 35000 table.players[3].scores = 40000 tile = string_to_136_tile(honors="5") meld, _ = table.player.try_to_call_meld(tile, True) assert meld is None