Exemple #1
0
def test_minimal_cost():
    table = Table()
    player = table.player

    # orasu
    table.round_wind_number = 7
    table.dealer_seat = 1
    player.dealer_seat = 1

    player.scores = 22000
    i = -1
    for enemy in table.players:
        if enemy != player:
            enemy.scores = 24000 + i * 6000
            i += 1

    minimal_cost = player.ai.placement.get_minimal_cost_needed()
    assert minimal_cost == 0

    player.scores = 1000
    for enemy in table.players:
        if enemy != player:
            enemy.scores = 33000

    minimal_cost = player.ai.placement.get_minimal_cost_needed()
    assert minimal_cost == 32000
def test_open_double_south_wind():
    table = Table()
    tiles = string_to_136_array(man="59", sou="1235", pin="12788", honors="22")
    table.player.init_hand(tiles)

    tile = string_to_136_tile(honors="2")
    meld, _ = table.player.try_to_call_meld(tile, True)
    assert meld is None

    # player is south and round is south
    table.round_wind_number = 5
    table.player.dealer_seat = 3
    assert table.player.player_wind == SOUTH

    table.player.init_hand(tiles)
    tile = string_to_136_tile(honors="2")
    meld, _ = table.player.try_to_call_meld(tile, True)
    assert meld is None

    # add dora in the hand and after that we can open a hand
    table.dora_indicators.append(string_to_136_tile(pin="6"))

    table.player.init_hand(tiles)
    tile = string_to_136_tile(honors="2")
    meld, _ = table.player.try_to_call_meld(tile, True)
    assert meld is not None
Exemple #3
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)
Exemple #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
Exemple #5
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
Exemple #6
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)
Exemple #7
0
def test_threatening_riichi_player_with_yakuhai_kan():
    table = Table()
    enemy_seat = 2
    table.round_wind_number = 1
    enemy_called_riichi_helper(table, enemy_seat)

    table.add_called_meld(
        enemy_seat, make_meld(MeldPrint.KAN, is_open=False, honors="1111"))

    # 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(man="2")) == 8000
Exemple #8
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
Exemple #9
0
def test_is_threatening_and_two_open_yakuhai_melds():
    table = Table()

    threatening_players = table.player.ai.defence.get_threatening_players()
    assert len(threatening_players) == 0

    # south player
    enemy_seat = 1
    # south round
    table.round_wind_number = 4

    table.add_called_meld(enemy_seat, make_meld(MeldPrint.PON, honors="222"))
    table.add_called_meld(enemy_seat, make_meld(MeldPrint.CHI, man="123"))
    table.player.round_step = 2

    table.add_discarded_tile(enemy_seat, string_to_136_tile(sou="1"), False)
    table.add_discarded_tile(enemy_seat, string_to_136_tile(man="5"), False)
    table.add_discarded_tile(enemy_seat, string_to_136_tile(sou="8"), False)
    table.add_discarded_tile(enemy_seat, string_to_136_tile(pin="9"), False)
    table.add_discarded_tile(enemy_seat, string_to_136_tile(sou="4"), False)
    table.add_discarded_tile(enemy_seat, string_to_136_tile(man="3"), False)

    # double wind is not enough
    threatening_players = table.player.ai.defence.get_threatening_players()
    assert len(threatening_players) == 0

    # with one dora in enemy melds we can start think about threat
    # it will be 3 han
    table.add_dora_indicator(string_to_136_tile(man="1"))
    threatening_players = table.player.ai.defence.get_threatening_players()
    assert len(threatening_players) == 1
    assert threatening_players[0].enemy.seat == enemy_seat
    assert threatening_players[0].threat_reason[
        "id"] == EnemyDanger.THREAT_EXPENSIVE_OPEN_HAND["id"]
    assert threatening_players[0].get_assumed_hand_cost(
        string_to_136_tile(man="8")) == 3900

    for tile_136 in range(0, 136):
        bonus_danger = threatening_players[0].threat_reason.get(
            "active_yaku")[0].get_bonus_danger(tile_136, 1)
        assert not bonus_danger
Exemple #10
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)
Exemple #11
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
Exemple #12
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
Exemple #13
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)