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_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_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)
    def __init__(self, game_options: Optional[GameOptions] = None, **kwargs):
        """
    Instantiates a new GameWidget and all its children widgets. All the widgets
    are empty (i.e., no cards).
    """
        # Store or initialize the game options. This has to be done before the call
        # to Widget.__init__() so the options are available when the game_widget.kv
        # file is parsed.
        self._game_options = game_options or GameOptions()

        super().__init__(**kwargs)

        # Dictionary used to store all the cards widgets.
        self._cards: Dict[Card, CardWidget] = {}

        # A reference to the area where the cards are moved when one player plays a
        # card.
        self._play_area = self.ids.play_area.__self__
        # Store the current play area size in order to update the position of the
        # already played cards accordingly, when the window is resized.
        self._prev_play_area_size = self._play_area.size[
            0], self._play_area.size[1]
        self._prev_play_area_pos = self._play_area.pos[0], self._play_area.pos[
            1]
        self._play_area.bind(size=lambda *_: self._update_play_area_cards())

        # The cards in the players' hands, sorted in display order.
        self._sorted_cards: Optional[PlayerPair[List[Card]]] = None

        # Widgets that store the cards.
        self._player_card_widgets: Optional[PlayerPair[CardSlotsLayout]] = None
        self._tricks_widgets: Optional[PlayerPair[CardSlotsLayout]] = None
        self._talon: Optional[TalonWidget] = None

        # Image that displays the trump suit, if the talon is empty.
        self._trump_suit_image: Optional[Image] = None

        # Labels used to display the trick points and game points.
        self._trick_score_labels: PlayerPair[Label] = PlayerPair(
            one=self.ids.human_trick_score_label.__self__,
            two=self.ids.computer_trick_score_label.__self__)
        self._game_score_labels: PlayerPair[Label] = PlayerPair(
            one=self.ids.human_game_score_label.__self__,
            two=self.ids.computer_game_score_label.__self__)

        # Stores the callback that is passed by the GameController when it requests
        # a new player action.
        self._action_callback: Optional[Callable[[PlayerAction], None]] = None

        # When a player action is requested, this dict stores the default action
        # associated to each card that can be double clicked.
        self._actions: Dict[CardWidget, PlayerAction] = {}

        # AnimationController that coordinates all card animations.
        self._animation_controller = AnimationController()
        self.fbind('size', self._cancel_animations)

        self._init_widgets()
Beispiel #5
0
    def test_stop_is_called_with_pending_callback(self):
        self.render(None)

        game_widget = Mock()
        players = PlayerPair(Mock(), Mock())
        players.one.is_cheater.return_value = False
        players.two.is_cheater.return_value = False
        score_view = Mock()
        # noinspection PyTypeChecker
        game_controller = GameController(game_widget, players, score_view)

        bummerl = Bummerl(next_dealer=PlayerId.ONE)
        bummerl.start_game(seed=2)
        actions = get_actions_for_one_complete_game(PlayerId.TWO)

        expected_game_state = GameState.new(dealer=PlayerId.ONE, random_seed=2)

        game_controller.start(bummerl)

        # Initializes the game widget.
        game_widget.reset.assert_called_once()
        game_widget.init_from_game_state.assert_called_once()
        actual_game_state, done_callback, game_points = \
          game_widget.init_from_game_state.call_args.args
        self.assertEqual(expected_game_state, actual_game_state)
        self.assertEqual(PlayerPair(0, 0), game_points)
        game_widget.reset_mock()
        done_callback()

        # Player action is requested.
        action = actions[0]
        players[action.player_id].request_next_action.assert_called_once()
        actual_game_state, action_callback, actual_game_points = \
          players[action.player_id].request_next_action.call_args.args

        self.assertEqual(bummerl.game_points, actual_game_points)
        expected_game_state = action.execute(expected_game_state)
        players[action.player_id].reset_mock()

        # GameController.stop() is called before the GameWidget calls
        # action_callback().
        game_controller.stop()

        # Player responds with an action.
        action_callback(action)

        # GameWidget.on_action() is called to update the UI.
        game_widget.on_action.assert_called_once()
        actual_action, done_callback = game_widget.on_action.call_args.args
        self.assertEqual(action, actual_action)
        game_widget.reset_mock()
        done_callback()

        # The GameController requests no action from the next player.
        next_player = expected_game_state.next_player
        players[next_player].request_next_action.assert_not_called()
 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_pickling(self):
        game = Game(PlayerId.ONE, seed=2)
        self.assertEqual(Suit.DIAMONDS, game.game_state.trump)

        actions = [
            # Player TWO wins the first trick. Score: 0-6.
            PlayCardAction(PlayerId.TWO, Card(Suit.HEARTS, CardValue.JACK)),
            PlayCardAction(PlayerId.ONE, Card(Suit.CLUBS, CardValue.KING)),

            # Player TWO closes the talon.
            CloseTheTalonAction(PlayerId.TWO),

            # Player TWO wins the second trick. Score: 0-18.
            PlayCardAction(PlayerId.TWO, Card(Suit.DIAMONDS, CardValue.TEN)),
            PlayCardAction(PlayerId.ONE, Card(Suit.DIAMONDS, CardValue.JACK)),

            # Player TWO wins the third trick. Score: 0-31.
            PlayCardAction(PlayerId.TWO, Card(Suit.HEARTS, CardValue.TEN)),
            PlayCardAction(PlayerId.ONE, Card(Suit.SPADES, CardValue.QUEEN)),

            # Player ONE wins the forth trick. Score: 13-31.
            PlayCardAction(PlayerId.TWO, Card(Suit.CLUBS, CardValue.JACK)),
            PlayCardAction(PlayerId.ONE, Card(Suit.CLUBS, CardValue.ACE)),

            # Player TWO wins the fifth trick. Score: 13-52.
            PlayCardAction(PlayerId.ONE, Card(Suit.SPADES, CardValue.TEN)),
            PlayCardAction(PlayerId.TWO, Card(Suit.SPADES, CardValue.ACE)),

            # Player TWO wins the sixth trick. Score: 13-67.
            PlayCardAction(PlayerId.TWO, Card(Suit.HEARTS, CardValue.ACE)),
            PlayCardAction(PlayerId.ONE, Card(Suit.SPADES, CardValue.KING))
        ]
        for action in actions[:8]:
            game.play_action(action)
        self.assertFalse(game.game_state.is_game_over)
        self.assertEqual(PlayerPair(0, 31), game.game_state.trick_points)
        self.assertFalse(game.game_state.is_to_lead(PlayerId.ONE))
        self.assertFalse(game.game_state.is_to_lead(PlayerId.TWO))

        unpickled_game: Game = loads(dumps(game))
        self.assertEqual(unpickled_game.game_state, game.game_state)
        self.assertFalse(unpickled_game.game_state.is_game_over)
        self.assertFalse(unpickled_game.game_state.is_to_lead(PlayerId.ONE))

        for action in actions[8:]:
            unpickled_game.play_action(action)

        self.assertTrue(unpickled_game.game_state.is_game_over)
        self.assertEqual(PlayerPair(13, 67),
                         unpickled_game.game_state.trick_points)
        self.assertEqual(PlayerPair(0, 3),
                         unpickled_game.game_state.game_points)
Beispiel #8
0
    def test_two_bummerl_with_random_players(self):
        class TestScoreViewWithBummerlCount:
            # pylint: disable=too-few-public-methods

            def __init__(self, done_callback):
                self._num_bummerls = 0
                self._done_callback = done_callback

            def score_view_delegate(self, score_history, dismiss_callback):
                total_game_points = PlayerPair(0, 0)
                for _, game_points in score_history:
                    total_game_points.one += game_points.one
                    total_game_points.two += game_points.two
                if total_game_points.one > 6 or total_game_points.two > 6:
                    self._num_bummerls += 1
                if self._num_bummerls < 2:
                    dismiss_callback()
                else:
                    self._done_callback()

        game_widget = GameWidget(GameOptions(enable_animations=False))
        players = PlayerPair(ComputerPlayer(RandomPlayer(PlayerId.ONE)),
                             ComputerPlayer(RandomPlayer(PlayerId.TWO)))
        two_bummerls_played = Mock()
        score_view = TestScoreViewWithBummerlCount(two_bummerls_played)

        self.render(game_widget)

        # noinspection PyTypeChecker
        game_controller = GameController(game_widget, players,
                                         score_view.score_view_delegate, 0)
        game_controller.start()
        self.wait_for_mock_callback(two_bummerls_played, timeout_seconds=60)
        game_controller.stop()
Beispiel #9
0
def _get_bummerl_score(bummerl, game_index):
  game_points = PlayerPair(0, 0)
  for i in range(game_index):
    result = bummerl.completed_games[i].game_state.game_points
    game_points.one += result.one
    game_points.two += result.two
  return game_points
 def is_to_lead(self, player_id):
   """
   Checks if we are at the beginning of a trick and the given player is
   expected to make the next move.
   If a player is to lead, it can exchange the trump card or close the talon.
   """
   return self.next_player == player_id and self.current_trick == PlayerPair(
     None, None)
 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 deep_copy(self) -> "GameState":
    """
    Creates and returns a deep copy of this game state. This is faster than
    using copy.deepcopy(), see GameStateCopyTest.test_deep_copy_alternatives*.
    """

    def copy_card(card: Card) -> Card:
      return None if card is None else card.copy()

    cards_in_hand = PlayerPair(
      one=[copy_card(card) for card in self.cards_in_hand.one],
      two=[copy_card(card) for card in self.cards_in_hand.two])
    talon = [copy_card(card) for card in self.talon]
    won_tricks = PlayerPair(
      one=[PlayerPair(copy_card(trick.one), copy_card(trick.two)) for trick in
           self.won_tricks.one],
      two=[PlayerPair(copy_card(trick.one), copy_card(trick.two)) for trick in
           self.won_tricks.two])
    marriage_suits = PlayerPair(one=list(self.marriage_suits.one),
                                two=list(self.marriage_suits.two))
    return GameState(
      cards_in_hand=cards_in_hand, talon=talon,
      trump=self.trump,
      trump_card=copy_card(self.trump_card),
      next_player=self.next_player,
      player_that_closed_the_talon=self.player_that_closed_the_talon,
      opponent_points_when_talon_was_closed=
      self.opponent_points_when_talon_was_closed,
      won_tricks=won_tricks,
      marriage_suits=marriage_suits,
      trick_points=PlayerPair(self.trick_points.one, self.trick_points.two),
      current_trick=PlayerPair(copy_card(self.current_trick.one),
                               copy_card(self.current_trick.two)))
Beispiel #13
0
    def test_auto_save_folder(self):
        with tempfile.TemporaryDirectory() as auto_save_folder:
            saved_games = []

            def _verify_auto_save_data():
                bummerl_filename = os.path.join(auto_save_folder,
                                                "autosave_bummerl.pickle")
                with open(bummerl_filename, "rb") as input_file:
                    bummerl = pickle.load(input_file)
                self.assertEqual(len(saved_games),
                                 len(bummerl.completed_games))
                for i, game in enumerate(bummerl.completed_games):
                    self._assert_game_equal(game, saved_games[i])

            class TestScoreViewWithBummerlCount:
                # pylint: disable=too-few-public-methods

                def __init__(self, done_callback, auto_save_folder):
                    self._num_bummerls = 0
                    self._done_callback = done_callback
                    self._auto_save_folder = auto_save_folder

                def score_view_delegate(self, score_history, dismiss_callback):
                    game_filename = os.path.join(self._auto_save_folder,
                                                 "autosave_game.pickle")
                    with open(game_filename, "rb") as input_file:
                        game = pickle.load(input_file)
                        saved_games.append(game)
                    _verify_auto_save_data()
                    total_game_points = PlayerPair(0, 0)
                    for _, game_points in score_history:
                        total_game_points.one += game_points.one
                        total_game_points.two += game_points.two
                    if total_game_points.one > 6 or total_game_points.two > 6:
                        self._num_bummerls += 1
                    if self._num_bummerls >= 1:
                        dismiss_callback()
                    else:
                        self._done_callback()

            game_widget = GameWidget(GameOptions(enable_animations=False))
            players = PlayerPair(ComputerPlayer(RandomPlayer(PlayerId.ONE)),
                                 ComputerPlayer(RandomPlayer(PlayerId.TWO)))
            one_bummerl_played = Mock()
            score_view = TestScoreViewWithBummerlCount(one_bummerl_played,
                                                       auto_save_folder)

            self.render(game_widget)

            # noinspection PyTypeChecker
            game_controller = GameController(game_widget, players,
                                             score_view.score_view_delegate, 0,
                                             auto_save_folder)
            game_controller.start()
            self.wait_for_mock_callback(one_bummerl_played, timeout_seconds=60)
            game_controller.stop()
 def execute(self, game_state: GameState) -> GameState:
     assert self.can_execute_on(game_state)
     new_game_state = copy.copy(game_state)
     trump_jack = Card(suit=game_state.trump, card_value=CardValue.JACK)
     new_player_cards = [
         card for card in game_state.cards_in_hand[self.player_id]
         if card != trump_jack
     ]
     new_player_cards.append(new_game_state.trump_card)
     if self.player_id == PlayerId.ONE:
         cards_in_hand = PlayerPair(new_player_cards,
                                    game_state.cards_in_hand.two)
     else:
         cards_in_hand = PlayerPair(game_state.cards_in_hand.one,
                                    new_player_cards)
     new_game_state.cards_in_hand = cards_in_hand
     new_game_state.trump_card = trump_jack
     new_game_state.trump_card.public = True
     return new_game_state
    def test_pickling(self):
        bummerl = Bummerl(next_dealer=PlayerId.ONE)
        _simulate_a_complete_game(bummerl.start_game(seed=2))
        bummerl.finalize_game()
        _simulate_a_complete_game(bummerl.start_game(seed=2))

        unpickled_bummerl = loads(dumps(bummerl))

        self.assertIsNot(bummerl, unpickled_bummerl)
        self.assertIsNotNone(unpickled_bummerl.game)
        self.assertEqual(PlayerPair(0, 3), unpickled_bummerl.game_points)
        self.assertEqual(1, len(unpickled_bummerl.completed_games))
        self.assertFalse(unpickled_bummerl.is_over)

        unpickled_bummerl.finalize_game()
        self.assertIsNone(unpickled_bummerl.game)
        self.assertEqual(PlayerPair(3, 3), unpickled_bummerl.game_points)
        self.assertEqual(2, len(unpickled_bummerl.completed_games))
        self.assertFalse(unpickled_bummerl.is_over)
Beispiel #16
0
def evaluate_bummerl(
        bummerl: Bummerl,
        bummerl_id: str = "0",
        options: Optional[MctsPlayerOptions] = None) -> EvalResults:
    options = options or MctsPlayerOptions(
        num_processes=1,
        max_permutations=150,
        max_iterations=667,
        merge_scoring_info_func=average_score_with_tiebreakers)
    players = PlayerPair(CythonMctsPlayer(PlayerId.ONE, False, options),
                         CythonMctsPlayer(PlayerId.TWO, False, options))
    bummerl_score = PlayerPair(0, 0)
    eval_results = []
    for game_id, game in enumerate(bummerl.completed_games):
        eval_results.extend(
            evaluate_game(game, players, bummerl_score, bummerl_id, game_id))
        bummerl_score.one += game.game_state.game_points.one
        bummerl_score.two += game.game_state.game_points.two
    return eval_results
Beispiel #17
0
def _main():
    # filename = "../autosave_bummerl.pickle"
    # with open(filename, "rb") as input_file:
    #   bummerl = pickle.load(input_file)
    # results = evaluate_bummerl(bummerl)
    # print_eval_results(results, None)

    options = MctsPlayerOptions(
        num_processes=1,
        max_permutations=150,
        max_iterations=667,
        merge_scoring_info_func=average_score_with_tiebreakers)
    players = PlayerPair(CythonMctsPlayer(PlayerId.ONE, False, options),
                         CythonMctsPlayer(PlayerId.TWO, False, options))
    bummerl_score = PlayerPair(0, 0)
    with open("../autosave_game.pickle", "rb") as input_file:
        game = pickle.load(input_file)
    print_eval_results(evaluate_game(game, players, bummerl_score, "0", "0"),
                       None)
Beispiel #18
0
def print_eval_results(eval_results: EvalResults,
                       restrict_to_player_id: Optional[PlayerId]):
    column_widths = _get_column_widths(eval_results)
    num_actions = PlayerPair(0, 0)
    sum_scores = PlayerPair(0, 0)
    for eval_result in eval_results:
        player_id = eval_result[2].player_id
        if restrict_to_player_id is not None and player_id != restrict_to_player_id:
            continue
        _print_eval_result(eval_result, column_widths)
        if eval_result[3] is not None:
            num_actions[player_id] += 1
            sum_scores[player_id] += eval_result[3]
    print()
    print("Overall performance:")
    if num_actions.one != 0:
        print("\tONE:\t" + ("{:.5f}".format(sum_scores.one / num_actions.one)))
    if num_actions.two != 0:
        print("\tTWO:\t" + ("{:.5f}".format(sum_scores.two / num_actions.two)))
 def test_who_laughs_last_puzzle(self):
     # Part one
     game_state = get_game_state_for_who_laughs_last_puzzle()
     action = self._mcts_player.request_next_action(
         game_state.next_player_view())
     expected_actions = {
         PlayCardAction(PlayerId.ONE, Card(Suit.HEARTS, CardValue.KING)),
         PlayCardAction(PlayerId.ONE, Card(Suit.HEARTS, CardValue.QUEEN))
     }
     self.assertIn(action, expected_actions)
     game_state = action.execute(game_state)
     if action.card.card_value == CardValue.KING:
         self.assertEqual(PlayerPair(19, 26), game_state.trick_points)
     else:
         self.assertEqual(PlayerPair(18, 26), game_state.trick_points)
     # Part two
     game_state = self._play_against_another_mcts_player_until_the_end(
         game_state)
     self.assertEqual(0, game_state.game_points.two)
 def test_pair_of_lists(self):
     test_pair: PlayerPair[List[int]] = PlayerPair()
     self.assertIsNone(test_pair.one)
     self.assertIsNone(test_pair.two)
     test_pair.one = [1, 2, 3]
     self.assertEqual([1, 2, 3], test_pair.one)
     self.assertIsNone(test_pair.two)
     test_pair.two = [2, 3, 4]
     self.assertEqual([1, 2, 3], test_pair.one)
     self.assertEqual([2, 3, 4], test_pair.two)
     another_test_pair: PlayerPair[List[int]] = PlayerPair()
     self.assertIsNone(another_test_pair.one)
     self.assertIsNone(another_test_pair.two)
     self.assertEqual([1, 2, 3], test_pair.one)
     self.assertEqual([2, 3, 4], test_pair.two)
     another_test_pair.one = [10, 20, 30]
     self.assertEqual([10, 20, 30], another_test_pair.one)
     self.assertIsNone(another_test_pair.two)
     self.assertEqual([1, 2, 3], test_pair.one)
     self.assertEqual([2, 3, 4], test_pair.two)
 def test_pair_of_ints(self):
     test_pair: PlayerPair[int] = PlayerPair()
     self.assertIsNone(test_pair.one)
     self.assertIsNone(test_pair.two)
     test_pair.one = 100
     self.assertEqual(100, test_pair.one)
     self.assertIsNone(test_pair.two)
     test_pair.two = 200
     self.assertEqual(100, test_pair.one)
     self.assertEqual(200, test_pair.two)
     another_test_pair: PlayerPair[int] = PlayerPair()
     self.assertIsNone(another_test_pair.one)
     self.assertIsNone(another_test_pair.two)
     self.assertEqual(100, test_pair.one)
     self.assertEqual(200, test_pair.two)
     another_test_pair.one = 300
     self.assertEqual(300, another_test_pair.one)
     self.assertIsNone(another_test_pair.two)
     self.assertEqual(100, test_pair.one)
     self.assertEqual(200, test_pair.two)
Beispiel #22
0
 def score_view_delegate(self, score_history, dismiss_callback):
     total_game_points = PlayerPair(0, 0)
     for _, game_points in score_history:
         total_game_points.one += game_points.one
         total_game_points.two += game_points.two
     if total_game_points.one > 6 or total_game_points.two > 6:
         self._num_bummerls += 1
     if self._num_bummerls < 2:
         dismiss_callback()
     else:
         self._done_callback()
Beispiel #23
0
def evaluate_one_player_vs_opponent_list(player: str,
                                         opponents: List[str]) -> DataFrame:
    rows = []
    for opponent in opponents:
        print(f"Simulating {player} vs {opponent}")
        players = PlayerPair(player, opponent)
        metrics = evaluate_player_pair_in_parallel(players)
        _print_metrics(metrics)
        rows.append([player, opponent] + _get_results_row(metrics))
    columns = ["player_one", "player_two"] + _get_metrics_column_names()
    return pandas.DataFrame(rows, columns=columns)
Beispiel #24
0
 def test_who_laughs_last_part_two_player_one_always_wins(self):
     game_state = get_game_state_for_who_laughs_last_puzzle()
     mcts = Mcts(PlayerId.ONE)
     root_node = mcts.build_tree(game_state)
     actions = root_node.best_actions()
     self.assertEqual(
         [PlayCardAction(PlayerId.ONE, Card(Suit.HEARTS, CardValue.KING))],
         actions)
     game_state = actions[0].execute(game_state)
     self.assertEqual(PlayerPair(19, 26), game_state.trick_points)
     self._assert_player_one_always_wins(game_state)
Beispiel #25
0
def get_game_state_for_forcing_the_issue_puzzle() -> GameState:
  """
  Generates a game view for the scenario described here:
  http://psellos.com/schnapsen/blog/2012/05/013-forcing.html

  The game state is the following:
    * cards_in_hand: [X♠, Q♥, X♣, A♦, K♦] [X♥, K♥, X♦, Q♦, J♦]
    * trump: ♥
    * trump_card: J♥
    * talon: [A♣], closed
    * next_player: PlayerId.ONE
    * won_tricks: [(K♠, Q♠), (A♥, A♠)], [(J♠, K♣), (J♣, Q♣)]
    * marriage_suits: [], [♣]
    * trick_points: (29, 31)
    * current_trick: (None, J♦)
    * player_that_closed_the_talon: PlayerId.TWO
    * opponent_points_when_talon_was_closed: 29
  """
  cards_in_hand = PlayerPair(
    one=[Card(Suit.SPADES, CardValue.TEN),
         Card(Suit.HEARTS, CardValue.QUEEN),
         Card(Suit.CLUBS, CardValue.TEN),
         Card(Suit.DIAMONDS, CardValue.ACE),
         Card(Suit.DIAMONDS, CardValue.KING)],
    two=[Card(Suit.HEARTS, CardValue.TEN),
         Card(Suit.HEARTS, CardValue.KING),
         Card(Suit.DIAMONDS, CardValue.TEN),
         Card(Suit.DIAMONDS, CardValue.QUEEN),
         Card(Suit.DIAMONDS, CardValue.JACK)])
  trump_card = Card(Suit.HEARTS, CardValue.JACK)
  talon = [Card(Suit.CLUBS, CardValue.ACE)]
  won_tricks = PlayerPair(
    one=[PlayerPair(Card(Suit.SPADES, CardValue.KING),
                    Card(Suit.SPADES, CardValue.QUEEN)),
         PlayerPair(Card(Suit.HEARTS, CardValue.ACE),
                    Card(Suit.SPADES, CardValue.ACE))],
    two=[PlayerPair(Card(Suit.SPADES, CardValue.JACK),
                    Card(Suit.CLUBS, CardValue.KING)),
         PlayerPair(Card(Suit.CLUBS, CardValue.JACK),
                    Card(Suit.CLUBS, CardValue.QUEEN))])
  marriage_suits = PlayerPair(one=[], two=[Suit.CLUBS])
  trick_points = PlayerPair(one=29, two=31)
  game_state = GameState(cards_in_hand=cards_in_hand, trump=trump_card.suit,
                         trump_card=trump_card, talon=talon,
                         won_tricks=won_tricks, trick_points=trick_points,
                         marriage_suits=marriage_suits,
                         next_player=PlayerId.TWO)
  game_state.close_talon()
  game_state.current_trick.two = Card(Suit.DIAMONDS, CardValue.JACK)
  game_state.next_player = PlayerId.ONE
  return game_state
    def test_play_a_full_game(self):
        game = Game(PlayerId.ONE, seed=2)
        self.assertEqual(PlayerId.ONE, game.dealer)
        self.assertEqual(2, game.seed)
        self.assertEqual(Suit.DIAMONDS, game.game_state.trump)

        actions = [
            # Player TWO wins the first trick. Score: 0-6.
            PlayCardAction(PlayerId.TWO, Card(Suit.HEARTS, CardValue.JACK)),
            PlayCardAction(PlayerId.ONE, Card(Suit.CLUBS, CardValue.KING)),

            # Player TWO closes the talon.
            CloseTheTalonAction(PlayerId.TWO),

            # Player TWO wins the second trick. Score: 0-18.
            PlayCardAction(PlayerId.TWO, Card(Suit.DIAMONDS, CardValue.TEN)),
            PlayCardAction(PlayerId.ONE, Card(Suit.DIAMONDS, CardValue.JACK)),

            # Player TWO wins the third trick. Score: 0-31.
            PlayCardAction(PlayerId.TWO, Card(Suit.HEARTS, CardValue.TEN)),
            PlayCardAction(PlayerId.ONE, Card(Suit.SPADES, CardValue.QUEEN)),

            # Player ONE wins the forth trick. Score: 13-31.
            PlayCardAction(PlayerId.TWO, Card(Suit.CLUBS, CardValue.JACK)),
            PlayCardAction(PlayerId.ONE, Card(Suit.CLUBS, CardValue.ACE)),

            # Player TWO wins the fifth trick. Score: 13-52.
            PlayCardAction(PlayerId.ONE, Card(Suit.SPADES, CardValue.TEN)),
            PlayCardAction(PlayerId.TWO, Card(Suit.SPADES, CardValue.ACE)),

            # Player TWO wins the sixth trick. Score: 13-67.
            PlayCardAction(PlayerId.TWO, Card(Suit.HEARTS, CardValue.ACE)),
            PlayCardAction(PlayerId.ONE, Card(Suit.SPADES, CardValue.KING))
        ]
        for i, action in enumerate(actions):
            game.play_action(action)
            self.assertEqual(actions[:i + 1], game.actions)

        self.assertTrue(game.game_state.is_game_over)
        self.assertEqual(PlayerPair(13, 67), game.game_state.trick_points)
        self.assertEqual(PlayerPair(0, 3), game.game_state.game_points)
 def test_invalid_trick_points(self):
     correct_trick_points = self.game_state.trick_points
     for points_one in range(100):
         for points_two in range(100):
             self.game_state.trick_points = PlayerPair(
                 points_one, points_two)
             if self.game_state.trick_points == correct_trick_points:
                 continue
             with self.assertRaisesRegex(InvalidGameStateError,
                                         "Invalid trick points",
                                         msg=f"{points_one} {points_two}"):
                 validate(self.game_state)
Beispiel #28
0
 def build(self):
   self._game_widget = GameWidget(game_options=self._game_options)
   self._game_widget.padding_pct = 0.01
   self._game_widget.size_hint = 1, 1
   human_player: Player = self._game_widget
   computer_player: Player = OutOfProcessComputerPlayer(
     CythonMctsPlayer, (PlayerId.TWO, False, mcts_player_options_v1()))
   players: PlayerPair[Player] = PlayerPair(human_player, computer_player)
   auto_save_folder = str(Path(__file__).parent.parent.absolute())
   self._game_controller = GameController(self._game_widget, players,
                                          auto_save_folder=auto_save_folder)
   return self._game_widget
  def test_announce_marriage_without_scoring_any_trick(self):
    game_state = get_game_state_for_tests()
    with GameStateValidator(game_state):
      for trick in game_state.won_tricks[PlayerId.ONE]:
        game_state.talon.extend([trick.one, trick.two])
      for trick in game_state.won_tricks[PlayerId.TWO]:
        game_state.talon.extend([trick.one, trick.two])
      game_state.won_tricks = PlayerPair([], [])
      game_state.trick_points = PlayerPair(0, 0)
      game_state.marriage_suits[PlayerId.TWO] = []

    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(0, 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_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)