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
Exemplo n.º 2
0
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
Exemplo n.º 3
0
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
Exemplo n.º 4
0
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
Exemplo n.º 5
0
    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)
Exemplo n.º 6
0
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
Exemplo n.º 7
0
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)
Exemplo n.º 8
0
    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')
Exemplo n.º 9
0
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_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_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")
Exemplo n.º 12
0
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)
Exemplo n.º 13
0
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)
Exemplo n.º 15
0
    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)
Exemplo n.º 16
0
    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)
Exemplo n.º 17
0
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')
Exemplo n.º 19
0
    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')
Exemplo n.º 20
0
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"
Exemplo n.º 21
0
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
Exemplo n.º 22
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
Exemplo n.º 23
0
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
Exemplo n.º 24
0
    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')
Exemplo n.º 25
0
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")
Exemplo n.º 26
0
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
Exemplo n.º 27
0
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
Exemplo n.º 28
0
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")
Exemplo n.º 29
0
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')
Exemplo n.º 31
0
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"
Exemplo n.º 32
0
    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')
Exemplo n.º 33
0
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)
Exemplo n.º 34
0
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