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_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)
 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])
Example #4
0
    def test_equals(self):
        # given
        card_a = Card(Card.Suit.DIAMOND, Card.Face.SEVEN)
        card_b = Card(Card.Suit.DIAMOND, Card.Face.SEVEN)

        # then
        self.assertEquals(card_a, card_b)
Example #5
0
    def test_notEquals_differentFace(self):
        # given
        card_a = Card(Card.Suit.DIAMOND, Card.Face.SEVEN)
        card_b = Card(Card.Suit.DIAMOND, Card.Face.EIGHT)

        # then
        self.assertNotEquals(card_a, card_b)
Example #6
0
 def test_aspect_ratio_is_set_in_constructor(self):
     card_widget = CardWidget(Card(Suit.SPADES, CardValue.ACE),
                              aspect_ratio=0.5)
     self.assertEqual([50, 100], card_widget.children[0].size)
     card_widget = CardWidget(Card(Suit.SPADES, CardValue.ACE),
                              aspect_ratio=0.25)
     self.assertEqual([25, 100], card_widget.children[0].size)
  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))
Example #8
0
    def _on_lead_do_not_follow_suit(self,
                                    game_view: GameState) -> PlayerAction:
        # If the cards that cannot be won by the opponent can get us to the end,
        # start playing them.
        action = self._play_winning_cards(game_view)
        if action is not None:
            return action

        # If we cannot win yet, and we have a marriage, announce it. If the Ace and
        # Ten from that suit cannot be in the opponents hand, play the King.
        if self._marriage_suit is not None:
            logging.debug("HeuristicPlayer: Announcing marriage for %s",
                          self._marriage_suit)
            king = Card(self._marriage_suit, CardValue.KING)
            ten = Card(self._marriage_suit, CardValue.TEN)
            ace = Card(self._marriage_suit, CardValue.ACE)
            if (ten in self._my_cards or ten in self._played_cards) and \
                (ace in self._my_cards or ace in self._played_cards):
                return AnnounceMarriageAction(self.id, king)
            return AnnounceMarriageAction(self.id, king.marriage_pair)

        # If we expect that the opponent has more trumps and we have big cards
        # (i.e., tens or aces), play one of the high card to force the opponent to
        # either play a trump or give up a lot of points.
        card = self._maybe_trump_control(game_view)
        if card is not None:
            return PlayCardAction(self.id, card)

        # Discard one of the small cards.
        card = self._best_discard(game_view)
        logging.debug("HeuristicPlayer: Discarding %s", card)
        return PlayCardAction(self.id, card)
Example #9
0
 def test_init_args_order_and_type(self):
   # Swaps the order of the arguments.
   with self.assertRaisesRegex(TypeError, "suit must be an instance of Suit"):
     Card(CardValue.ACE, Suit.DIAMONDS)
   with self.assertRaisesRegex(TypeError,
                               "card_value must be an instance of CardValue"):
     Card(Suit.DIAMONDS, Suit.DIAMONDS)
Example #10
0
    def test_reset_withoutDealer(self):
        # given
        self.game.bid_value = 24
        self.game.dealer = 2
        self.game.skat.append(Card(Card.Suit.DIAMOND, Card.Face.SEVEN))
        self.game.players[0].cards.append(
            Card(Card.Suit.DIAMOND, Card.Face.EIGHT))
        self.game.players[1].cards.append(
            Card(Card.Suit.DIAMOND, Card.Face.NINE))
        self.game.players[2].cards.append(
            Card(Card.Suit.DIAMOND, Card.Face.TEN))
        self.game.passed_bid_players.append(self.game.players[0])

        # when
        self.game.reset()

        # then
        # clear cards had to be called
        self.assertEquals(len(self.game.skat), 0)
        self.assertEquals(len(self.game.players[0].cards), 0)
        self.assertEquals(len(self.game.players[1].cards), 0)
        self.assertEquals(len(self.game.players[2].cards), 0)
        # reset bid value
        self.assertEquals(self.game.bid_value, -1)
        # reset game variant
        self.assertEquals(self.game.game_variant, None)
        # reset passed bid player list
        self.assertEquals(len(self.game.passed_bid_players), 0)
        # untouched dealer
        self.assertEquals(self.game.dealer, 2)
Example #11
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)
Example #12
0
    def test_reset_witDealer(self):
        # given
        self.game.bid_value = 24
        self.game.dealer = 2
        self.game.skat.append(Card(Card.Suit.DIAMOND, Card.Face.SEVEN))
        self.game.players[0].cards.append(
            Card(Card.Suit.DIAMOND, Card.Face.EIGHT))
        self.game.players[1].cards.append(
            Card(Card.Suit.DIAMOND, Card.Face.NINE))
        self.game.players[2].cards.append(
            Card(Card.Suit.DIAMOND, Card.Face.TEN))

        # when
        self.game.reset(True)

        # then
        # cleared cards
        self.assertEquals(len(self.game.skat), 0)
        self.assertEquals(len(self.game.players[0].cards), 0)
        self.assertEquals(len(self.game.players[1].cards), 0)
        self.assertEquals(len(self.game.players[2].cards), 0)
        # reset bid value
        self.assertEquals(self.game.bid_value, -1)
        # reset game variant
        self.assertEquals(self.game.game_variant, None)
        # reset dealer
        self.assertEquals(self.game.dealer, -1)
    def test_compareJacks_invalidJacksFails(self):
        # given
        no_jack_a = Card(Card.Suit.CLUB, Card.Face.TEN)
        no_jack_b = Card(Card.Suit.DIAMOND, Card.Face.NINE)

        # when/then
        self.assertRaises(TypeError, self.game_variant.compare_jacks,
                          no_jack_a, no_jack_b)
    def test_compareJacks_invalidLowerJackFails(self):
        # given
        higher_jack = Card(Card.Suit.CLUB, Card.Face.JACK)
        no_jack = Card(Card.Suit.CLUB, Card.Face.TEN)

        # when/then
        self.assertRaises(TypeError, self.game_variant.compare_jacks,
                          higher_jack, no_jack)
Example #15
0
 def test_marriage_pair(self):
   for suit in Suit:
     king = Card(suit, CardValue.KING)
     queen = Card(suit, CardValue.QUEEN)
     self.assertEqual(king, queen.marriage_pair)
     self.assertEqual(queen, king.marriage_pair)
   with self.assertRaises(AssertionError):
     _ = Card(Suit.DIAMONDS, CardValue.TEN).marriage_pair
  def test_cancel_two_cards_animation_with_callback(self):
    card_widget_1 = CardWidget(Card(Suit.SPADES, CardValue.QUEEN))
    card_widget_1.pos = 0, 0
    card_widget_2 = CardWidget(Card(Suit.SPADES, CardValue.KING))
    card_widget_2.pos = self.window.size[0], 0
    float_layout = FloatLayout()
    float_layout.add_widget(card_widget_1)
    float_layout.add_widget(card_widget_2)
    self.render(float_layout)

    self.assert_pixels_almost_equal([0, 0], card_widget_1.pos)
    self.assert_pixels_almost_equal([self.window.size[0], 0], card_widget_2.pos)
    animation_controller = AnimationController()
    animation_1 = Animation(x=self.window.size[0], y=self.window.size[1],
                            duration=5)
    on_complete_callback_1 = Mock()
    animation_1.bind(on_complete=on_complete_callback_1)
    animation_controller.add_card_animation(card_widget_1, animation_1)
    animation_2 = Animation(x=0, y=self.window.size[1],
                            duration=2 * animation_1.duration)
    on_complete_callback_2 = Mock()
    animation_2.bind(on_complete=on_complete_callback_2)
    animation_controller.add_card_animation(card_widget_2, animation_2)
    on_both_animations_complete_callback = Mock()
    self.assertFalse(animation_controller.is_running)
    animation_controller.start(on_both_animations_complete_callback)
    self.assertTrue(animation_controller.is_running)

    on_complete_callback_1.assert_not_called()
    on_complete_callback_2.assert_not_called()
    on_both_animations_complete_callback.assert_not_called()

    # Advance a couple of frames to move the cards a little bit, but not
    # complete any animation.
    self.advance_frames(5)
    self.assertNotEqual(0, card_widget_1.x)
    self.assertNotEqual(0, card_widget_1.y)
    self.assertNotEqual(self.window.size[0], card_widget_2.x)
    self.assertNotEqual(0, card_widget_2.y)

    # No callback should be called.
    on_complete_callback_1.assert_not_called()
    on_complete_callback_2.assert_not_called()
    on_both_animations_complete_callback.assert_not_called()

    # Cancel the animations.
    self.assertTrue(animation_controller.is_running)
    animation_controller.cancel()
    self.assertFalse(animation_controller.is_running)

    # All callbacks should be called.
    on_complete_callback_1.assert_called_once()
    on_complete_callback_2.assert_called_once()
    on_both_animations_complete_callback.assert_called_once()

    # Verify that the AnimationController can be reused.
    animation_controller.add_card_animation(card_widget_1, animation_1)
 def test_duck_puzzle(self):
     game_view = get_game_view_for_duck_puzzle()
     action = self._mcts_player.request_next_action(game_view)
     print(f"Selected action: {action}")
     expected_actions = {
         PlayCardAction(PlayerId.ONE, Card(Suit.SPADES, CardValue.ACE)),
         PlayCardAction(PlayerId.ONE, Card(Suit.SPADES, CardValue.TEN))
     }
     self.assertIn(action, expected_actions)
    def test_isTrump_TrumpTrue(self):
        # when/then
        for suit in Card.Suit:
            self.assertTrue(
                self.game_variant.is_trump(Card(suit, Card.Face.JACK)))

        for face in Card.Face:
            self.assertTrue(
                self.game_variant.is_trump(Card(Card.Suit.CLUB, face)))
    def test_getHighestCard_differentFaceAndSuit(self):
        # given
        diamonds_seven = Card(Card.Suit.DIAMOND, Card.Face.SEVEN)
        hearts_eight = Card(Card.Suit.HEARTS, Card.Face.EIGHT)
        spade_nine = Card(Card.Suit.SPADE, Card.Face.NINE)

        # when/then
        result = self.game_variant.get_highest_card(
            [spade_nine, hearts_eight, diamonds_seven])
        self.assertEquals(Card(Card.Suit.SPADE, Card.Face.NINE), result)
Example #20
0
    def test_getCurrentTurnPlayer_thirdHand(self):
        # given
        self.trick.add(self.player2, Card(Card.Suit.DIAMOND, Card.Face.SEVEN))
        self.trick.add(self.player3, Card(Card.Suit.DIAMOND, Card.Face.EIGHT))

        # when
        result = self.trick.get_current_player()

        # then
        self.assertEqual(self.player1, result)
Example #21
0
    def test_isComplete_False(self):
        # given
        self.trick.add(self.player1, Card(Card.Suit.DIAMOND, Card.Face.SEVEN))
        self.trick.add(self.player2, Card(Card.Suit.DIAMOND, Card.Face.EIGHT))

        # when
        result = self.trick.is_complete()

        # then
        self.assertFalse(result)
Example #22
0
 def test_card_value_and_suit_cannot_be_none(self):
   with self.assertRaisesRegex(ValueError,
                               "card_value and suit cannot be None"):
     print(Card(None, CardValue.ACE))
   with self.assertRaisesRegex(ValueError,
                               "card_value and suit cannot be None"):
     print(Card(Suit.DIAMONDS, None))
   with self.assertRaisesRegex(ValueError,
                               "card_value and suit cannot be None"):
     print(Card(None, None))
    def test_compareCards_sameSuit(self):
        # given
        diamond_seven = Card(Card.Suit.DIAMOND, Card.Face.SEVEN)
        diamond_eight = Card(Card.Suit.DIAMOND, Card.Face.EIGHT)

        # when/then
        self.assertEquals(
            self.game_variant.compare_cards(diamond_eight, diamond_seven), 1)
        self.assertEquals(
            self.game_variant.compare_cards(diamond_seven, diamond_eight), -1)
    def test_getHighestCard_sameSuit(self):
        # given
        diamonds_ten = Card(Card.Suit.DIAMOND, Card.Face.TEN)
        diamonds_queen = Card(Card.Suit.DIAMOND, Card.Face.QUEEN)
        diamonds_king = Card(Card.Suit.DIAMOND, Card.Face.KING)

        # when/then
        result = self.game_variant.get_highest_card(
            [diamonds_queen, diamonds_king, diamonds_ten])
        self.assertEquals(Card(Card.Suit.DIAMOND, Card.Face.TEN), result)
    def test_getHighestCard_sameFace(self):
        # given
        diamonds_seven = Card(Card.Suit.DIAMOND, Card.Face.SEVEN)
        hearts_seven = Card(Card.Suit.HEARTS, Card.Face.SEVEN)
        spade_seven = Card(Card.Suit.SPADE, Card.Face.SEVEN)

        # when/then
        result = self.game_variant.get_highest_card(
            [hearts_seven, spade_seven, diamonds_seven])
        self.assertEquals(Card(Card.Suit.HEARTS, Card.Face.SEVEN), result)
    def test_getHighestCard_jackAndSuit(self):
        # given
        diamonds_jack = Card(Card.Suit.DIAMOND, Card.Face.JACK)
        diamonds_king = Card(Card.Suit.DIAMOND, Card.Face.KING)
        club_ace = Card(Card.Suit.CLUB, Card.Face.ACE)

        # when/then
        result = self.game_variant.get_highest_card(
            [diamonds_king, club_ace, diamonds_jack])
        self.assertEquals(Card(Card.Suit.DIAMOND, Card.Face.JACK), result)
    def test_getHighestCard_jacks(self):
        # given
        diamonds_jack = Card(Card.Suit.DIAMOND, Card.Face.JACK)
        hearts_jack = Card(Card.Suit.HEARTS, Card.Face.JACK)
        spade_jack = Card(Card.Suit.SPADE, Card.Face.JACK)

        # when/then
        result = self.game_variant.get_highest_card(
            [spade_jack, hearts_jack, diamonds_jack])
        self.assertEquals(Card(Card.Suit.SPADE, Card.Face.JACK), result)
    def test_getHighestCard_TrumpAndSuit(self):
        # given
        diamond_ace = Card(Card.Suit.DIAMOND, Card.Face.ACE)
        diamond_king = Card(Card.Suit.DIAMOND, Card.Face.KING)
        club_seven = Card(Card.Suit.CLUB, Card.Face.SEVEN)

        # when/then
        result = self.game_variant.get_highest_card(
            [diamond_king, club_seven, diamond_ace])
        self.assertEquals(Card(Card.Suit.CLUB, Card.Face.SEVEN), result)
    def test_compareCards_sameFace(self):
        # given
        diamonds_seven = Card(Card.Suit.DIAMOND, Card.Face.SEVEN)
        heats_seven = Card(Card.Suit.HEARTS, Card.Face.SEVEN)

        # when/then
        self.assertEquals(
            self.game_variant.compare_cards(heats_seven, diamonds_seven), 0)
        self.assertEquals(
            self.game_variant.compare_cards(diamonds_seven, heats_seven), 0)
 def can_execute_on(self, game_state: GameState) -> bool:
     if not game_state.is_to_lead(self.player_id):
         return False
     queen = Card(self._card.suit, CardValue.QUEEN)
     king = Card(self._card.suit, CardValue.KING)
     if queen not in game_state.cards_in_hand[self.player_id]:
         return False
     if king not in game_state.cards_in_hand[self.player_id]:
         return False
     return True