Coverage for zombie_nomnom/models/dice.py: 100%
43 statements
« prev ^ index » next coverage.py v7.6.8, created at 2024-12-05 01:14 +0000
« prev ^ index » next coverage.py v7.6.8, created at 2024-12-05 01:14 +0000
1"""
2This module contains everything we care about when it comes to the die.
3We define a class to contain the faces as well as be able to select one
4using the random built-in library.
6We can instatation an instance like this
7```python
8from zombie_nomnom.models.dice import Die, Face
10custom_die = Die(faces=[
11 Face.BRAIN,
12 Face.BRAIN,
13 Face.BRAIN,
14 Face.SHOTGUN
15 Face.SHOTGUN,
16 Face.SHOTGUN,
17])
19# is currently set to None because it was not set.
20custom_die.current_face
22# roll and calculate the current face
23custom_die.roll()
25# will be one of the faces in the in the faces array
26custom_die.current_face
27```
29Most of the time you will want to use a preconfigured recipe
30To build your dice which you can use our `create_die` method.
32```python
33from zombie_nomnom.models.dice import create_die, DieColor
35green_die = create_die(DieColor.GREEN)
37yellow_die = create_die(DieColor.YELLOW)
39red_die = create_die(DieColor.RED)
40```
42Most of the die in the game are already pre-defined so you can expirement
43and use different dice as you make your own custom games.
45"""
47from enum import Enum
48from pydantic import BaseModel, Field, field_validator
49import random
52class Face(str, Enum):
53 """
54 Face of the die for the game.
56 There are three core ones:
57 - BRAIN: Single point scoring face
58 - FOOT: Neutral dice that will be re-rolled first before any other die are given.
59 - SHOTGUN: Damaging dice where you are limited to only so many before your turn is over.
60 """
62 BRAIN = "BRAIN"
63 """Scoring `Face` worth a single point.
64 """
65 FOOT = "FOOT"
66 """Neutral `Face` that we will reroll.
67 """
68 SHOTGUN = "SHOTGUN"
69 """Damaging `Face` that may end the turn.
70 """
73class DieFace(BaseModel):
74 """
75 Represents a custom face on a die. Used to allow us to be able to score extra points or damage on a player when drawn.
76 """
78 name: str
79 """Name of the face."""
80 score: int
81 """Amount of points a player will gain from face."""
82 damage: int
83 """Amount of damage a player will take from face."""
86class DieColor(str, Enum):
87 """
88 Names of special core dice in the game.
89 There are only three to begin with: RED, YELLOW, GREEN
90 """
92 RED = "RED"
93 """The hardest die to score on in the game with only a single side.
94 """
95 YELLOW = "YELLOW"
96 """The most medium die to score on with an equal number of brain and shot sides.
97 """
98 GREEN = "GREEN"
99 """The most forgiving dice with only a single side that will damage you.
100 """
103# TODO(Milo): Update this for custom exception on invalid dice.
104class Die(BaseModel):
105 """
106 Represents the die we are rolling in the game.
107 This is currently enforced to only support 6 sided dice.
108 """
110 name: str | None = None
111 """
112 The plaintext name of the die.
113 """
114 faces: list[DieFace | Face] = Field(min_length=6, max_length=6)
115 """
116 faces of the dice. It is currently only allowed to have 6 values.
117 """
118 current_face: Face | DieFace | None = None
119 """
120 The currently displayed face of the die. Defaults to None.
121 """
123 def roll(self) -> Face:
124 """Rolls the dice using the `builtins.random` and updates the current_face field.
126 **Returns**
127 - `Face`: The face that the die is now on.
128 """
129 self.current_face = random.choice(self.faces)
130 return self.current_face
133_dice_face_mapping = {
134 DieColor.RED: {Face.BRAIN: 1, Face.FOOT: 2, Face.SHOTGUN: 3},
135 DieColor.YELLOW: {Face.BRAIN: 2, Face.FOOT: 2, Face.SHOTGUN: 2},
136 DieColor.GREEN: {Face.BRAIN: 3, Face.FOOT: 2, Face.SHOTGUN: 1},
137}
140# TODO(Milo): Update this with custom exception for invalid dice.
141def create_die(color: DieColor) -> Die:
142 """Factory method to take in a `DieColor` and then create a die based on that.
143 Only supports the first three colors defined: `DieColor.RED`, `DieColor.YELLOW`, `DieColor.GREEN`.
145 **Parameters**
146 - color (`DieColor`): The color of the dice you want the factory to produce.
148 `Raises`:
149 - `ValueError`: When we are unable to resolve the color to a known recipe.
151 `Returns`
152 - `Die`: The dice defined by the color given.
153 """
154 if color not in _dice_face_mapping:
155 raise ValueError(f"Unknown Die Color: {color}")
157 mapped_color = _dice_face_mapping[color]
158 faces = []
159 for face, amount in mapped_color.items():
160 faces.extend([face] * amount)
161 return Die(faces=faces, name=color)