Skip to content
This repository was archived by the owner on Jul 2, 2024. It is now read-only.

Commit 51f2365

Browse files
committed
WKT: updated models documentation
Signed-off-by: Serhii Horodilov <sgorodil@gmail.com>
1 parent e92c33f commit 51f2365

File tree

1 file changed

+118
-18
lines changed

1 file changed

+118
-18
lines changed

src/wtk/models.py

Lines changed: 118 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,36 @@
11
"""
2+
***********
23
Game models
4+
***********
5+
6+
Enemy
7+
=====
8+
9+
.. autoclass:: Enemy
10+
:members: decrease_health, select_attack, select_defence
11+
:special_members: __init__
12+
13+
Player
14+
======
15+
16+
.. autoclass:: Player
17+
:members: decrease_health, select_attack, select_defence, attack, defence
18+
:special_members: __init__
319
420
"""
521

622
import logging
723
import random
824
from abc import ABC, abstractmethod
25+
from functools import wraps
926

1027
from wtk import settings
1128
from wtk.enums import FightChoice, FightResult, get_fight_result
1229
from wtk.exceptions import EnemyDown, GameOver
1330
from wtk.loggers import stream_handler
1431

32+
__all__ = ["Enemy", "Player"]
33+
1534

1635
class _AbstractModel(ABC):
1736
"""Abstract game model"""
@@ -30,17 +49,26 @@ def decrease_health(self) -> None:
3049

3150

3251
class Enemy(_AbstractModel):
33-
"""Enemy model
52+
"""
53+
Enemy model
3454
35-
:ivar level: enemy's level
55+
Represents the playing enemy-bot.
56+
57+
:ivar level: enemy's level value
3658
:type level: int
3759
:ivar health: enemy's instance health points
3860
:type health: int
3961
4062
"""
4163

4264
def __init__(self, level: int = settings.INITIAL_ENEMY_LEVEL) -> None:
43-
"""Initialize instance"""
65+
"""
66+
Initialize instance
67+
68+
:param level: an enemy's level indicator
69+
:type level: int
70+
71+
"""
4472

4573
self.health = level
4674
self.level = level
@@ -56,7 +84,11 @@ def __str__(self) -> str:
5684
return f"Enemy level {self.level}"
5785

5886
def decrease_health(self) -> None:
59-
"""Decrease health points
87+
"""
88+
Decrease health points
89+
90+
This method decreases the health meter value. When it comes to be
91+
less than 1 (one) an ``EnemyDown`` exception is raised.
6092
6193
:raise: EnemyDown
6294
@@ -68,28 +100,38 @@ def decrease_health(self) -> None:
68100

69101
@staticmethod
70102
def _select_fight_choice() -> FightChoice: # pragma: no cover
71-
"""Return a random fight choice"""
103+
"""
104+
Return a random fight choice
105+
106+
Choices made by an enemy are random.
107+
108+
:return: a fight choice
109+
110+
"""
72111

73112
return random.choice(tuple(FightChoice))
74113

114+
@wraps(_select_fight_choice, ("__annotations__", "__doc__"))
75115
def select_attack(self) -> FightChoice: # pragma: no cover
76116
return self._select_fight_choice()
77117

118+
@wraps(_select_fight_choice, ("__annotations__", "__doc__"))
78119
def select_defence(self) -> FightChoice: # pragma: no cover
79120
return self._select_fight_choice()
80121

81122

82123
class Player(_AbstractModel):
83-
"""Player model
124+
"""
125+
Player model
126+
127+
This model is controlled by the player.
84128
85129
:ivar name: player's name
86130
:type name: str
87131
:ivar health: player's instance health points
88132
:type health: int
89133
:ivar score: player's instance gained score points
90134
:type score: int
91-
:cvar logger: class based message logger
92-
:type logger: :class: `logging.Logger`
93135
94136
"""
95137

@@ -98,7 +140,16 @@ class Player(_AbstractModel):
98140
logger.addHandler(stream_handler)
99141

100142
def __init__(self, name: str) -> None:
101-
"""Initialize instance"""
143+
"""
144+
Initialize instance
145+
146+
This method performs player instance initialization. It set instance
147+
name, initial score points value and health.
148+
149+
:param name: a player's name
150+
:type name: str
151+
152+
"""
102153

103154
self.name = name
104155
self.health = settings.INITIAL_PLAYER_HEALTH
@@ -115,7 +166,11 @@ def __str__(self) -> str:
115166
return self.name
116167

117168
def decrease_health(self) -> None:
118-
"""Decrease instance health points
169+
"""
170+
Decrease health points
171+
172+
This method decreases the health meter value. When it comes to be
173+
less than 1 (one) an ``GameOver`` exception is raised.
119174
120175
:raise: GameOver
121176
@@ -127,7 +182,16 @@ def decrease_health(self) -> None:
127182

128183
@staticmethod
129184
def _select_fight_choice() -> FightChoice:
130-
"""Return fight choice from the user's prompt"""
185+
"""
186+
Return fight choice from the user's prompt
187+
188+
The player is asked to make their decision for the upcoming fight.
189+
The chosen value is validated and if it is invalid the question is
190+
repeated.
191+
192+
:return: a fight choice
193+
194+
"""
131195

132196
choices = ", ".join(
133197
f"{choice.name} - {choice.value}" for choice in FightChoice
@@ -140,25 +204,50 @@ def _select_fight_choice() -> FightChoice:
140204
except ValueError:
141205
pass
142206

207+
@wraps(_select_fight_choice, ("__annotations__", "__doc__"))
143208
def select_attack(self) -> FightChoice: # pragma: no cover
144209
return self._select_fight_choice()
145210

211+
@wraps(_select_fight_choice, ("__annotations__", "__doc__"))
146212
def select_defence(self) -> FightChoice: # pragma: no cover
147213
return self._select_fight_choice()
148214

149215
@staticmethod
150216
def fight(attack: FightChoice, defence: FightChoice) -> FightResult:
151-
"""Implements a fight result calculation interface"""
217+
"""
218+
Fight result calculation interface
219+
220+
The method calculates the fight result based on the game rules:
221+
222+
- **knight** beats **thief**
223+
- **thief** beats **wizard**
224+
- **wizard** beats **knight**
225+
226+
"""
152227

153228
return get_fight_result(attack, defence)
154229

155230
def add_score_points(self, score_points: int) -> None:
156-
"""Add score points"""
231+
"""Add score points to the player instance"""
157232

158233
self.score += score_points
159234

160235
def attack(self, enemy: Enemy) -> None:
161-
"""Attack an enemy"""
236+
"""
237+
Attack an enemy
238+
239+
Perform attack on an enemy instance. This method takes an enemy
240+
instance as an argument. After that, it takes attack choice from
241+
the player model and the defence choice from an enemy model.
242+
After fight result calculation required operation are to be
243+
performed (decrease enemy health, assign score points etc.).
244+
Based on fight result should print out a message:
245+
246+
- "YOUR ATTACK IS SUCCESSFUL!"
247+
- "YOUR ATTACK IS FAILED!"
248+
- "IT'S A DRAW!"
249+
250+
"""
162251

163252
attack = self.select_attack()
164253
defence = enemy.select_defence()
@@ -180,7 +269,21 @@ def attack(self, enemy: Enemy) -> None:
180269
self.logger.info(settings.MSG_DRAW)
181270

182271
def defence(self, enemy: Enemy) -> None:
183-
"""Defend from an enemy's attack"""
272+
"""
273+
Defend from an enemy's attack
274+
275+
Perform defence from an enemy attack. This method takes an enemy
276+
instance as an argument. After that, it takes defence choice from
277+
the player model and the attack choice from an enemy model.
278+
After fight result calculation required operation are to be
279+
performed (decrease player health).
280+
Based on fight result should print out a message:
281+
282+
- "YOUR DEFENCE IS SUCCESSFUL!"
283+
- "YOUR DEFENCE IS FAILED!"
284+
- "IT'S A DRAW!"
285+
286+
"""
184287

185288
attack = enemy.select_attack()
186289
defence = self.select_defence()
@@ -194,6 +297,3 @@ def defence(self, enemy: Enemy) -> None:
194297
self.logger.info(settings.MSG_SUCCESS_DEFENCE)
195298
elif fight_result == FightResult.DRAW:
196299
self.logger.info(settings.MSG_DRAW)
197-
198-
199-
__all__ = ["Enemy", "Player"]

0 commit comments

Comments
 (0)