コード例 #1
0
  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)
コード例 #2
0
 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])
コード例 #3
0
  def test_play_trick_talon_has_more_than_one_card(self):
    game_state = get_game_state_with_multiple_cards_in_the_talon_for_tests()

    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)

    queen_diamonds = game_state.cards_in_hand[PlayerId.TWO][0]
    action = PlayCardAction(PlayerId.TWO, queen_diamonds)
    game_state = action.execute(game_state)
    self.assertEqual(PlayerPair(None, None), game_state.current_trick)
    self.assertEqual(PlayerPair(28, 33), game_state.trick_points)
    self.assertEqual(PlayerPair(queen_hearts, queen_diamonds),
                     game_state.won_tricks[PlayerId.ONE][-1])
    self.assertFalse(queen_hearts in game_state.cards_in_hand[PlayerId.ONE])
    self.assertFalse(queen_diamonds in game_state.cards_in_hand[PlayerId.TWO])
    self.assertTrue(first_talon_card in game_state.cards_in_hand[PlayerId.ONE])
    self.assertTrue(second_talon_card in game_state.cards_in_hand[PlayerId.TWO])
    self.assertEqual([Card(Suit.CLUBS, CardValue.TEN)], game_state.talon)
    self.assertEqual(PlayerId.ONE, game_state.next_player)
コード例 #4
0
  def test_actions_after_the_opponent_played_one_card_talon_is_empty(self):
    game_state = get_game_state_with_empty_talon_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.CLUBS, CardValue.KING)),
      PlayCardAction(PlayerId.TWO, Card(Suit.CLUBS, CardValue.JACK)),
      PlayCardAction(PlayerId.TWO, Card(Suit.CLUBS, CardValue.QUEEN)),
    ]
    self.assertSetEqual(set(expected_actions), set(actions))

    game_state = get_game_state_with_empty_talon_for_tests()
    with GameStateValidator(game_state):
      game_state.next_player = PlayerId.TWO
    action = PlayCardAction(PlayerId.TWO, Card(Suit.CLUBS, 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.CLUBS, CardValue.ACE)),
    ]
    self.assertSetEqual(set(expected_actions), set(actions))
コード例 #5
0
  def test_must_follow_suit_must_use_higher_trump(self):
    """
    Player.ONE plays the trump Queen. Player.TWO has three trump cards.
    The valid cards are only the trump King and Ace.
    """
    game_state = get_game_state_with_empty_talon_for_tests()

    with GameStateValidator(game_state):
      ace_clubs = game_state.cards_in_hand.one[0]
      queen_clubs = game_state.cards_in_hand.two[3]
      game_state.cards_in_hand.two[3] = ace_clubs
      game_state.cards_in_hand.one[0] = queen_clubs

    action = PlayCardAction(PlayerId.ONE, queen_clubs)
    self.assertTrue(action.can_execute_on(game_state))
    game_state = action.execute(game_state)
    num_legal_cards = 0
    valid_cards = [Card(Suit.CLUBS, CardValue.KING),
                   Card(Suit.CLUBS, CardValue.ACE)]
    for card in game_state.cards_in_hand[PlayerId.TWO]:
      action = PlayCardAction(PlayerId.TWO, card)
      is_legal_card = action.can_execute_on(game_state)
      self.assertEqual(card in valid_cards, 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)
コード例 #6
0
  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)
コード例 #7
0
    def test_leaf_node(self):
        game_state = _get_game_state_with_one_card_left()
        play_jack_clubs = PlayCardAction(PlayerId.ONE,
                                         Card(Suit.CLUBS, CardValue.JACK))
        game_state = play_jack_clubs.execute(game_state)
        mcts = Mcts(PlayerId.TWO)
        root_node = mcts.build_tree(game_state)

        self.assertIsNone(root_node.parent)
        self.assertEqual(1, len(root_node.children))
        self.assertEqual([], root_node.untried_actions)
        self.assertTrue(root_node.fully_expanded)
        self.assertFalse(root_node.terminal)
        self.assertEqual(PlayerId.TWO, root_node.player)
        self.assertFalse(root_node.fully_simulated)

        action = list(root_node.children.keys())[0]
        self.assertEqual(
            PlayCardAction(PlayerId.TWO, Card(Suit.SPADES, CardValue.JACK)),
            action)
        leaf: Node = root_node.children[action]
        self.assertIs(root_node, leaf.parent)
        self.assertIsNone(leaf.children)
        self.assertIsNone(leaf.untried_actions)
        self.assertTrue(leaf.fully_expanded)
        self.assertTrue(leaf.terminal)
        self.assertEqual(PlayerId.ONE, leaf.player)
        self.assertAlmostEqual(0.33, leaf.ucb, delta=0.01)
        self.assertTrue(leaf.fully_simulated)
コード例 #8
0
 def test_elimination_play_player_two(self):
     game_state = get_game_state_for_elimination_play_puzzle()
     action = PlayCardAction(PlayerId.ONE, Card(Suit.CLUBS, CardValue.JACK))
     game_state = action.execute(game_state)
     action = PlayCardAction(PlayerId.TWO, Card(Suit.CLUBS, CardValue.KING))
     game_state = action.execute(game_state)
     self.assertEqual(34, game_state.trick_points.one)
     self.assertEqual(40, game_state.trick_points.two)
     mcts = Mcts(PlayerId.TWO)
     root_node = mcts.build_tree(game_state)
     for action, child in root_node.children.items():
         print(action, child)
     for action, child in root_node.children.items():
         self.assertTrue(child.fully_simulated)
         self.assertEqual(PlayerId.ONE, child.player)
         self.assertAlmostEqual(0.33, child.ucb, delta=0.01, msg=action)
コード例 #9
0
 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()))
コード例 #10
0
  def test_play_trick_talon_is_empty(self):
    game_state = get_game_state_with_empty_talon_for_tests()

    ace_clubs = game_state.cards_in_hand[PlayerId.ONE][0]
    action = PlayCardAction(PlayerId.ONE, ace_clubs)
    game_state = action.execute(game_state)
    self.assertEqual(ace_clubs, game_state.current_trick[PlayerId.ONE])
    self.assertEqual(PlayerId.TWO, game_state.next_player)

    jack_clubs = game_state.cards_in_hand[PlayerId.TWO][2]
    action = PlayCardAction(PlayerId.TWO, jack_clubs)
    game_state = action.execute(game_state)
    self.assertEqual(PlayerPair(None, None), game_state.current_trick)
    self.assertEqual(PlayerPair(48, 59), game_state.trick_points)
    self.assertEqual(PlayerPair(ace_clubs, jack_clubs),
                     game_state.won_tricks[PlayerId.ONE][-1])
    self.assertFalse(ace_clubs in game_state.cards_in_hand[PlayerId.ONE])
    self.assertFalse(jack_clubs in game_state.cards_in_hand[PlayerId.TWO])
    self.assertEqual(3, len(game_state.cards_in_hand[PlayerId.ONE]))
    self.assertEqual(3, len(game_state.cards_in_hand[PlayerId.TWO]))
    self.assertEqual(PlayerId.ONE, game_state.next_player)
コード例 #11
0
  def test_play_trick_talon_is_closed(self):
    game_state = get_game_state_for_tests()
    game_state.close_talon()

    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)

    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, 59), 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.assertEqual(4, len(game_state.cards_in_hand[PlayerId.ONE]))
    self.assertEqual(4, len(game_state.cards_in_hand[PlayerId.TWO]))
    self.assertEqual(PlayerId.TWO, game_state.next_player)
コード例 #12
0
 def test_play_trick_talon_closed_opponent_cannot_follow_suit(self):
   game_state = get_game_state_for_tests()
   with GameStateValidator(game_state):
     trick = game_state.won_tricks.two.pop(0)
     game_state.talon.append(trick.one)
     game_state.talon.append(trick.two)
     trick = game_state.won_tricks.two.pop(0)
     game_state.talon.append(trick.one)
     game_state.talon.append(trick.two)
     game_state.trick_points.two = 0
   game_state.close_talon()
   self.assertEqual([False, False, False, False, False],
                    [card.public for card in game_state.talon])
   action = PlayCardAction(PlayerId.ONE, Card(Suit.HEARTS, CardValue.TEN))
   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.TWO, Card(Suit.CLUBS, CardValue.JACK))
   self.assertTrue(action.can_execute_on(game_state))
   game_state = action.execute(game_state)
   self.assertEqual([False, True, True, False, False],
                    [card.public for card in game_state.talon])
コード例 #13
0
 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()))
コード例 #14
0
    def test_know_your_opponent_puzzle(self):
        game_state = get_game_state_for_know_your_opponent_puzzle()
        game_state = self._play_against_another_mcts_player_until_the_end(
            game_state)
        self.assertEqual(0, game_state.game_points.two)

        # If we just run the MctsPlayer for Player.TWO, it doesn't play the Ace
        # of Spades as the second card to challenge Player.ONE as described in the
        # puzzle, so we run this scenario manually here.
        game_state = get_game_state_for_know_your_opponent_puzzle()
        action = PlayCardAction(PlayerId.ONE, Card(Suit.HEARTS,
                                                   CardValue.KING))
        game_state = action.execute(game_state)
        action = PlayCardAction(PlayerId.TWO, Card(Suit.SPADES, CardValue.ACE))
        game_state = action.execute(game_state)
        action = self._mcts_player.request_next_action(
            game_state.next_player_view())
        self.assertEqual(
            PlayCardAction(PlayerId.ONE, Card(Suit.SPADES, CardValue.KING)),
            action)
        game_state = action.execute(game_state)
        game_state = self._play_against_another_mcts_player_until_the_end(
            game_state)
        self.assertEqual(0, game_state.game_points.two)
コード例 #15
0
  def test_play_trick_player_two_wins(self):
    game_state = get_game_state_for_tests()
    trump_card = game_state.trump_card
    last_talon_card = game_state.talon[0]
    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)

    jack_clubs = game_state.cards_in_hand[PlayerId.TWO][2]
    action = PlayCardAction(PlayerId.TWO, jack_clubs)
    game_state = action.execute(game_state)
    self.assertEqual(PlayerPair(None, None), game_state.current_trick)
    self.assertEqual(PlayerPair(22, 58), game_state.trick_points)
    self.assertEqual(PlayerPair(queen_hearts, jack_clubs),
                     game_state.won_tricks[PlayerId.TWO][-1])
    self.assertFalse(queen_hearts in game_state.cards_in_hand[PlayerId.ONE])
    self.assertFalse(jack_clubs in game_state.cards_in_hand[PlayerId.TWO])
    self.assertTrue(trump_card in game_state.cards_in_hand[PlayerId.ONE])
    self.assertTrue(last_talon_card in game_state.cards_in_hand[PlayerId.TWO])
    self.assertEqual([], game_state.talon)
    self.assertIsNone(game_state.trump_card)
    self.assertEqual(PlayerId.TWO, game_state.next_player)
コード例 #16
0
 def test_cannot_play_cards_not_in_hand(self):
   game_state = get_game_state_for_tests()
   for card in Card.get_all_cards():
     action = PlayCardAction(PlayerId.ONE, card)
     self.assertEqual(card in game_state.cards_in_hand[PlayerId.ONE],
                      action.can_execute_on(game_state))
     self.assertEqual(card in game_state.cards_in_hand[PlayerId.ONE],
                      action.can_execute_on(game_state.next_player_view()))
   action = PlayCardAction(PlayerId.ONE,
                           game_state.cards_in_hand[PlayerId.ONE][0])
   self.assertTrue(action.can_execute_on(game_state))
   self.assertTrue(action.can_execute_on(game_state.next_player_view()))
   game_state = action.execute(game_state)
   for card in Card.get_all_cards():
     action = PlayCardAction(PlayerId.TWO, card)
     self.assertEqual(card in game_state.cards_in_hand[PlayerId.TWO],
                      action.can_execute_on(game_state))
     self.assertEqual(card in game_state.cards_in_hand[PlayerId.TWO],
                      action.can_execute_on(game_state.next_player_view()))
コード例 #17
0
 def test_must_follow_suit_must_use_trump(self):
   """Player.TWO has no hearts, so they must use one of the trump cards."""
   game_state = get_game_state_for_tests()
   game_state.close_talon()
   self.assertTrue(game_state.must_follow_suit())
   action = PlayCardAction(PlayerId.ONE,
                           game_state.cards_in_hand[PlayerId.ONE][0])
   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.TWO]:
     action = PlayCardAction(PlayerId.TWO, card)
     is_legal_card = action.can_execute_on(game_state)
     self.assertEqual(card.suit == game_state.trump, 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(3, num_legal_cards)
コード例 #18
0
  def test_must_follow_suit_cannot_play_lower_card_same_suit(self):
    """
    Player.ONE has two cards of the same suit as the card played by Player.TWO,
    one lower and one higher. Player.ONE also has a trump card. The only valid
    card is the higher card having the same suit as the card played by
    Player.TWO.
    """
    game_state = get_game_state_for_tests()

    with GameStateValidator(game_state):
      ten_spades = game_state.cards_in_hand.one[3]
      jack_spades = game_state.cards_in_hand.two[3]
      game_state.cards_in_hand.two[3] = ten_spades
      game_state.cards_in_hand.one[3] = jack_spades

      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())
    action = PlayCardAction(PlayerId.TWO, ten_spades)
    self.assertTrue(action.can_execute_on(game_state))
    game_state = action.execute(game_state)
    ace_spades = Card(Suit.SPADES, CardValue.ACE)
    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 == ace_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(1, num_legal_cards)