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}
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
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
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
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
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)
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
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
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
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()
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)