... | @@ -315,7 +315,7 @@ values are documented. |
... | @@ -315,7 +315,7 @@ values are documented. |
|
|
|
|
|
## Type Hints
|
|
## Type Hints
|
|
|
|
|
|
I am a stickler for type hints...
|
|
I am a stickler for [type hints...](https://www.python.org/dev/peps/pep-0484/)
|
|
|
|
|
|
```python
|
|
```python
|
|
def one_flip(p: float) -> bool:
|
|
def one_flip(p: float) -> bool:
|
... | @@ -354,3 +354,184 @@ checklist](https://www.cs.odu.edu/~tkennedy/cs330/f20/Public/classChecklistCross |
... | @@ -354,3 +354,184 @@ checklist](https://www.cs.odu.edu/~tkennedy/cs330/f20/Public/classChecklistCross |
|
| `begin()` and `end()` | `iterator` | `__iter__` | `iter()` and `iter_mut()` |
|
|
| `begin()` and `end()` | `iterator` | `__iter__` | `iter()` and `iter_mut()` |
|
|
|
|
|
|
|
|
|
|
|
|
Whenever Python code is written, the first function most people write is usually
|
|
|
|
`__init__`... since it serves as a constructor to initialize the fields (data
|
|
|
|
members) of each new object. For now... let us focus on three methods:
|
|
|
|
|
|
|
|
- `__str__` - generates a human readable string for output.
|
|
|
|
- `__repr--` - generates a *complete* string for debugging, often in the form
|
|
|
|
of a string that fully describes an object.
|
|
|
|
- `__eq__` - compares two objects, returning `True` if they are equal. The
|
|
|
|
objects need not be of the same type.
|
|
|
|
|
|
|
|
|
|
|
|
## Tic-Tac-Toe Example
|
|
|
|
|
|
|
|
The code snippets in this section are part of a larger Tic-Tac-Toe example. The
|
|
|
|
full source code can be found in this [workshop's Git
|
|
|
|
repository](https://git-community.cs.odu.edu/tkennedy/python-workshop/-/tree/master/OOP/Tic-Tac-Toe).
|
|
|
|
|
|
|
|
Let us start with the Player class. Note that the code is fully documented with
|
|
|
|
pydoc documentation and type hints.
|
|
|
|
|
|
|
|
*Note: The use of `class Player(object):` is a holdover from Python 2.* In
|
|
|
|
modern Python 3, it should not be used. The `(object)` should be omitted. The
|
|
|
|
line should be `class Player:`.
|
|
|
|
|
|
|
|
|
|
|
|
```python
|
|
|
|
class Player(object):
|
|
|
|
"""
|
|
|
|
This is more a Player interface than a Player class.
|
|
|
|
<p>
|
|
|
|
However, such distinctions and discussions belong in
|
|
|
|
the OOP and Inheritance Modules
|
|
|
|
"""
|
|
|
|
|
|
|
|
PROMPT_MSG = "Enter your desired move (1-9): "
|
|
|
|
"""
|
|
|
|
Message used to prompt a human player for a move.
|
|
|
|
"""
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def is_generic(possible_cylon: "Player") -> bool:
|
|
|
|
"""
|
|
|
|
Checks whether a player is a placeholder or
|
|
|
|
an actual player.
|
|
|
|
|
|
|
|
Args:
|
|
|
|
possible_cylon (Player): player whose humanity is in question
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
True if the player is a Cylon
|
|
|
|
"""
|
|
|
|
|
|
|
|
# print(REFERENCE_CYLON)
|
|
|
|
return possible_cylon == REFERENCE_CYLON
|
|
|
|
|
|
|
|
def __init__(self, n: str = "I. C. Generic"):
|
|
|
|
"""
|
|
|
|
Create a Player with a selected name.
|
|
|
|
|
|
|
|
Args:
|
|
|
|
n: desired name
|
|
|
|
"""
|
|
|
|
|
|
|
|
self._name = n
|
|
|
|
self._symbol = '?' # testing caught this
|
|
|
|
|
|
|
|
def get_name(self) -> str:
|
|
|
|
"""
|
|
|
|
Retrieve name.
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
player name
|
|
|
|
"""
|
|
|
|
|
|
|
|
return self._name
|
|
|
|
|
|
|
|
def set_name(self, n: str):
|
|
|
|
"""
|
|
|
|
Set player name.
|
|
|
|
|
|
|
|
@param n new name
|
|
|
|
|
|
|
|
@pre (n.size() > 0)
|
|
|
|
"""
|
|
|
|
|
|
|
|
self._name = n
|
|
|
|
|
|
|
|
def next_move(self) -> str:
|
|
|
|
"""
|
|
|
|
Retrieve the next move.
|
|
|
|
|
|
|
|
@return board cell id representing the selected move
|
|
|
|
|
|
|
|
@throws IOException if the move can not be retreived from the player.
|
|
|
|
"""
|
|
|
|
|
|
|
|
choice = int(input(self._name + ", " + Player.PROMPT_MSG))
|
|
|
|
|
|
|
|
return choice
|
|
|
|
|
|
|
|
def is_human(self) -> bool:
|
|
|
|
"""
|
|
|
|
Is this a Human Player?
|
|
|
|
|
|
|
|
In this discussion, always yes :(
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
True if the player is a human
|
|
|
|
"""
|
|
|
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
def is_computer(self):
|
|
|
|
"""
|
|
|
|
Is this a Computer Player?
|
|
|
|
|
|
|
|
In this discussion, always no :(
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
True if the player is a Cylon
|
|
|
|
"""
|
|
|
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
def get_symbol(self) -> str:
|
|
|
|
"""
|
|
|
|
Retrieve player symbol to be used
|
|
|
|
for marking moves.
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
current player symbol
|
|
|
|
"""
|
|
|
|
|
|
|
|
return self._symbol
|
|
|
|
|
|
|
|
def set_symbol(self, new_symbol: str):
|
|
|
|
"""
|
|
|
|
Change the player symbol.
|
|
|
|
|
|
|
|
Args:
|
|
|
|
new_symbol: new character to be used by the player
|
|
|
|
"""
|
|
|
|
|
|
|
|
self._symbol = new_symbol
|
|
|
|
|
|
|
|
def __eq__(self, rhs):
|
|
|
|
if not isinstance(rhs, self.__class__):
|
|
|
|
return False
|
|
|
|
|
|
|
|
return self._name == rhs._name
|
|
|
|
|
|
|
|
def __hash__(self):
|
|
|
|
return hash(self._name)
|
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
"""
|
|
|
|
Generate a player string, but only the name.
|
|
|
|
"""
|
|
|
|
|
|
|
|
return self._name
|
|
|
|
|
|
|
|
def __deepcopy__(self, memo):
|
|
|
|
"""
|
|
|
|
Create a new duplicate Player.
|
|
|
|
"""
|
|
|
|
|
|
|
|
cpy = Player(self._name)
|
|
|
|
cpy.set_symbol(self._symbol)
|
|
|
|
|
|
|
|
return cpy
|
|
|
|
|
|
|
|
|
|
|
|
REFERENCE_CYLON = Player()
|
|
|
|
"""
|
|
|
|
A Player that serves as a sentinal value or placeholder.
|
|
|
|
"""
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|