def test_advanceTurn_ongoingMove_raises(started_round: Round, card: Card): player = started_round.current_player move = play_card(player, card, autofill=False) with pytest.raises(valid8.ValidationError): started_round.advance_turn() step = None for _ in card.steps: step = move.send(autofill_step(step)) with pytest.raises(valid8.ValidationError): started_round.advance_turn() send_gracious(move, autofill_step(step)) # send final step started_round.advance_turn()
def test_prince_emptyDeck_dealsSetAsideCard(current_player: RoundPlayer, target: RoundPlayer, set_aside: cards.Card): current_player.round.deck = Deck([], set_aside=set_aside) give_card(target, CardMockCases().case_generic(), replace=True) move = play_card(current_player, cards.Prince()) target_step = next(move) target_step.choice = target send_gracious(move, target_step) assert target.hand.card is set_aside assert current_player.round.deck.set_aside is None assert not current_player.round.deck
def test_targetCard_allOpponentsImmune_canChooseNone(started_round: Round, card): for player in started_round.players: if player is not started_round.current_player: player.immune = True with assert_state_is_preserved(started_round, allow_mutation={ started_round.current_player }) as mocked_round: move = play_card(mocked_round.current_player, card) target_step = next(move) target_step.choice = mv.OpponentChoice.NO_TARGET send_gracious(move, target_step)
def test_chancellor_correctlyHandlesCards(started_round): player = started_round.current_player other_card = player.hand.card top_2 = started_round.deck.stack[-2:] move = play_card(player, cards.Chancellor()) card_choice: mv.ChooseOneCard = next(move) assert player.hand.card is other_card assert other_card in card_choice.options assert set(top_2).issubset(set(card_choice.options)) card_choice.choice = random.choice(card_choice.options) order_choice: mv.ChooseOrderForDeckBottom = move.send(card_choice) assert player.hand.card is card_choice.choice assert len(player.hand) == 1 assert set(card_choice.options) - {card_choice.choice} == set( order_choice.cards) order = list(order_choice.cards) random.shuffle(order) order_choice.choice = tuple(order) results = send_gracious(move, order_choice) assert started_round.deck.stack[:2] == order assert tuple(map(type, results)) == ( mv.CardChosen, mv.CardsPlacedBottomOfDeck, ) assert results[0].choice is card_choice.choice assert results[1].cards == order_choice.choice
def test_cardSteps_correspondsToReality(player: RoundPlayer, card: cards.Card): move = play_card(player, card, autofill=False) step = None for expected_step_type in card.steps: step = move.send(autofill_step(step)) assert type(step) == expected_step_type results = send_gracious(move, autofill_step(step)) assert mv.is_move_results(results)
def test_countess_playNotPrinceOrKing_noOp(current_player: RoundPlayer, card_type): target = current_player.round.next_player(current_player) with assert_state_is_preserved(current_player.round, allow_mutation={current_player, target}) as mocked_round: player, target = mocked_round.current_player, mocked_round.players[ target.id] give_card(player, cards.Countess(), replace=True) move = play_card(player, card := card_from_card_type(card_type), autofill=False) step = None for _ in card.steps: step = move.send(step) if isinstance(step, mv.PlayerChoice): step.choice = target else: step = autofill_step(step) send_gracious(move, step)
def test_king_againstOpponent_swapsCards(current_player: RoundPlayer): move = play_card(current_player, cards.King()) target_step = autofill_step(next(move)) target = target_step.choice player_card, target_card = current_player.hand.card, target.hand.card results = send_gracious(move, target_step) assert current_player.hand.card is target_card assert target.hand.card is player_card assert tuple(map(type, results)) == (mv.CardsSwapped, ) assert results[0].opponent is target
def test_priest_validOpponent_showsCard(started_round: Round): player = started_round.current_player opponent = started_round.next_player(player) move = play_card(player, cards.Priest()) target_step = next(move) target_step.choice = opponent result, *_ = send_gracious(move, target_step) assert len(_) == 0 assert isinstance(result, mv.ShowOpponentCard) move.close() assert result.opponent is opponent
def test_baron_equalOpponent_noneEliminated(started_round: Round, card): player = started_round.current_player opponent = started_round.next_player(player) give_card(player, card, replace=True) give_card(opponent, card, replace=True) move = play_card(player, cards.Baron()) target_step = next(move) target_step.choice = opponent comparison, *_ = send_gracious(move, target_step) move.close() assert len(_) == 0 assert isinstance(comparison, mv.CardComparison) assert player.alive assert opponent.alive
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_baron_strongerOpponent_selfEliminated(started_round: Round, card1, card2): player = started_round.current_player opponent = started_round.next_player(player) give_card(player, card1, replace=True) give_card(opponent, card2, replace=True) move = play_card(player, cards.Baron()) target_step = next(move) target_step.choice = opponent comparison, elimination, *_ = send_gracious(move, target_step) move.close() assert len(_) == 0 assert isinstance(comparison, mv.CardComparison) assert isinstance(elimination, mv.PlayerEliminated) assert comparison.opponent is opponent assert elimination.eliminated is player assert not player.alive assert opponent.alive
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_prince_againstPrincess_kills(started_round: Round): player = started_round.current_player victim = started_round.next_player(player) give_card(victim, cards.Princess(), replace=True) victim_card = victim.hand.card deck_before = list(started_round.deck) move = play_card(player, cards.Prince()) target_step = next(move) target_step.choice = victim results = send_gracious(move, target_step) assert tuple(map(type, results)) == ( mv.CardDiscarded, mv.PlayerEliminated, ) assert results[0].target is victim assert results[0].discarded is victim_card assert results[1].eliminated is victim assert not victim.alive assert CardType(victim.discarded_cards[-1]) == CardType.PRINCESS assert list(started_round.deck) == deck_before
def test_prince_againstNonPrincess_dealsCard(started_round: Round, target: RoundPlayer, card_type): player = started_round.current_player give_card(target, card_from_card_type(card_type), replace=True) target_card = target.hand.card deck_before = list(started_round.deck) move = play_card(player, cards.Prince()) target_step = next(move) target_step.choice = target results = send_gracious(move, target_step) assert tuple(map(type, results)) == ( mv.CardDiscarded, mv.CardDealt, ) assert results[0].target is target assert target.alive assert target.hand.card is deck_before[-1] assert target.discarded_cards[ -1 if target is not player else -2] is target_card # Checking second-to-last as last is the Prince card: assert list(started_round.discard_pile)[-2] is target_card assert list(started_round.deck) == deck_before[:-1]
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)