-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathtile.py
130 lines (115 loc) · 3.72 KB
/
tile.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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
66
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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
"""
This module contains the Tile class, which described a
single hexagonal tile.
"""
from typing import Optional, Any
class Tile:
"""
This class contains all data required to define a tile.
As Python does not support access control, any members that
must not be accessed externally are prefixed with an underscore.
"""
def __init__(self, game: Any, x: int, y: int) -> None:
self.game = game
self.x_coord = x
self.y_coord = y
self._revealed = False
self._mine = False
self._flag = False
def is_revealed(self) -> bool:
"""
Checks if the tile is revealed (i.e. has been clicked on)
"""
return self._revealed
def has_mine(self) -> bool:
"""
Checks if the tile has a mine
"""
return self._mine
def has_flag(self) -> bool:
"""
Checks if the user has set a flag on this tile
"""
return self._flag
def adjacent_mine_count(self) -> int:
"""
Returns the number of adjacent mines to this current tile
"""
return self.game.adjacent_mine_count(self.x_coord,
self.y_coord)
def has_adjacent_mines(self) -> bool:
"""
Returns whether the current tile has any adjacent mines.
"""
return self.adjacent_mine_count() > 0
def color(self) -> str:
"""
Colour to use for rendering this tile as a hexagon
"""
if self.is_revealed():
if self.has_mine():
return 'red'
if self.has_adjacent_mines():
return 'orange'
return 'lightgreen'
if self.has_flag():
return 'purple'
return 'lightblue'
def text(self) -> Optional[str]:
"""
Text that should be shown on this tile
"""
if not self.has_mine() and self.is_revealed():
if self.has_adjacent_mines():
return str(self.adjacent_mine_count())
# otherwise return None, which will prevent
# any text from being shown on this tile
return None
def can_toggle_flag(self) -> bool:
"""
Whether the user is allowed to set/unset flags on this tile
"""
if self.has_flag():
return True
old_color = self.color()
self._flag = True
new_color = self.color()
self._flag = False
if old_color == new_color:
return False
return True
def change_into_mine(self) -> None:
"""
Tile.__init__ only creates non-mine tiles. This method
can then be used to change some of those tiles into mines.
"""
self._mine = True
def set_flag(self) -> None:
""" If allowed, change this tile to have a flag """
if self.has_flag():
return
if not self.can_toggle_flag():
return
self._flag = True
def unset_flag(self) -> None:
""" If allowed, change this tile to not have a flag """
if not self.has_flag():
return
if not self.can_toggle_flag():
return
self._flag = False
def reveal(self) -> None:
"""
Called on left-click and also when the game is over
and all tiles (incl. mine positions) are revealed to the user.
"""
if not self.has_flag():
self._revealed = True
def __repr__(self) -> str:
"""
Useful only for debugging: this text is printed to the console
when you try to print a tile object.
"""
return (f'<Tile revealed={self.is_revealed()} '
+ f'mine={self.has_mine()} '
+ f'flag={self.has_flag()}>')