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()
def __init__(self, card: Card, aspect_ratio: float = 24 / 37, path: Optional[str] = None, **kwargs): """ Instantiates a new CardWidget. :param card: The card value to associate to this widget. :param aspect_ratio: The aspect ratio that will be enforced. :param path: The path to the folder containing the card images. :param kwargs: Parameters to be forwarded to the base class' constructor. """ super().__init__(**kwargs) self._card = card self._path = path or GameOptions().cards_path self._visible = True self._grayed_out = False self._touch_down_pos: Optional[Tuple[int, int]] = None self._shadow_image = _get_drop_shadow_filename(self._path) self._shadow_enabled = _SHADOW_STRENGTH self.auto_bring_to_front = True image = Image(source=_get_card_filename(card, self._path)) image.keep_ratio = False image.allow_stretch = True self.fbind("size", image.setter("size")) self.add_widget(image) self._ratio = aspect_ratio self.width = self.height * self._ratio self.size_hint = None, None self.register_event_type("on_double_tap") self.register_event_type("on_card_moved") self._check_aspect_ratio = True # noinspection PyUnreachableCode if __debug__: self.fbind("size", self._assert_aspect_ratio)
def __init__(self, **kwargs): super().__init__(**kwargs) self._game_options = GameOptions() self._game_widget: Optional[GameWidget] = None self._game_controller: Optional[GameController] = None self.title = f"Schnapsen Card Game :: v{__version__}" self.icon = os.path.join(self._game_options.resource_path, "icon.png")
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()
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 test_default_options(self): game_options = GameOptions() self.assertTrue(game_options.resource_path) self.assertTrue(game_options.cards_path) self.assertTrue(game_options.enable_animations) self.assertEqual(1, game_options.animation_duration_multiplier) self.assertEqual(0.5, game_options.play_card_duration) self.assertEqual(1.5, game_options.exchange_trump_duration) self.assertEqual(0.5, game_options.close_talon_duration) self.assertEqual(0.5, game_options.trick_completed_duration) self.assertEqual(0.5, game_options.draw_cards_duration) self.assertFalse(game_options.computer_cards_visible)
def test_custom_options(self): game_options = GameOptions(animation_duration_multiplier=10, close_talon_duration=2, resource_path="/test/folder/", cards_path="/test/cards/folder/", enable_animations=False, computer_cards_visible=True) self.assertEqual("/test/folder/", game_options.resource_path) self.assertEqual("/test/cards/folder/", game_options.cards_path) self.assertFalse(game_options.enable_animations) self.assertEqual(10, game_options.animation_duration_multiplier) self.assertEqual(5, game_options.play_card_duration) self.assertEqual(15, game_options.exchange_trump_duration) self.assertEqual(20, game_options.close_talon_duration) self.assertEqual(5, game_options.trick_completed_duration) self.assertEqual(5, game_options.draw_cards_duration) self.assertTrue(game_options.computer_cards_visible)
def test_custom_options_with_no_default(self): with self.assertRaisesRegex(AssertionError, "No default value for option: no_default"): GameOptions(no_default="test")