Skip to content

Players module

Provide the classes to instantiate players, human or computer.

This module allows the creation of different categories of players.

Examples:

>>> player1 = RandomComputerPlayer(Mark("X"))
>>> player2 = MinimaxComputerPlayer(Mark("O"))

The module contains the following class: - Player - ABC - ComputerPlayer - ABC. Extension of class Player. - RandomComputerPlayer - Extension of class ComputerPlayer. - MinimaxComputerPlayer - ABC. Extension of class ComputerPlayer.

ComputerPlayer

Bases: Player

Abstract class for the creation of computer players. Extends as metaclass, abc.ABCMeta. Extends Player abstract class An instance of subclass of the Player class that represents a human or computer.

Attributes:

Name Type Description
mark

Mark An instance of Mark class that handles user marks

Methods:

Name Description
get_move

GameState) -> Move | None: Return the current computer player's move in the given game state

get_computer_move

GameState) -> Move | None: Determines current player base on the current game state. Abstract method

Source code in src\backend\game\players.py
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
class ComputerPlayer(Player, metaclass=abc.ABCMeta):
    """Abstract class for the creation of computer players. Extends as metaclass, abc.ABCMeta.
        Extends Player abstract class An instance of subclass of the Player class that represents
        a human or computer.

    Attributes:
        mark: Mark
            An instance of Mark class that handles user marks

    Methods:
        get_move(self, game_state: GameState) -> Move | None:
            Return the current computer player's move in the given game state
        get_computer_move(self, game_state: GameState) -> Move | None:
            Determines current player base on the current game state. Abstract method
    """
    def __init__(self, mark: Mark, delay_seconds: float = 0.25) -> None:
        """
        Args:
            mark (Mark): An instance class that handles user marks
            delay_seconds (float, optional): Represents the delay time for the computer
                to player. Defaults to 0.25.
        """
        super().__init__(mark)
        self.delay_seconds = delay_seconds

    def get_move(self, game_state: GameState) -> Move | None:
        """Return the current computer player's move in the given game state

        Args:
            game_state (GameState): current GameState, consisting of a current Grid (9 elemets that
                that can be X, O or spaces) and a starting Mark (default X).

        Returns:
            Move | None: return a move class or none
        """
        time.sleep(self.delay_seconds)
        return self.get_computer_move(game_state)

    @abc.abstractmethod
    def get_computer_move(self, game_state: GameState) -> Move | None:
        """Return the computer's move in the given game state."""

__init__(mark, delay_seconds=0.25)

Parameters:

Name Type Description Default
mark Mark

An instance class that handles user marks

required
delay_seconds float

Represents the delay time for the computer to player. Defaults to 0.25.

0.25
Source code in src\backend\game\players.py
82
83
84
85
86
87
88
89
90
def __init__(self, mark: Mark, delay_seconds: float = 0.25) -> None:
    """
    Args:
        mark (Mark): An instance class that handles user marks
        delay_seconds (float, optional): Represents the delay time for the computer
            to player. Defaults to 0.25.
    """
    super().__init__(mark)
    self.delay_seconds = delay_seconds

get_computer_move(game_state) abstractmethod

Return the computer's move in the given game state.

Source code in src\backend\game\players.py
105
106
107
@abc.abstractmethod
def get_computer_move(self, game_state: GameState) -> Move | None:
    """Return the computer's move in the given game state."""

get_move(game_state)

Return the current computer player's move in the given game state

Parameters:

Name Type Description Default
game_state GameState

current GameState, consisting of a current Grid (9 elemets that that can be X, O or spaces) and a starting Mark (default X).

required

Returns:

Type Description
Move | None

Move | None: return a move class or none

Source code in src\backend\game\players.py
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
def get_move(self, game_state: GameState) -> Move | None:
    """Return the current computer player's move in the given game state

    Args:
        game_state (GameState): current GameState, consisting of a current Grid (9 elemets that
            that can be X, O or spaces) and a starting Mark (default X).

    Returns:
        Move | None: return a move class or none
    """
    time.sleep(self.delay_seconds)
    return self.get_computer_move(game_state)

MinimaxComputerPlayer

Bases: ComputerPlayer

A class for the creation of computer players with move based on minimax algorithm. Extends ComputerPlayer, an abstract class for the creation of computer players.

Methods:

Name Description
get_computer_move

GameState) -> Move | None: Return the current computer player's move in the given game state.

Source code in src\backend\game\players.py
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
class MinimaxComputerPlayer(ComputerPlayer):
    """A class for the creation of computer players with move based on minimax algorithm.
    Extends ComputerPlayer, an abstract class for the creation of computer players.

    Methods:
        get_computer_move(self, game_state: GameState) -> Move | None:
            Return the current computer player's move in the given game state.
    """
    def get_computer_move(self, game_state: GameState) -> Move | None:
        """Return the current computer player's move in the given game state using
        minimax algorithm.

        Args:
            game_state (GameState): current GameState, consisting of a current Grid (9 elemets that
                that can be X, O or spaces) and a starting Mark (default X).

        Returns:
            Move | None: return a move class or none.
        """
        if game_state.game_not_started:
            return game_state.make_random_move()
        return find_best_move(game_state)

get_computer_move(game_state)

Return the current computer player's move in the given game state using minimax algorithm.

Parameters:

Name Type Description Default
game_state GameState

current GameState, consisting of a current Grid (9 elemets that that can be X, O or spaces) and a starting Mark (default X).

required

Returns:

Type Description
Move | None

Move | None: return a move class or none.

Source code in src\backend\game\players.py
137
138
139
140
141
142
143
144
145
146
147
148
149
150
def get_computer_move(self, game_state: GameState) -> Move | None:
    """Return the current computer player's move in the given game state using
    minimax algorithm.

    Args:
        game_state (GameState): current GameState, consisting of a current Grid (9 elemets that
            that can be X, O or spaces) and a starting Mark (default X).

    Returns:
        Move | None: return a move class or none.
    """
    if game_state.game_not_started:
        return game_state.make_random_move()
    return find_best_move(game_state)

Player

Abstract class for the creation of players. Extends as metaclass, abc.ABCMeta.

Attributes:

Name Type Description
mark

Mark An instance of Mark class that handles user marks.

Methods:

Name Description
make_move

GameState) -> GameState: Handles the current player move.

get_move

GameState) -> Move | None: Determines current player base on the current game state. Abstract method.

Source code in src\backend\game\players.py
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
class Player(metaclass=abc.ABCMeta):
    """Abstract class for the creation of players. Extends as metaclass, abc.ABCMeta.

    Attributes:
        mark: Mark
            An instance of Mark class that handles user marks.

    Methods:
        make_move(self, game_state: GameState) -> GameState:
            Handles the current player move.
        get_move(self, game_state: GameState) -> Move | None:
            Determines current player base on the current game state. Abstract method.
    """
    def __init__(self, mark: Mark) -> None:
        """Initializes the instance based on mark provided.
        Args:
            mark (Mark): An instance class that handles user marks.
        """
        self.mark = mark

    def make_move(self, game_state: GameState) -> GameState:
        """Handles the current player move which depends on the get_move method
        implemented in each subclass if it's the given player's turn and whether the move exists.

        Args:
            game_state (GameState): current GameState, consisting of a current Grid (9 elemets that
                that can be X, O or spaces) and a starting Mark (default X).

        Raises:
            InvalidMove: Exception when a invalid move is selected
        Returns:
            GameState: current GameState, consisting of a current Grid (9 elemets that
            that can be X, O or spaces) and a starting Mark (default X).
        """
        if self.mark is game_state.current_mark:
            if move := self.get_move(game_state):
                return move.after_state
            raise InvalidMove("No more possible moves")
        raise InvalidMove("It's the other player's turn")

    @abc.abstractmethod
    def get_move(self, game_state: GameState) -> Move | None:
        """Return the current player's move in the given game state."""

__init__(mark)

Initializes the instance based on mark provided.

Parameters:

Name Type Description Default
mark Mark

An instance class that handles user marks.

required
Source code in src\backend\game\players.py
36
37
38
39
40
41
def __init__(self, mark: Mark) -> None:
    """Initializes the instance based on mark provided.
    Args:
        mark (Mark): An instance class that handles user marks.
    """
    self.mark = mark

get_move(game_state) abstractmethod

Return the current player's move in the given game state.

Source code in src\backend\game\players.py
63
64
65
@abc.abstractmethod
def get_move(self, game_state: GameState) -> Move | None:
    """Return the current player's move in the given game state."""

make_move(game_state)

Handles the current player move which depends on the get_move method implemented in each subclass if it's the given player's turn and whether the move exists.

Parameters:

Name Type Description Default
game_state GameState

current GameState, consisting of a current Grid (9 elemets that that can be X, O or spaces) and a starting Mark (default X).

required

Raises:

Type Description
InvalidMove

Exception when a invalid move is selected

Returns:

Name Type Description
GameState GameState

current GameState, consisting of a current Grid (9 elemets that

GameState

that can be X, O or spaces) and a starting Mark (default X).

Source code in src\backend\game\players.py
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
def make_move(self, game_state: GameState) -> GameState:
    """Handles the current player move which depends on the get_move method
    implemented in each subclass if it's the given player's turn and whether the move exists.

    Args:
        game_state (GameState): current GameState, consisting of a current Grid (9 elemets that
            that can be X, O or spaces) and a starting Mark (default X).

    Raises:
        InvalidMove: Exception when a invalid move is selected
    Returns:
        GameState: current GameState, consisting of a current Grid (9 elemets that
        that can be X, O or spaces) and a starting Mark (default X).
    """
    if self.mark is game_state.current_mark:
        if move := self.get_move(game_state):
            return move.after_state
        raise InvalidMove("No more possible moves")
    raise InvalidMove("It's the other player's turn")

RandomComputerPlayer

Bases: ComputerPlayer

Class for the creation of computer players with random moves. Extends ComputerPlayer abstract class.

Methods:

Name Description
get_computer_move

GameState) -> Move | None: Return the current computer player's random move in the given game state.

Source code in src\backend\game\players.py
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
class RandomComputerPlayer(ComputerPlayer):
    """Class for the creation of computer players with random moves. Extends ComputerPlayer
    abstract class.

    Methods:
        get_computer_move(self, game_state: GameState) -> Move | None:
            Return the current computer player's random move in the given game state.
    """
    def get_computer_move(self, game_state: GameState) -> Move | None:
        """Return the current computer player's random move in the given game state.

        Args:
            game_state (GameState): current GameState, consisting of a current Grid (9 elemets that
                that can be X, O or spaces) and a starting Mark (default X).

        Returns:
            Move | None: return a move class or none
        """
        return game_state.make_random_move()

get_computer_move(game_state)

Return the current computer player's random move in the given game state.

Parameters:

Name Type Description Default
game_state GameState

current GameState, consisting of a current Grid (9 elemets that that can be X, O or spaces) and a starting Mark (default X).

required

Returns:

Type Description
Move | None

Move | None: return a move class or none

Source code in src\backend\game\players.py
117
118
119
120
121
122
123
124
125
126
127
def get_computer_move(self, game_state: GameState) -> Move | None:
    """Return the current computer player's random move in the given game state.

    Args:
        game_state (GameState): current GameState, consisting of a current Grid (9 elemets that
            that can be X, O or spaces) and a starting Mark (default X).

    Returns:
        Move | None: return a move class or none
    """
    return game_state.make_random_move()