diff --git a/README.md b/README.md index bba0888..99b1877 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ import logging import sys from codenames.classic.board import ClassicBoard -from codenames.classic.player import ClassicTeam +from codenames.classic.team import ClassicTeam from codenames.classic.runner import ClassicGamePlayers, ClassicGameRunner from codenames.generic.move import Clue, Guess from codenames.generic.player import Operative, Spymaster diff --git a/codenames/classic/board.py b/codenames/classic/board.py index ead40c3..8a6c43d 100644 --- a/codenames/classic/board.py +++ b/codenames/classic/board.py @@ -5,7 +5,7 @@ from typing import Self from codenames.classic.color import ClassicColor -from codenames.classic.player import ClassicTeam +from codenames.classic.team import ClassicTeam from codenames.classic.types import ClassicCard, ClassicCards from codenames.generic.board import Board, Vocabulary from codenames.utils.builder import extract_random_subset diff --git a/codenames/classic/player.py b/codenames/classic/player.py index b2c195f..91d8e98 100644 --- a/codenames/classic/player.py +++ b/codenames/classic/player.py @@ -3,29 +3,18 @@ import abc from codenames.classic.color import ClassicColor -from codenames.generic.player import Operative, Player, Spymaster, Team - - -class ClassicTeam(Team): - BLUE = "BLUE" - RED = "RED" - - @property - def as_card_color(self) -> ClassicColor: - return ClassicColor.BLUE if self == ClassicTeam.BLUE else ClassicColor.RED - - @property - def opponent(self) -> ClassicTeam: - return ClassicTeam.BLUE if self == ClassicTeam.RED else ClassicTeam.RED +from codenames.classic.state import ClassicOperativeState, ClassicSpymasterState +from codenames.classic.team import ClassicTeam +from codenames.generic.player import Operative, Player, Spymaster class ClassicPlayer(Player[ClassicColor, ClassicTeam]): pass -class ClassicSpymaster(Spymaster[ClassicColor, ClassicTeam], abc.ABC): +class ClassicSpymaster(Spymaster[ClassicColor, ClassicTeam, ClassicSpymasterState], abc.ABC): pass -class ClassicOperative(Operative[ClassicColor, ClassicTeam], abc.ABC): +class ClassicOperative(Operative[ClassicColor, ClassicTeam, ClassicOperativeState], abc.ABC): pass diff --git a/codenames/classic/runner.py b/codenames/classic/runner.py index f78fdf9..9ef8f91 100644 --- a/codenames/classic/runner.py +++ b/codenames/classic/runner.py @@ -5,8 +5,8 @@ from typing import Collection, Iterator from codenames.classic.board import ClassicBoard -from codenames.classic.player import ClassicTeam from codenames.classic.state import ClassicGameState +from codenames.classic.team import ClassicTeam from codenames.classic.winner import Winner from codenames.generic.exceptions import InvalidGuess from codenames.generic.move import GivenGuess diff --git a/codenames/classic/score.py b/codenames/classic/score.py index f272df9..734ad2e 100644 --- a/codenames/classic/score.py +++ b/codenames/classic/score.py @@ -2,7 +2,7 @@ from pydantic import BaseModel -from codenames.classic.player import ClassicTeam +from codenames.classic.team import ClassicTeam from codenames.generic.state import TeamScore diff --git a/codenames/classic/state.py b/codenames/classic/state.py index a9e350d..777be9d 100644 --- a/codenames/classic/state.py +++ b/codenames/classic/state.py @@ -5,8 +5,8 @@ from codenames.classic.board import ClassicBoard from codenames.classic.color import ClassicColor -from codenames.classic.player import ClassicTeam from codenames.classic.score import Score +from codenames.classic.team import ClassicTeam from codenames.classic.types import ClassicCard, ClassicGivenClue, ClassicGivenGuess from codenames.classic.winner import Winner, WinningReason from codenames.generic.card import canonical_format diff --git a/codenames/classic/team.py b/codenames/classic/team.py new file mode 100644 index 0000000..23439e8 --- /dev/null +++ b/codenames/classic/team.py @@ -0,0 +1,17 @@ +from __future__ import annotations + +from codenames.classic.color import ClassicColor +from codenames.generic.player import Team + + +class ClassicTeam(Team): + BLUE = "BLUE" + RED = "RED" + + @property + def as_card_color(self) -> ClassicColor: + return ClassicColor.BLUE if self == ClassicTeam.BLUE else ClassicColor.RED + + @property + def opponent(self) -> ClassicTeam: + return ClassicTeam.BLUE if self == ClassicTeam.RED else ClassicTeam.RED diff --git a/codenames/classic/types.py b/codenames/classic/types.py index 909df32..21a33a5 100644 --- a/codenames/classic/types.py +++ b/codenames/classic/types.py @@ -1,5 +1,5 @@ from codenames.classic.color import ClassicColor -from codenames.classic.player import ClassicTeam +from codenames.classic.team import ClassicTeam from codenames.generic.card import Card from codenames.generic.move import GivenClue, GivenGuess diff --git a/codenames/classic/winner.py b/codenames/classic/winner.py index dd91c06..dd57e9e 100644 --- a/codenames/classic/winner.py +++ b/codenames/classic/winner.py @@ -2,7 +2,7 @@ from pydantic import BaseModel -from codenames.classic.player import ClassicTeam +from codenames.classic.team import ClassicTeam class WinningReason(StrEnum): diff --git a/codenames/duet/player.py b/codenames/duet/player.py index 3a9bd34..4bbf48f 100644 --- a/codenames/duet/player.py +++ b/codenames/duet/player.py @@ -3,24 +3,18 @@ import abc from codenames.duet.card import DuetColor -from codenames.generic.player import Operative, Spymaster, Team +from codenames.duet.state import DuetOperativeState, DuetSpymasterState +from codenames.duet.team import DuetTeam +from codenames.generic.player import Operative, Spymaster -class DuetTeam(Team): - MAIN = "MAIN" - - @property - def as_card_color(self) -> DuetColor: - return DuetColor.GREEN # Naive implementation - - -class DuetPlayer(Spymaster[DuetColor, DuetTeam], Operative[DuetColor, DuetTeam], abc.ABC): +class DuetSpymaster(Spymaster[DuetColor, DuetTeam, DuetSpymasterState], abc.ABC): pass -class DuetSpymaster(Spymaster[DuetColor, DuetTeam], abc.ABC): +class DuetOperative(Operative[DuetColor, DuetTeam, DuetOperativeState], abc.ABC): pass -class DuetOperative(Operative[DuetColor, DuetTeam], abc.ABC): +class DuetPlayer(DuetSpymaster, DuetOperative, abc.ABC): pass diff --git a/codenames/duet/state.py b/codenames/duet/state.py index c34e8fc..3e92173 100644 --- a/codenames/duet/state.py +++ b/codenames/duet/state.py @@ -8,7 +8,6 @@ from codenames.duet.board import DuetBoard from codenames.duet.card import DuetColor -from codenames.duet.player import DuetTeam from codenames.duet.score import ( ASSASSIN_HIT, GAME_QUIT, @@ -18,6 +17,7 @@ GameResult, Score, ) +from codenames.duet.team import DuetTeam from codenames.duet.types import DuetCard, DuetGivenClue, DuetGivenGuess from codenames.generic.board import WordGroup from codenames.generic.card import canonical_format diff --git a/codenames/duet/team.py b/codenames/duet/team.py new file mode 100644 index 0000000..2bfbdd5 --- /dev/null +++ b/codenames/duet/team.py @@ -0,0 +1,12 @@ +from __future__ import annotations + +from codenames.duet.card import DuetColor +from codenames.generic.player import Team + + +class DuetTeam(Team): + MAIN = "MAIN" + + @property + def as_card_color(self) -> DuetColor: + return DuetColor.GREEN # Naive implementation diff --git a/codenames/duet/types.py b/codenames/duet/types.py index a967524..0b2836d 100644 --- a/codenames/duet/types.py +++ b/codenames/duet/types.py @@ -1,5 +1,5 @@ from codenames.duet.card import DuetColor -from codenames.duet.player import DuetTeam +from codenames.duet.team import DuetTeam from codenames.generic.card import Card from codenames.generic.move import GivenClue, GivenGuess diff --git a/codenames/generic/player.py b/codenames/generic/player.py index 4a1a60d..faf5a44 100644 --- a/codenames/generic/player.py +++ b/codenames/generic/player.py @@ -57,13 +57,13 @@ def on_guess_given(self, given_guess: GivenGuess[C, T]): pass -class Spymaster[C: CardColor, T: Team](Player[C, T], abc.ABC): +class Spymaster[C: CardColor, T: Team, S: "SpymasterState"](Player[C, T], abc.ABC): @abc.abstractmethod - def give_clue(self, game_state: SpymasterState[C, T]) -> Clue: + def give_clue(self, game_state: S) -> Clue: raise NotImplementedError -class Operative[C: CardColor, T: Team](Player[C, T], abc.ABC): +class Operative[C: CardColor, T: Team, S: "OperativeState"](Player[C, T], abc.ABC): @abc.abstractmethod - def guess(self, game_state: OperativeState[C, T]) -> Guess: + def guess(self, game_state: S) -> Guess: raise NotImplementedError() diff --git a/codenames/online/codenames_game/agent.py b/codenames/online/codenames_game/agent.py index 5f72f51..a0a3b6b 100644 --- a/codenames/online/codenames_game/agent.py +++ b/codenames/online/codenames_game/agent.py @@ -3,12 +3,8 @@ import logging from typing import TYPE_CHECKING -from codenames.classic.player import ( - ClassicOperative, - ClassicPlayer, - ClassicSpymaster, - ClassicTeam, -) +from codenames.classic.player import ClassicOperative, ClassicPlayer, ClassicSpymaster +from codenames.classic.team import ClassicTeam from codenames.generic.move import Clue, Guess from codenames.generic.state import OperativeState, SpymasterState diff --git a/codenames/online/codenames_game/runner.py b/codenames/online/codenames_game/runner.py index f344a66..1e85248 100644 --- a/codenames/online/codenames_game/runner.py +++ b/codenames/online/codenames_game/runner.py @@ -4,8 +4,8 @@ from threading import Semaphore, Thread from typing import ContextManager, Iterable -from codenames.classic.player import ClassicTeam from codenames.classic.runner import ClassicGamePlayers, ClassicGameRunner +from codenames.classic.team import ClassicTeam from codenames.generic.move import Clue, Guess from codenames.generic.player import Operative, Player, PlayerRole, Spymaster from codenames.online.codenames_game.adapter import ( diff --git a/tests/classic/test_board.py b/tests/classic/test_board.py index 5eb2d39..141362b 100644 --- a/tests/classic/test_board.py +++ b/tests/classic/test_board.py @@ -1,7 +1,7 @@ import pytest from codenames.classic.board import ClassicBoard -from codenames.classic.player import ClassicTeam +from codenames.classic.team import ClassicTeam from codenames.generic.board import two_integer_factors from codenames.generic.exceptions import CardNotFoundError from codenames.utils.vocabulary.languages import SupportedLanguage, get_vocabulary diff --git a/tests/classic/test_flows.py b/tests/classic/test_flows.py index e678841..df4e251 100644 --- a/tests/classic/test_flows.py +++ b/tests/classic/test_flows.py @@ -1,7 +1,7 @@ from unittest.mock import MagicMock from codenames.classic.board import ClassicBoard -from codenames.classic.player import ClassicTeam +from codenames.classic.team import ClassicTeam from codenames.classic.types import ClassicGivenClue, ClassicGivenGuess from codenames.classic.winner import Winner, WinningReason from codenames.generic.move import PASS_GUESS, QUIT_GAME, Clue, Guess diff --git a/tests/classic/test_game_runner.py b/tests/classic/test_game_runner.py index 6078ea2..9cfe601 100644 --- a/tests/classic/test_game_runner.py +++ b/tests/classic/test_game_runner.py @@ -2,15 +2,15 @@ from codenames.classic.board import ClassicBoard from codenames.classic.color import ClassicColor -from codenames.classic.player import ClassicTeam from codenames.classic.runner import ClassicGameRunner from codenames.classic.state import ClassicOperativeState +from codenames.classic.team import ClassicTeam from codenames.classic.types import ClassicGivenClue, ClassicGivenGuess from codenames.classic.winner import Winner, WinningReason from codenames.generic.move import Clue from tests.classic.utils.dictated import ( - DictatedClassicOperative, - DictatedClassicSpymaster, + ClassicDictatedOperative, + ClassicDictatedSpymaster, ) from tests.classic.utils.runner import build_players, run_game from tests.utils.hooks import hook_method @@ -76,7 +76,7 @@ def test_game_runner_spymaster_state(board_10: ClassicBoard): DictatedTurn(clue=Clue(word="B", card_amount=1), guesses=[4, 9]), ] - with hook_method(DictatedClassicSpymaster, "give_clue") as give_clue_mock: + with hook_method(ClassicDictatedSpymaster, "give_clue") as give_clue_mock: run_game(board=board_10, all_turns=all_turns) calls = give_clue_mock.hook.calls @@ -108,7 +108,7 @@ def test_game_runner_operative_state(board_10: ClassicBoard): DictatedTurn(clue=Clue(word="A", card_amount=2), guesses=[0, 1, 2]), DictatedTurn(clue=Clue(word="B", card_amount=1), guesses=[4, 9]), ] - with hook_method(DictatedClassicOperative, "guess") as pick_guess_mock: + with hook_method(ClassicDictatedOperative, "guess") as pick_guess_mock: run_game(board=board_10, all_turns=all_turns) calls = pick_guess_mock.hook.calls diff --git a/tests/classic/test_game_state.py b/tests/classic/test_game_state.py index bbcfea3..bb56a2f 100644 --- a/tests/classic/test_game_state.py +++ b/tests/classic/test_game_state.py @@ -4,8 +4,8 @@ from codenames.classic.board import ClassicBoard from codenames.classic.color import ClassicColor -from codenames.classic.player import ClassicTeam from codenames.classic.state import ClassicGameState, ClassicPlayerState +from codenames.classic.team import ClassicTeam from codenames.classic.types import ClassicCard, ClassicGivenClue, ClassicGivenGuess from codenames.classic.winner import Winner, WinningReason from codenames.generic.exceptions import InvalidGuess, InvalidTurn diff --git a/tests/classic/test_player.py b/tests/classic/test_player.py index d804a01..c5e39ef 100644 --- a/tests/classic/test_player.py +++ b/tests/classic/test_player.py @@ -1,13 +1,14 @@ import pytest from codenames.classic.color import ClassicColor -from codenames.classic.player import ClassicPlayer, ClassicTeam +from codenames.classic.player import ClassicPlayer from codenames.classic.runner import ClassicGamePlayers +from codenames.classic.team import ClassicTeam from codenames.generic.player import PlayerRole from codenames.generic.runner import TeamPlayers from tests.classic.utils.dictated import ( - DictatedClassicOperative, - DictatedClassicSpymaster, + ClassicDictatedOperative, + ClassicDictatedSpymaster, ) @@ -19,18 +20,18 @@ def test_player_team_card_color(): def test_play_to_string(): - p1 = DictatedClassicOperative(guesses=[], name="Player 1", team=ClassicTeam.RED) - p2 = DictatedClassicSpymaster(clues=[], name="Player 2", team=ClassicTeam.BLUE) + p1 = ClassicDictatedOperative(guesses=[], name="Player 1", team=ClassicTeam.RED) + p2 = ClassicDictatedSpymaster(clues=[], name="Player 2", team=ClassicTeam.BLUE) - assert str(p1) == "Player 1 | Red Dictated Classic Operative" - assert str(p2) == "Player 2 | Blue Dictated Classic Spymaster" + assert str(p1) == "Player 1 | Red Classic Dictated Operative" + assert str(p2) == "Player 2 | Blue Classic Dictated Spymaster" def test_game_players_builder(): - blue_spymaster = DictatedClassicSpymaster(clues=[], name="Blue Spymaster", team=ClassicTeam.BLUE) - blue_operative = DictatedClassicOperative(guesses=[], name="Blue Operative", team=ClassicTeam.BLUE) - red_spymaster = DictatedClassicSpymaster(clues=[], name="Red Spymaster", team=ClassicTeam.RED) - red_operative = DictatedClassicOperative(guesses=[], name="Red Operative", team=ClassicTeam.RED) + blue_spymaster = ClassicDictatedSpymaster(clues=[], name="Blue Spymaster", team=ClassicTeam.BLUE) + blue_operative = ClassicDictatedOperative(guesses=[], name="Blue Operative", team=ClassicTeam.BLUE) + red_spymaster = ClassicDictatedSpymaster(clues=[], name="Red Spymaster", team=ClassicTeam.RED) + red_operative = ClassicDictatedOperative(guesses=[], name="Red Operative", team=ClassicTeam.RED) players = ClassicGamePlayers.from_collection(blue_spymaster, blue_operative, red_spymaster, red_operative) @@ -39,29 +40,29 @@ def test_game_players_builder(): def test_game_players_builder_raises_if_not_enough_players(): - blue_spymaster = DictatedClassicSpymaster(clues=[], name="Blue Spymaster", team=ClassicTeam.BLUE) - blue_operative = DictatedClassicOperative(guesses=[], name="Blue Operative", team=ClassicTeam.BLUE) - red_spymaster = DictatedClassicSpymaster(clues=[], name="Red Spymaster", team=ClassicTeam.RED) + blue_spymaster = ClassicDictatedSpymaster(clues=[], name="Blue Spymaster", team=ClassicTeam.BLUE) + blue_operative = ClassicDictatedOperative(guesses=[], name="Blue Operative", team=ClassicTeam.BLUE) + red_spymaster = ClassicDictatedSpymaster(clues=[], name="Red Spymaster", team=ClassicTeam.RED) with pytest.raises(ValueError): ClassicGamePlayers.from_collection(blue_spymaster, blue_operative, red_spymaster) def test_game_players_builder_raises_if_operative_missing_from_team(): - blue_spymaster = DictatedClassicSpymaster(clues=[], name="Blue Spymaster", team=ClassicTeam.BLUE) - blue_operative = DictatedClassicOperative(guesses=[], name="Blue Operative", team=ClassicTeam.BLUE) - red_spymaster = DictatedClassicSpymaster(clues=[], name="Red Spymaster", team=ClassicTeam.RED) - blue_operative_2 = DictatedClassicOperative(guesses=[], name="Blue Operative 2", team=ClassicTeam.BLUE) + blue_spymaster = ClassicDictatedSpymaster(clues=[], name="Blue Spymaster", team=ClassicTeam.BLUE) + blue_operative = ClassicDictatedOperative(guesses=[], name="Blue Operative", team=ClassicTeam.BLUE) + red_spymaster = ClassicDictatedSpymaster(clues=[], name="Red Spymaster", team=ClassicTeam.RED) + blue_operative_2 = ClassicDictatedOperative(guesses=[], name="Blue Operative 2", team=ClassicTeam.BLUE) with pytest.raises(ValueError): ClassicGamePlayers.from_collection(blue_spymaster, blue_operative, red_spymaster, blue_operative_2) def test_get_player(): - blue_spymaster = DictatedClassicSpymaster(clues=[], name="Blue Spymaster", team=ClassicTeam.BLUE) - blue_operative = DictatedClassicOperative(guesses=[], name="Blue Operative", team=ClassicTeam.BLUE) - red_spymaster = DictatedClassicSpymaster(clues=[], name="Red Spymaster", team=ClassicTeam.RED) - red_operative = DictatedClassicOperative(guesses=[], name="Red Operative", team=ClassicTeam.RED) + blue_spymaster = ClassicDictatedSpymaster(clues=[], name="Blue Spymaster", team=ClassicTeam.BLUE) + blue_operative = ClassicDictatedOperative(guesses=[], name="Blue Operative", team=ClassicTeam.BLUE) + red_spymaster = ClassicDictatedSpymaster(clues=[], name="Red Spymaster", team=ClassicTeam.RED) + red_operative = ClassicDictatedOperative(guesses=[], name="Red Operative", team=ClassicTeam.RED) players = ClassicGamePlayers.from_collection(blue_spymaster, blue_operative, red_spymaster, red_operative) blue_spymaster_2 = players.get_player(team=ClassicTeam.BLUE, role=PlayerRole.SPYMASTER) @@ -72,10 +73,10 @@ def test_get_player(): def test_game_players_properties(): - blue_spymaster = DictatedClassicSpymaster(clues=[], name="Blue Spymaster", team=ClassicTeam.BLUE) - blue_operative = DictatedClassicOperative(guesses=[], name="Blue Operative", team=ClassicTeam.BLUE) - red_spymaster = DictatedClassicSpymaster(clues=[], name="Red Spymaster", team=ClassicTeam.RED) - red_operative = DictatedClassicOperative(guesses=[], name="Red Operative", team=ClassicTeam.RED) + blue_spymaster = ClassicDictatedSpymaster(clues=[], name="Blue Spymaster", team=ClassicTeam.BLUE) + blue_operative = ClassicDictatedOperative(guesses=[], name="Blue Operative", team=ClassicTeam.BLUE) + red_spymaster = ClassicDictatedSpymaster(clues=[], name="Red Spymaster", team=ClassicTeam.RED) + red_operative = ClassicDictatedOperative(guesses=[], name="Red Operative", team=ClassicTeam.RED) players = ClassicGamePlayers.from_collection(blue_spymaster, blue_operative, red_spymaster, red_operative) assert players.spymasters == (blue_spymaster, red_spymaster) @@ -83,8 +84,8 @@ def test_game_players_properties(): def test_team_raises_if_spymaster_and_operative_have_different_teams(): - blue_spymaster = DictatedClassicSpymaster(clues=[], name="Blue Spymaster", team=ClassicTeam.BLUE) - red_operative = DictatedClassicOperative(guesses=[], name="Red Operative", team=ClassicTeam.RED) + blue_spymaster = ClassicDictatedSpymaster(clues=[], name="Blue Spymaster", team=ClassicTeam.BLUE) + red_operative = ClassicDictatedOperative(guesses=[], name="Red Operative", team=ClassicTeam.RED) with pytest.raises(ValueError): TeamPlayers(spymaster=blue_spymaster, operative=red_operative) diff --git a/tests/classic/test_serialization.py b/tests/classic/test_serialization.py index 992fcbe..752adce 100644 --- a/tests/classic/test_serialization.py +++ b/tests/classic/test_serialization.py @@ -1,5 +1,5 @@ from codenames.classic.color import ClassicColor -from codenames.classic.player import ClassicTeam +from codenames.classic.team import ClassicTeam from codenames.classic.types import ClassicCard, ClassicGivenClue diff --git a/tests/classic/utils/dictated.py b/tests/classic/utils/dictated.py index 63624ad..1acba81 100644 --- a/tests/classic/utils/dictated.py +++ b/tests/classic/utils/dictated.py @@ -1,11 +1,12 @@ from codenames.classic.color import ClassicColor -from codenames.classic.player import ClassicTeam +from codenames.classic.state import ClassicOperativeState, ClassicSpymasterState +from codenames.classic.team import ClassicTeam from tests.utils.players.dictated import DictatedOperative, DictatedSpymaster -class DictatedClassicSpymaster(DictatedSpymaster[ClassicColor, ClassicTeam]): +class ClassicDictatedSpymaster(DictatedSpymaster[ClassicColor, ClassicTeam, ClassicSpymasterState]): pass -class DictatedClassicOperative(DictatedOperative[ClassicColor, ClassicTeam]): +class ClassicDictatedOperative(DictatedOperative[ClassicColor, ClassicTeam, ClassicOperativeState]): pass diff --git a/tests/classic/utils/runner.py b/tests/classic/utils/runner.py index 8ccfc56..24ad1d5 100644 --- a/tests/classic/utils/runner.py +++ b/tests/classic/utils/runner.py @@ -2,8 +2,8 @@ from unittest.mock import Mock from codenames.classic.board import ClassicBoard -from codenames.classic.player import ClassicTeam from codenames.classic.runner import ClassicGamePlayers, ClassicGameRunner +from codenames.classic.team import ClassicTeam from codenames.generic.move import Guess from codenames.generic.runner import ( ClueGivenSubscriber, @@ -11,8 +11,8 @@ TeamPlayers, ) from tests.classic.utils.dictated import ( - DictatedClassicOperative, - DictatedClassicSpymaster, + ClassicDictatedOperative, + ClassicDictatedSpymaster, ) from tests.utils.players.dictated import DictatedTurn @@ -54,6 +54,6 @@ def build_players(all_turns: Iterable[DictatedTurn], first_team: ClassicTeam = C def build_team(team: ClassicTeam, turns: Iterable[DictatedTurn]) -> TeamPlayers: clues = [turn.clue for turn in turns] guesses = [Guess(card_index=index) for turn in turns for index in turn.guesses] - spymaster = DictatedClassicSpymaster(clues=clues, team=team) - operative = DictatedClassicOperative(guesses=guesses, team=team) + spymaster = ClassicDictatedSpymaster(clues=clues, team=team) + operative = ClassicDictatedOperative(guesses=guesses, team=team) return TeamPlayers(spymaster=spymaster, operative=operative) diff --git a/tests/classic/utils/types.py b/tests/classic/utils/types.py index f7b65e8..3aeca6e 100644 --- a/tests/classic/utils/types.py +++ b/tests/classic/utils/types.py @@ -1,6 +1,7 @@ from codenames.classic.color import ClassicColor -from codenames.classic.player import ClassicTeam +from codenames.classic.state import ClassicOperativeState, ClassicSpymasterState +from codenames.classic.team import ClassicTeam from tests.utils.players.cheaters import CheaterOperative, CheaterSpymaster -ClassicCheaterSpymaster = CheaterSpymaster[ClassicColor, ClassicTeam] -ClassicCheaterOperator = CheaterOperative[ClassicColor, ClassicTeam] +ClassicCheaterSpymaster = CheaterSpymaster[ClassicColor, ClassicTeam, ClassicSpymasterState] +ClassicCheaterOperator = CheaterOperative[ClassicColor, ClassicTeam, ClassicOperativeState] diff --git a/tests/duet/test_game_runner.py b/tests/duet/test_game_runner.py index 49a1fa8..09ee3a0 100644 --- a/tests/duet/test_game_runner.py +++ b/tests/duet/test_game_runner.py @@ -4,7 +4,6 @@ import pytest from codenames.duet.board import DuetBoard -from codenames.duet.player import DuetTeam from codenames.duet.runner import DuetGameRunner from codenames.duet.score import ( MISTAKE_LIMIT_REACHED, @@ -17,6 +16,7 @@ DuetSide, DuetSpymasterState, ) +from codenames.duet.team import DuetTeam from codenames.duet.types import DuetGivenClue, DuetGivenGuess from codenames.generic.move import PASS_GUESS, Clue from tests.duet.utils.runner import build_players, run_duet_game diff --git a/tests/duet/utils/dictated.py b/tests/duet/utils/dictated.py index 6f4846b..9bf0dc6 100644 --- a/tests/duet/utils/dictated.py +++ b/tests/duet/utils/dictated.py @@ -1,17 +1,17 @@ from typing import Iterable from codenames.duet.card import DuetColor -from codenames.duet.player import DuetOperative, DuetPlayer, DuetSpymaster, DuetTeam -from codenames.duet.state import DuetSide +from codenames.duet.player import DuetPlayer +from codenames.duet.state import DuetOperativeState, DuetSide, DuetSpymasterState +from codenames.duet.team import DuetTeam from codenames.generic.move import Clue, Guess -from codenames.generic.state import OperativeState, SpymasterState from tests.utils.players.dictated import DictatedOperative, DictatedSpymaster -DictatedDuetSpymaster = DictatedSpymaster[DuetColor, DuetTeam] -DictatedDuetOperative = DictatedOperative[DuetColor, DuetTeam] +DictatedDuetSpymaster = DictatedSpymaster[DuetColor, DuetTeam, DuetSpymasterState] +DictatedDuetOperative = DictatedOperative[DuetColor, DuetTeam, DuetOperativeState] -class DictatedDuetPlayer(DuetPlayer, DuetSpymaster, DuetOperative): +class DictatedDuetPlayer(DuetPlayer): def __init__( self, clues: Iterable[Clue], @@ -31,8 +31,8 @@ def __init__( auto_quit=auto_quit, ) - def give_clue(self, game_state: SpymasterState) -> Clue: + def give_clue(self, game_state: DuetSpymasterState) -> Clue: return self._spymaster.give_clue(game_state=game_state) - def guess(self, game_state: OperativeState) -> Guess: + def guess(self, game_state: DuetOperativeState) -> Guess: return self._operative.guess(game_state=game_state) diff --git a/tests/duet/utils/runner.py b/tests/duet/utils/runner.py index 6403378..cc0d4aa 100644 --- a/tests/duet/utils/runner.py +++ b/tests/duet/utils/runner.py @@ -2,9 +2,9 @@ from unittest.mock import Mock from codenames.duet.board import DuetBoard -from codenames.duet.player import DuetTeam from codenames.duet.runner import DuetGamePlayers, DuetGameRunner from codenames.duet.state import DuetGameState, DuetSide +from codenames.duet.team import DuetTeam from codenames.generic.move import Guess from codenames.generic.runner import ( ClueGivenSubscriber, diff --git a/tests/online/codenames_game_test.py b/tests/online/codenames_game_test.py index 5b45515..3d6b3c0 100644 --- a/tests/online/codenames_game_test.py +++ b/tests/online/codenames_game_test.py @@ -1,7 +1,7 @@ import pytest -from codenames.classic.player import ClassicTeam from codenames.classic.runner import ClassicGamePlayers +from codenames.classic.team import ClassicTeam from codenames.classic.winner import WinningReason from codenames.online.codenames_game.runner import CodenamesGameRunner from codenames.online.codenames_game.screenshot import reset_screenshot_run diff --git a/tests/utils/players/cheaters.py b/tests/utils/players/cheaters.py index 9fb24a6..9eddfbc 100644 --- a/tests/utils/players/cheaters.py +++ b/tests/utils/players/cheaters.py @@ -7,25 +7,25 @@ from codenames.generic.state import OperativeState, SpymasterState -class CheaterSpymaster[C: CardColor, T: Team](Spymaster[C, T]): +class CheaterSpymaster[C: CardColor, T: Team, S: SpymasterState](Spymaster[C, T, S]): def __init__(self, name: str, team: T, card_amount: int = 4): super().__init__(name, team) - self.game_state: Optional[SpymasterState[C, T]] = None + self.game_state: Optional[S] = None self.card_amount = card_amount - def give_clue(self, game_state: SpymasterState[C, T]) -> Clue: + def give_clue(self, game_state: S) -> Clue: self.game_state = game_state random_word = uuid4().hex[:4] return Clue(word=random_word, card_amount=self.card_amount) -class CheaterOperative[C: CardColor, T: Team](Operative[C, T]): +class CheaterOperative[C: CardColor, T: Team, S: OperativeState](Operative[C, T, S]): def __init__(self, name: str, team: T, spymaster: CheaterSpymaster): super().__init__(name, team) self.spymaster = spymaster self.team_cards: list[Card[C]] = [] - def guess(self, game_state: OperativeState) -> Guess: + def guess(self, game_state: S) -> Guess: if not self.team_cards: self._init_cheating() next_card = self.team_cards.pop() diff --git a/tests/utils/players/dictated.py b/tests/utils/players/dictated.py index 12995b1..1312e7d 100644 --- a/tests/utils/players/dictated.py +++ b/tests/utils/players/dictated.py @@ -12,7 +12,7 @@ def __init__(self, player: Player): self.player = player -class DictatedSpymaster[C: CardColor, T: Team](Spymaster[C, T]): +class DictatedSpymaster[C: CardColor, T: Team, S: SpymasterState](Spymaster[C, T, S]): def __init__( self, clues: Iterable[Clue], @@ -35,7 +35,7 @@ def give_clue(self, game_state: SpymasterState) -> Clue: return clue -class DictatedOperative[C: CardColor, T: Team](Operative[C, T]): +class DictatedOperative[C: CardColor, T: Team, S: OperativeState](Operative[C, T, S]): def __init__( self, guesses: Iterable[Guess],