def test_actions_when_player_is_to_lead_talon_is_closed(self):
    game_state = get_game_state_for_tests()
    game_state = CloseTheTalonAction(PlayerId.ONE).execute(game_state)

    actions = get_available_actions(game_state)
    self.assertEqual(set(actions),
                     set(get_available_actions(game_state.next_player_view())))
    expected_actions = [
      AnnounceMarriageAction(PlayerId.ONE, Card(Suit.HEARTS, CardValue.QUEEN)),
      AnnounceMarriageAction(PlayerId.ONE, Card(Suit.HEARTS, CardValue.KING)),
      PlayCardAction(PlayerId.ONE, Card(Suit.HEARTS, CardValue.TEN)),
      PlayCardAction(PlayerId.ONE, Card(Suit.SPADES, CardValue.TEN)),
      PlayCardAction(PlayerId.ONE, Card(Suit.SPADES, CardValue.ACE)),
    ]
    self.assertSetEqual(set(expected_actions), set(actions))

    game_state = get_game_state_for_tests()
    with GameStateValidator(game_state):
      game_state.next_player = PlayerId.TWO
    game_state = CloseTheTalonAction(PlayerId.TWO).execute(game_state)

    actions = get_available_actions(game_state)
    self.assertEqual(set(actions),
                     set(get_available_actions(game_state.next_player_view())))
    expected_actions = [
      PlayCardAction(PlayerId.TWO, Card(Suit.DIAMONDS, CardValue.QUEEN)),
      AnnounceMarriageAction(PlayerId.TWO, Card(Suit.CLUBS, CardValue.KING)),
      PlayCardAction(PlayerId.TWO, Card(Suit.CLUBS, CardValue.JACK)),
      AnnounceMarriageAction(PlayerId.TWO, Card(Suit.CLUBS, CardValue.QUEEN)),
      PlayCardAction(PlayerId.TWO, Card(Suit.SPADES, CardValue.JACK)),
    ]
    self.assertSetEqual(set(expected_actions), set(actions))
    def test_won_tricks(self):
        # Cannot win with the same suit, but smaller card.
        trick = self.game_state.won_tricks.one[0]  # K♠, Q♠
        swapped_trick = PlayerPair(one=trick.two, two=trick.one)
        self.game_state.won_tricks.one[0] = swapped_trick
        with self.assertRaisesRegex(InvalidGameStateError,
                                    "ONE cannot win this trick: Q♠, K♠"):
            validate(self.game_state)

        # Cannot win with non-trump card against a trump card.
        self.game_state = get_game_state_for_tests()
        self.game_state.won_tricks.one.append(
            self.game_state.won_tricks.two.pop())
        self.game_state.trick_points = PlayerPair(42, 33)
        with self.assertRaisesRegex(InvalidGameStateError,
                                    "ONE cannot win this trick: X♦, X♣"):
            validate(self.game_state)

        # Different suits, no trump. Could be valid wins for both players, since we
        # don't know who played the first card.
        self.game_state = get_game_state_for_tests()
        card = self.game_state.won_tricks.two[-1].two
        self.game_state.won_tricks.two[-1].two = \
          self.game_state.cards_in_hand.one[3]
        self.game_state.cards_in_hand.one[3] = card
        validate(self.game_state)
        self.game_state.won_tricks.one.append(
            self.game_state.won_tricks.two.pop())
        self.game_state.trick_points = PlayerPair(42, 33)
        validate(self.game_state)
  def test_actions_after_the_opponent_played_one_card(self):
    game_state = get_game_state_for_tests()
    action = PlayCardAction(PlayerId.ONE, Card(Suit.SPADES, CardValue.TEN))
    game_state = action.execute(game_state)

    actions = get_available_actions(game_state)
    self.assertEqual(set(actions),
                     set(get_available_actions(game_state.next_player_view())))
    expected_actions = [
      PlayCardAction(PlayerId.TWO, Card(Suit.DIAMONDS, CardValue.QUEEN)),
      PlayCardAction(PlayerId.TWO, Card(Suit.CLUBS, CardValue.KING)),
      PlayCardAction(PlayerId.TWO, Card(Suit.CLUBS, CardValue.JACK)),
      PlayCardAction(PlayerId.TWO, Card(Suit.CLUBS, CardValue.QUEEN)),
      PlayCardAction(PlayerId.TWO, Card(Suit.SPADES, CardValue.JACK)),
    ]
    self.assertSetEqual(set(expected_actions), set(actions))

    game_state = get_game_state_for_tests()
    with GameStateValidator(game_state):
      game_state.next_player = PlayerId.TWO
    action = PlayCardAction(PlayerId.TWO, Card(Suit.DIAMONDS, CardValue.QUEEN))
    game_state = action.execute(game_state)

    actions = get_available_actions(game_state)
    self.assertEqual(set(actions),
                     set(get_available_actions(game_state.next_player_view())))
    expected_actions = [
      PlayCardAction(PlayerId.ONE, Card(Suit.HEARTS, CardValue.QUEEN)),
      PlayCardAction(PlayerId.ONE, Card(Suit.HEARTS, CardValue.KING)),
      PlayCardAction(PlayerId.ONE, Card(Suit.HEARTS, CardValue.TEN)),
      PlayCardAction(PlayerId.ONE, Card(Suit.SPADES, CardValue.TEN)),
      PlayCardAction(PlayerId.ONE, Card(Suit.SPADES, CardValue.ACE)),
    ]
    self.assertSetEqual(set(expected_actions), set(actions))
  def test_actions_after_the_opponent_played_one_card_talon_is_closed(self):
    game_state = get_game_state_for_tests()
    game_state = CloseTheTalonAction(PlayerId.ONE).execute(game_state)
    action = PlayCardAction(PlayerId.ONE, Card(Suit.SPADES, CardValue.TEN))
    game_state = action.execute(game_state)

    actions = get_available_actions(game_state)
    self.assertEqual(set(actions),
                     set(get_available_actions(game_state.next_player_view())))
    expected_actions = [
      PlayCardAction(PlayerId.TWO, Card(Suit.SPADES, CardValue.JACK)),
    ]
    self.assertSetEqual(set(expected_actions), set(actions))

    game_state = get_game_state_for_tests()
    with GameStateValidator(game_state):
      game_state.next_player = PlayerId.TWO
    game_state = CloseTheTalonAction(PlayerId.TWO).execute(game_state)
    action = PlayCardAction(PlayerId.TWO, Card(Suit.SPADES, CardValue.JACK))
    game_state = action.execute(game_state)

    actions = get_available_actions(game_state)
    self.assertEqual(set(actions),
                     set(get_available_actions(game_state.next_player_view())))
    expected_actions = [
      PlayCardAction(PlayerId.ONE, Card(Suit.SPADES, CardValue.TEN)),
      PlayCardAction(PlayerId.ONE, Card(Suit.SPADES, CardValue.ACE)),
    ]
    self.assertSetEqual(set(expected_actions), set(actions))
Ejemplo n.º 5
0
 def test_cards_missing_in_both_hands(self):
   game_state = get_game_state_for_tests()
   game_view = game_state.next_player_view()
   game_view.cards_in_hand[PlayerId.ONE][0] = None
   unseen_cards = get_unseen_cards(game_view)
   with self.assertRaisesRegex(AssertionError, "Cards missing in both hands"):
     populate_game_view(game_view, unseen_cards)
  def test_must_follow_suit_can_play_any_higher_card_same_suit(self):
    """
    Player.ONE has two cards of the same suit as the card played by Player.TWO,
    both higher. Player.ONE also has a trump card. Any of the two cards from the
    same suit as the card played by Player.TWO are valid.
    """
    game_state = get_game_state_for_tests()

    with GameStateValidator(game_state):
      queen_hearts = game_state.cards_in_hand.one[0]
      queen_clubs = game_state.cards_in_hand.two[4]
      game_state.cards_in_hand.two[4] = queen_hearts
      game_state.cards_in_hand.one[0] = queen_clubs
      game_state.close_talon()
      game_state.next_player = PlayerId.TWO

    self.assertTrue(game_state.must_follow_suit())
    jack_spades = Card(Suit.SPADES, CardValue.JACK)
    action = PlayCardAction(PlayerId.TWO, jack_spades)
    self.assertTrue(action.can_execute_on(game_state))
    game_state = action.execute(game_state)
    num_legal_cards = 0
    for card in game_state.cards_in_hand[PlayerId.ONE]:
      action = PlayCardAction(PlayerId.ONE, card)
      is_legal_card = action.can_execute_on(game_state)
      self.assertEqual(card.suit == Suit.SPADES, is_legal_card, msg=f"{card}")
      self.assertEqual(is_legal_card,
                       action.can_execute_on(game_state.next_player_view()))
      if is_legal_card:
        num_legal_cards += 1
    self.assertEqual(2, num_legal_cards)
    def test_function_with_valid_changes(self):
        @validate_game_states
        def func(game_state: GameState) -> int:
            game_state.next_player = game_state.next_player.opponent()
            return 42

        self.assertEqual(42, func(get_game_state_for_tests()))
def _generate_data(cheater: bool, options: MctsPlayerOptions,
                   constant_budget: bool):
    dataframes = []
    fully_simulated_game_states = {
        "You first. No, you first":
        get_game_state_for_you_first_no_you_first_puzzle(),
        "Elimination play":
        get_game_state_for_elimination_play_puzzle(),
        "Playing to win the last trick":
        get_game_state_for_playing_to_win_the_last_trick_puzzle(),
        "Tempo":
        get_game_state_for_tempo_puzzle(),
        "Who laughs last":
        get_game_state_for_who_laughs_last_puzzle(),
        "Forcing the issue":
        get_game_state_for_forcing_the_issue_puzzle(),
        "Game state for tests":
        get_game_state_for_tests(),
    }
    dataframes.extend(
        _run_simulations(fully_simulated_game_states, cheater, options,
                         constant_budget))
    partially_simulated_game_states = {}
    for seed in [0, 20, 40, 60, 100]:
        partially_simulated_game_states[f"Random GameState (seed={seed})"] = \
          GameState.new(dealer=PlayerId.ONE, random_seed=seed)
    dataframes.extend(
        _run_simulations(partially_simulated_game_states, cheater, options,
                         constant_budget))
    dataframes.extend(
        _run_simulations(same_game_state_after_each_trick_scenarios(20),
                         cheater, options, constant_budget))
    dataframe = pandas.concat(dataframes, ignore_index=True)
    # noinspection PyTypeChecker
    dataframe.to_csv(_get_csv_path(cheater), index=False)
  def test_play_trick_winner_has_pending_marriage_points(self):
    game_state = get_game_state_for_tests()
    with GameStateValidator(game_state):
      for trick in game_state.won_tricks[PlayerId.TWO]:
        game_state.trick_points[PlayerId.TWO] -= trick.one.card_value
        game_state.trick_points[PlayerId.TWO] -= trick.two.card_value
        game_state.talon.extend([trick.one, trick.two])
      game_state.trick_points = PlayerPair(22, 0)
      game_state.won_tricks[PlayerId.TWO] = []

    first_talon_card = game_state.talon[0]
    second_talon_card = game_state.talon[1]

    queen_hearts = game_state.cards_in_hand[PlayerId.ONE][0]
    action = PlayCardAction(PlayerId.ONE, queen_hearts)
    game_state = action.execute(game_state)
    self.assertEqual(queen_hearts, game_state.current_trick[PlayerId.ONE])
    self.assertEqual(PlayerId.TWO, game_state.next_player)
    self.assertEqual([Suit.DIAMONDS], game_state.marriage_suits[PlayerId.TWO])
    self.assertEqual(0, game_state.trick_points[PlayerId.TWO])

    queen_clubs = game_state.cards_in_hand[PlayerId.TWO][4]
    action = PlayCardAction(PlayerId.TWO, queen_clubs)
    game_state = action.execute(game_state)
    self.assertEqual(PlayerPair(None, None), game_state.current_trick)
    self.assertEqual(PlayerPair(22, 26), game_state.trick_points)
    self.assertEqual(PlayerPair(queen_hearts, queen_clubs),
                     game_state.won_tricks[PlayerId.TWO][-1])
    self.assertFalse(queen_hearts in game_state.cards_in_hand[PlayerId.ONE])
    self.assertFalse(queen_clubs in game_state.cards_in_hand[PlayerId.TWO])
    self.assertTrue(second_talon_card in game_state.cards_in_hand[PlayerId.ONE])
    self.assertTrue(first_talon_card in game_state.cards_in_hand[PlayerId.TWO])
    self.assertEqual(PlayerId.TWO, game_state.next_player)
 def test_play_trick_talon_closed_opponent_cannot_follow_suit_or_trump(self):
   game_state = get_game_state_for_tests()
   with GameStateValidator(game_state):
     trick = game_state.won_tricks.one.pop(0)
     game_state.talon.append(trick.one)
     game_state.talon.append(trick.two)
     game_state.trick_points.one -= trick.one.card_value
     game_state.trick_points.one -= trick.two.card_value
     trick = game_state.won_tricks.two.pop(-1)
     game_state.talon.append(trick.one)
     game_state.talon.append(trick.two)
     game_state.trick_points.two -= trick.one.card_value
     game_state.trick_points.two -= trick.two.card_value
     game_state.next_player = PlayerId.TWO
   game_state.close_talon()
   self.assertEqual([False, False, False, False, False],
                    [card.public for card in game_state.talon])
   action = PlayCardAction(PlayerId.TWO, Card(Suit.DIAMONDS, CardValue.QUEEN))
   self.assertTrue(action.can_execute_on(game_state))
   game_state = action.execute(game_state)
   self.assertEqual([False, False, False, False, False],
                    [card.public for card in game_state.talon])
   action = PlayCardAction(PlayerId.ONE, Card(Suit.HEARTS, CardValue.QUEEN))
   self.assertTrue(action.can_execute_on(game_state))
   game_state = action.execute(game_state)
   self.assertEqual([True, False, False, True, True],
                    [card.public for card in game_state.talon])
 def test_cannot_execute_illegal_action(self):
   game_state = get_game_state_for_tests()
   queen_clubs = Card(Suit.CLUBS, CardValue.QUEEN)
   action = AnnounceMarriageAction(PlayerId.TWO, queen_clubs)
   self.assertFalse(action.can_execute_on(game_state))
   with self.assertRaises(AssertionError):
     action.execute(game_state)
 def test_invalid_when_exiting_other_exception_is_raised(self):
     game_state = get_game_state_for_tests()
     with self.assertRaisesRegex(InvalidGameStateError,
                                 "Invalid trick points"):
         with GameStateValidator(game_state):
             game_state.trick_points = PlayerPair(0, 0)
             raise ValueError(
                 "This will be replaced by InvalidGameStateError")
 def test_cannot_exchange_trump_if_not_in_players_hand(self):
   game_state = get_game_state_for_tests()
   trump_jack = Card(suit=game_state.trump, card_value=CardValue.JACK)
   self.assertFalse(trump_jack in game_state.cards_in_hand[PlayerId.ONE])
   self.assertTrue(game_state.is_to_lead(PlayerId.ONE))
   self.assertFalse(game_state.is_talon_closed)
   action = ExchangeTrumpCardAction(PlayerId.ONE)
   self.assertFalse(action.can_execute_on(game_state))
   self.assertFalse(action.can_execute_on(game_state.next_player_view()))
 def test_cannot_exchange_trump_when_talon_is_closed(self):
   game_state = get_game_state_for_tests()
   action = ExchangeTrumpCardAction(PlayerId.TWO)
   game_state.next_player = PlayerId.TWO
   self.assertTrue(action.can_execute_on(game_state))
   self.assertTrue(action.can_execute_on(game_state.next_player_view()))
   game_state.close_talon()
   self.assertFalse(action.can_execute_on(game_state))
   self.assertFalse(action.can_execute_on(game_state.next_player_view()))
    def test_marriage_card_not_played(self):
        # One card is in the talon, one card is in the player's hand.
        card = self.game_state.won_tricks.one[-1].two
        self.game_state.won_tricks.one[-1].two = self.game_state.talon[0]
        self.game_state.talon[0] = card
        with self.assertRaisesRegex(InvalidGameStateError,
                                    "♦ was announced, but no card was played"):
            validate(self.game_state)

        # Both cards are still in the player's hand.
        self.game_state = get_game_state_for_tests()
        self.game_state.marriage_suits.one.append(Suit.HEARTS)
        with self.assertRaisesRegex(InvalidGameStateError,
                                    "♥ was announced, but no card was played"):
            validate(self.game_state)

        # Both cards are still in the player's hand, but they just announced it and
        # played one card.
        self.game_state = get_game_state_for_tests()
        king_hearts = self.game_state.cards_in_hand.one[1]
        self.game_state.current_trick.one = king_hearts
        self.game_state.marriage_suits.one.append(Suit.HEARTS)
        self.game_state.trick_points.one += 20
        self.game_state.next_player = PlayerId.TWO
        with self.assertRaisesRegex(InvalidGameStateError,
                                    "Marriage card should be public: Q♥"):
            validate(self.game_state)
        self.game_state.cards_in_hand.one[0].public = True
        validate(self.game_state)

        # Both cards were played, but by different players.
        self.game_state = get_game_state_for_tests()
        self.game_state.marriage_suits.one.append(Suit.SPADES)
        with self.assertRaisesRegex(InvalidGameStateError,
                                    "ONE announced .* ♠ and played one card"):
            validate(self.game_state)

        # The other player announced the marriage.
        self.game_state = get_game_state_for_tests()
        self.game_state.marriage_suits.one.append(
            self.game_state.marriage_suits.two.pop())
        with self.assertRaisesRegex(InvalidGameStateError,
                                    "♦ was announced, but no card was played"):
            validate(self.game_state)
Ejemplo n.º 16
0
 def test_game_view_with_public_talon_cards(self):
   game_state = get_game_state_for_tests()
   game_state.talon[0].public = True
   game_view = game_state.next_player_view()
   unseen_cards = get_unseen_cards(game_view)
   self.assertEqual([Card(Suit.SPADES, CardValue.JACK),
                     Card(Suit.CLUBS, CardValue.JACK),
                     Card(Suit.CLUBS, CardValue.QUEEN),
                     Card(Suit.CLUBS, CardValue.KING)],
                    unseen_cards)
    def test_function_with_invalid_changes(self):
        @validate_game_states
        def func(game_state: GameState) -> int:
            game_state.trick_points = PlayerPair(0, 0)
            return 42

        self.assertEqual(42, func(GameState.new(PlayerId.ONE)))
        with self.assertRaisesRegex(InvalidGameStateError,
                                    "Invalid trick points"):
            func(get_game_state_for_tests())
Ejemplo n.º 18
0
 def test_generate_all_permutations(self):
   game_state = get_game_state_for_tests()
   game_view = game_state.next_player_view()
   unseen_cards = get_unseen_cards(game_view)
   all_game_states = [populate_game_view(game_view, list(permutation)) for
                      permutation in itertools.permutations(unseen_cards)]
   all_game_states = set(all_game_states)
   self.assertEqual(120,  # factorial(5)
                    len(all_game_states))
   self.assertIn(game_state, all_game_states)
Ejemplo n.º 19
0
 def test_game_view(self):
   game_state = get_game_state_for_tests()
   game_view = game_state.next_player_view()
   unseen_cards = get_unseen_cards(game_view)
   self.assertEqual([Card(Suit.SPADES, CardValue.JACK),
                     Card(Suit.DIAMONDS, CardValue.JACK),
                     Card(Suit.CLUBS, CardValue.JACK),
                     Card(Suit.CLUBS, CardValue.QUEEN),
                     Card(Suit.CLUBS, CardValue.KING)],
                    unseen_cards)
 def test_execute(self):
   game_state = get_game_state_for_tests()
   next_player = game_state.next_player
   action = CloseTheTalonAction(next_player)
   self.assertTrue(action.can_execute_on(game_state))
   game_state = action.execute(game_state)
   self.assertEqual(next_player, game_state.next_player)
   self.assertTrue(game_state.is_talon_closed)
   self.assertEqual(next_player, game_state.player_that_closed_the_talon)
   self.assertEqual(53, game_state.opponent_points_when_talon_was_closed)
Ejemplo n.º 21
0
 def test_too_many_cards_in_permutation(self):
   game_state = get_game_state_for_tests()
   game_view = game_state.next_player_view()
   permutation = [Card(Suit.SPADES, CardValue.JACK),
                  Card(Suit.DIAMONDS, CardValue.JACK),
                  Card(Suit.CLUBS, CardValue.JACK),
                  Card(Suit.CLUBS, CardValue.QUEEN),
                  Card(Suit.CLUBS, CardValue.KING),
                  Card(Suit.DIAMONDS, CardValue.QUEEN)]
   with self.assertRaisesRegex(AssertionError,
                               "Too many cards in permutation"):
     populate_game_view(game_view, permutation)
 def test_invalid_when_entering(self):
     game_state = get_game_state_for_tests()
     game_state.trick_points = PlayerPair(0, 0)
     with self.assertRaisesRegex(InvalidGameStateError,
                                 "Invalid trick points"):
         with GameStateValidator(game_state):
             pass
     with self.assertRaisesRegex(InvalidGameStateError,
                                 "Invalid trick points"):
         with GameStateValidator(game_state):
             # This would make the game_state valid.
             game_state.trick_points = PlayerPair(22, 53)
  def test_can_only_execute_before_leading_a_trick(self):
    # Other player is to lead, cannot exchange trump.
    game_state = get_game_state_for_tests()
    self.assertTrue(game_state.is_to_lead(PlayerId.ONE))
    action = ExchangeTrumpCardAction(PlayerId.TWO)
    self.assertFalse(action.can_execute_on(game_state))
    self.assertFalse(action.can_execute_on(game_state.next_player_view()))

    # PlayerId.TWO is to lead, can exchange trump.
    game_state.next_player = PlayerId.TWO
    self.assertTrue(action.can_execute_on(game_state))
    self.assertTrue(action.can_execute_on(game_state.next_player_view()))
 def test_must_follow_trump_can_discard_any_card(self):
   game_state = get_game_state_for_tests()
   with GameStateValidator(game_state):
     game_state.next_player = PlayerId.TWO
     game_state.close_talon()
   action = PlayCardAction(PlayerId.TWO,
                           game_state.cards_in_hand[PlayerId.TWO][0])
   game_state = action.execute(game_state)
   for card in game_state.cards_in_hand[PlayerId.ONE]:
     action = PlayCardAction(PlayerId.ONE, card)
     self.assertTrue(action.can_execute_on(game_state))
     self.assertTrue(action.can_execute_on(game_state.next_player_view()))
 def test_announce_non_trump_marriage(self):
   game_state = get_game_state_for_tests()
   queen_hearts = Card(Suit.HEARTS, CardValue.QUEEN)
   action = AnnounceMarriageAction(PlayerId.ONE, queen_hearts)
   self.assertTrue(action.can_execute_on(game_state))
   game_state = action.execute(game_state)
   self.assertEqual(42, game_state.trick_points[PlayerId.ONE])
   self.assertEqual(queen_hearts, game_state.current_trick[PlayerId.ONE])
   self.assertEqual([Suit.HEARTS], game_state.marriage_suits[PlayerId.ONE])
   self.assertEqual(PlayerId.TWO, game_state.next_player)
   king_hearts = game_state.cards_in_hand[PlayerId.ONE][1]
   self.assertTrue(king_hearts.public)
 def test_announcing_marriage_is_enough_to_win_the_game(self):
   game_state = get_game_state_for_tests()
   with GameStateValidator(game_state):
     game_state.next_player = PlayerId.TWO
   king_clubs = Card(Suit.CLUBS, CardValue.KING)
   action = AnnounceMarriageAction(PlayerId.TWO, king_clubs)
   self.assertTrue(action.can_execute_on(game_state))
   game_state = action.execute(game_state)
   queen_clubs = game_state.cards_in_hand[PlayerId.TWO][4]
   self.assertTrue(queen_clubs.public)
   self.assertEqual(93, game_state.trick_points[PlayerId.TWO])
   self.assertTrue(game_state.is_game_over)
 def test_execute(self):
   game_state = get_game_state_for_tests()
   action = ExchangeTrumpCardAction(PlayerId.TWO)
   game_state.next_player = PlayerId.TWO
   self.assertTrue(action.can_execute_on(game_state))
   trump_card = game_state.trump_card
   trump_jack = Card(suit=game_state.trump, card_value=CardValue.JACK)
   game_state = action.execute(game_state)
   self.assertEqual(game_state.trump_card, trump_jack)
   self.assertTrue(trump_card in game_state.cards_in_hand[PlayerId.TWO])
   index = game_state.cards_in_hand[PlayerId.TWO].index(trump_card)
   self.assertTrue(game_state.cards_in_hand[PlayerId.TWO][index].public)
   self.assertEqual(PlayerId.TWO, game_state.next_player)
 def test_can_only_execute_before_leading_a_trick(self):
   game_state = get_game_state_for_tests()
   queen_hearts = Card(Suit.HEARTS, CardValue.QUEEN)
   action = AnnounceMarriageAction(PlayerId.ONE, queen_hearts)
   self.assertTrue(action.can_execute_on(game_state))
   self.assertTrue(action.can_execute_on(game_state.next_player_view()))
   king_clubs = Card(Suit.CLUBS, CardValue.KING)
   action = AnnounceMarriageAction(PlayerId.TWO, king_clubs)
   self.assertFalse(action.can_execute_on(game_state))
   self.assertFalse(action.can_execute_on(game_state.next_player_view()))
   game_state.next_player = PlayerId.TWO
   self.assertTrue(action.can_execute_on(game_state))
   self.assertTrue(action.can_execute_on(game_state.next_player_view()))
 def test_can_only_execute_on_players_turn(self):
   game_state = get_game_state_for_tests()
   card = game_state.cards_in_hand[PlayerId.ONE][0]
   action_one = PlayCardAction(PlayerId.ONE, card)
   self.assertTrue(action_one.can_execute_on(game_state))
   self.assertTrue(action_one.can_execute_on(game_state.next_player_view()))
   action_two = PlayCardAction(PlayerId.TWO,
                               game_state.cards_in_hand[PlayerId.TWO][0])
   self.assertFalse(action_two.can_execute_on(game_state))
   self.assertFalse(action_two.can_execute_on(game_state.next_player_view()))
   game_state = action_one.execute(game_state)
   self.assertFalse(action_one.can_execute_on(game_state))
   self.assertFalse(action_one.can_execute_on(game_state.next_player_view()))
   self.assertTrue(action_two.can_execute_on(game_state))
   self.assertTrue(action_two.can_execute_on(game_state.next_player_view()))
 def test_announce_trump_marriage(self):
   game_state = get_game_state_for_tests()
   with GameStateValidator(game_state):
     game_state.next_player = PlayerId.TWO
   queen_clubs = Card(Suit.CLUBS, CardValue.QUEEN)
   action = AnnounceMarriageAction(PlayerId.TWO, queen_clubs)
   self.assertTrue(action.can_execute_on(game_state))
   game_state = action.execute(game_state)
   self.assertEqual(93, game_state.trick_points[PlayerId.TWO])
   self.assertEqual(queen_clubs, game_state.current_trick[PlayerId.TWO])
   self.assertEqual([Suit.DIAMONDS, Suit.CLUBS],
                    game_state.marriage_suits[PlayerId.TWO])
   self.assertEqual(PlayerId.ONE, game_state.next_player)
   king_clubs = game_state.cards_in_hand[PlayerId.TWO][1]
   self.assertTrue(king_clubs.public)