def test_2_threeway_draw():
    """
    Three players end with a Guard and total discarded value of 2.

    player0 plays: Spy, Priest
    player1 plays: Guard, Guard
    player2 plays: Priest, Spy
    """
    game_round = start_round_from_player_cards(
        [cards.Spy(), cards.Priest(),
         cards.Guard()],
        [cards.Guard(), cards.Guard(),
         cards.Guard()],
        [cards.Priest(), cards.Spy(),
         cards.Guard()],
        first_player=0,
    )
    player0, player1, player2 = game_round.players

    play_with_choices(player0, CardType.SPY)
    play_with_choices(player1, CardType.GUARD, player0, CardType.PRINCESS)
    play_with_choices(player2, CardType.PRIEST, player0)
    play_with_choices(player0, CardType.PRIEST, player1)
    play_with_choices(player1, CardType.GUARD, player2, CardType.PRINCESS)
    play_with_choices(player2, CardType.SPY)

    end = game_round.state
    assert end.type == RoundState.Type.ROUND_END
    assert end.winners == {player0, player1, player2}
Beispiel #2
0
def test_guard_guessGuard_raises(started_round: Round):
    player = started_round.current_player
    move = play_card(player, cards.Guard())
    target_step = next(move)
    guess_step = move.send(autofill_step(target_step))
    with pytest.raises(valid8.ValidationError):
        guess_step.choice = CardType.GUARD
Beispiel #3
0
def test_start_emptyDeckUponStart_raises(new_round: Round):
    new_round.deck = Deck(
        [cards.Guard() for _ in range(new_round.num_players + 1)],
        set_aside=cards.Princess(),
    )
    with pytest.raises(valid8.ValidationError):
        new_round.start()
def test_1_prince_victory():
    """
    player1 has a countess, player0 uses a prince to discard himself and get the
    princess and win.
    """
    game_round = start_round_from_player_cards(
        [cards.Prince(), cards.Handmaid(),
         cards.Guard()],
        [cards.Countess(), cards.Priest()],
        set_aside=cards.Princess(),
        first_player=0,
    )
    player0, player1 = game_round.players
    assert tuple(map(CardType,
                     player0.hand)) == (CardType.PRINCE, CardType.HANDMAID)
    assert tuple(map(CardType, player1.hand)) == (CardType.COUNTESS, )
    assert max(game_round.players, key=lambda p: p.hand.card.value) is player1

    (immunity, ) = play_with_choices(player0, CardType.HANDMAID)
    assert immunity.player is player0

    results = play_with_choices(player1, CardType.PRIEST,
                                mv.OpponentChoice.NO_TARGET)
    assert results == ()

    discarded, dealt = play_with_choices(player0, CardType.PRINCE, player0)
    assert CardType(discarded.discarded) == CardType.GUARD
    assert CardType(dealt.dealt) == CardType.PRINCESS

    end = game_round.state
    assert end.type == RoundState.Type.ROUND_END
    assert max(game_round.players, key=lambda p: p.hand.card.value) is player0
    assert end.winner is player0
Beispiel #5
0
def test_roundEnd_totalTie_allContendersWin(started_round: Round, loser):
    losers = {loser} if loser is not None else set()
    winners = set(started_round.players) - losers

    started_round.deck.stack.clear()
    for player in winners:
        give_card(player, cards.Princess(), replace=True)
        player.discarded_cards = [cards.Guard()]
    for loser in losers:
        give_card(loser, cards.Guard(), replace=True)

    end: loveletter.round.RoundEnd = force_next_turn(started_round)
    assert end.type == RoundState.Type.ROUND_END
    assert end.tie_contenders == winners
    assert end.winners == winners
    if len(winners) > 1:
        with pytest.raises(valid8.ValidationError):
            # noinspection PyStatementEffect
            end.winner
def test_5_baron_suicide():
    """
    player0 has Baron-Baron and everyone else has higher cards, so they die.
    """
    game_round = start_round_from_player_cards(
        [cards.Baron(), cards.Baron()],
        [cards.Countess(), cards.Handmaid(),
         cards.Guard()],
        [cards.Handmaid(), cards.Princess(),
         cards.Guard()],
        first_player=0,
    )
    player0, player1, player2 = game_round.players

    play_random_move(player0)
    assert not game_round.ended
    assert not player0.alive
    assert player1.alive
    assert player2.alive
def test_6_guard_win():
    """A chain of Guard eliminations that ends in player 3 winning"""
    game_round = start_round_from_player_cards(
        [cards.King()],
        [cards.Countess(), cards.Guard()],
        [cards.Princess(), cards.Guard()],
        [cards.Guard(), cards.Guard()],
        first_player=1,
    )
    player0, player1, player2, player3 = game_round.players

    play_with_choices(player1, CardType.GUARD, player0, CardType.KING)
    play_with_choices(player2, CardType.GUARD, player1, CardType.COUNTESS)
    play_with_choices(player3, CardType.GUARD, player2, CardType.PRINCESS)

    assert game_round.ended
    assert not player0.alive
    assert not player1.alive
    assert not player2.alive
    assert player3.alive
    assert game_round.state.winner is player3
Beispiel #8
0
def test_roundEnd_cardTie_maxDiscardedValueWins(started_round: Round,
                                                from_player):
    discard_piles = (
        [cards.Priest(), cards.Prince()],  # total value: 7
        [cards.Guard(), cards.Countess()],  # total value: 8  -- best; offset=1
        [cards.Guard(), cards.Spy()],  # total value: 1
        [cards.Spy()],  # total value: 0
    )
    winner = started_round.get_player(from_player, offset=1)
    card_in_common = CardType.GUARD  # everyone will have this card in hand

    started_round.deck.stack.clear()
    for player, discard_pile in zip(
            cycle_from(started_round.players, from_item=from_player, times=1),
            discard_piles,
    ):
        give_card(player, card_from_card_type(card_in_common), replace=True)
        player.discarded_cards = discard_pile

    end: loveletter.round.RoundEnd = force_next_turn(started_round)
    assert end.type == RoundState.Type.ROUND_END
    assert end.winner is winner
    assert end.tie_contenders == frozenset(started_round.players)  # everyone
    def round_runner(g):
        game_round = start_round_from_player_cards(
            [cards.Guard(), cards.Baron()],
            [cards.King(), cards.Princess()],
            first_player=0,
        )
        object.__setattr__(g.state, "round", game_round)  # work around frozen dataclass
        player0, player1 = game_round.players

        play_with_choices(player0, CardType.GUARD, player1, cards.Princess)
        play_random_move(player1)

        end = game_round.state
        assert end.type == RoundState.Type.ROUND_END
        assert end.winner is player0
def test_3_king_win():
    """
    player1 draws the Princess but is forced to relinquish it because they have a King.
    """
    game_round = start_round_from_player_cards(
        [cards.Guard(), cards.Baron()],
        [cards.King(), cards.Princess()],
        first_player=0,
    )
    player0, player1 = game_round.players

    play_with_choices(player0, CardType.GUARD, player1, cards.Princess)
    play_random_move(player1)

    end = game_round.state
    assert end.type == RoundState.Type.ROUND_END
    assert end.winner is player0
Beispiel #11
0
def test_guard_correctGuess_eliminatesOpponent(started_round: Round):
    player = started_round.current_player
    for other in set(started_round.players) - {player}:
        assert other.alive
        move = play_card(player, cards.Guard())
        target_step = move.send(None)
        target_step.choice = other
        guess_step = move.send(target_step)
        guess_step.choice = guess = type(other.hand.card)
        results = send_gracious(move, guess_step)
        assert tuple(map(type, results)) == (mv.CorrectCardGuess,
                                             mv.PlayerEliminated)
        assert results[0].guess == CardType(guess)
        assert results[1].eliminated == other
        assert not other.alive
        # artificially start new turn with same player
        restart_turn(started_round)
Beispiel #12
0
def test_advanceTurn_emptyDeck_roundEndsWithLargestCardWinner(
        started_round: Round, set_aside):
    started_round.deck = Deck([], set_aside=set_aside)
    increasing_cards = [
        cards.Guard(),
        cards.Priest(),
        cards.Baron(),
        cards.Princess()
    ]
    for player, card in zip(started_round.players, increasing_cards):
        give_card(player, card, replace=True)
    # noinspection PyUnboundLocalVariable
    winner = player

    state: loveletter.round.RoundEnd = force_next_turn(started_round)
    assert state.type == RoundState.Type.ROUND_END
    assert state.reason == loveletter.round.RoundEnd.Reason.EMPTY_DECK
    assert state.winners == frozenset({winner})
    assert state.winner is winner
Beispiel #13
0
def test_guard_incorrectGuess_doesNotEliminateOpponent(started_round: Round):
    player = started_round.current_player
    for other in set(started_round.players) - {player}:
        assert other.alive
        wrong_guesses = set(CardType) - {
            CardType(type(other.hand.card)),
            CardType.GUARD,
        }
        for guess in wrong_guesses:
            move = play_card(player, cards.Guard())
            target_step = next(move)
            target_step.choice = other
            guess_step = move.send(target_step)
            guess_step.choice = guess
            results = send_gracious(move, guess_step)
            assert tuple(map(type, results)) == (mv.WrongCardGuess, )
            assert results[0].guess == CardType(guess)
            assert other.alive
            # artificially start new turn with same player
            restart_turn(started_round)
def test_4_princess_suicide():
    """
    player1 holds a Princess but has to eliminate themselves because they draw a Prince
    and the opponent is immune.
    """
    game_round = start_round_from_player_cards(
        [cards.Handmaid(), cards.Baron(),
         cards.Guard()],
        [cards.Princess(), cards.Prince(),
         cards.Countess()],
        first_player=0,
    )
    player0, player1 = game_round.players

    play_with_choices(player0, CardType.HANDMAID)
    play_random_move(player1)

    assert game_round.ended
    assert game_round.state.winner is player0
    assert CardType(
        game_round.deck.take()) == CardType.GUARD  # assert no card dealt
Beispiel #15
0
def test_chooseCardToPlay_validatesCardInHand(current_player: RoundPlayer):
    event = loveletter.round.ChooseCardToPlay(current_player)
    with pytest.raises(valid8.ValidationError):
        event.choice = cards.Guard(
        )  # this card object is not in the player's hand
Beispiel #16
0
def test_start_insufficientCardsInDeck_raises(new_round: Round):
    new_round.deck = Deck([cards.Guard() for _ in new_round.players], None)
    with pytest.raises(valid8.ValidationError):
        new_round.start()
Beispiel #17
0
def test_playType_notPresent_raises(player: RoundPlayer):
    give_card(player, cards.Guard())
    give_card(player, cards.Princess())
    with pytest.raises(valid8.ValidationError):
        send_gracious(player.play_type(CardType.PRINCE), None)