-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathflooder.py
More file actions
191 lines (160 loc) · 6.26 KB
/
flooder.py
File metadata and controls
191 lines (160 loc) · 6.26 KB
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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
import random, sys
try:
import bext
except ImportError:
print('This program requires the bext module, which you')
print('can install by following the instructions at')
print('https://pypi.org/project/Bext/')
sys.exit()
# Set up the constants:
BOARD_WIDTH = 16 # (!) Try changing 4 or 40
BOARD_HEIGHT = 14 # (!) Try changin this to 4 or 20
MOVES_PER_GAME = 20 # (!) Try changinthis to 3 or 300
# constant for the diferent shapes used in colorblind mode:
HEART = chr(9829) # character 9829 is '♥'.
DIAMOND = chr(9830) # character 9830 is '♦'.
SPADE = chr(9824) # character 9824 is '♠'.
CLUB = chr(9827) # character 9827 is '♣'.
BALL = chr(9679) # character 9879 is '●'.
TRIANGLE = chr(9650) # character 9650 is '▲'.
BLOCK = chr(9608) # character 9608 is '█'
LEFTRIGHT = chr(9472) # character 9472 is '─'
UPDOWN = chr(9474) # character 9474 is '│'
DOWNRIGHT = chr(9484) # character 9484 is '┌'
DOWNLEFT = chr(9488) # character 9488 is '┐'
UPRIGHT = chr(9492) # character 9492 is '└'
UPLEFT = chr (9496) # character 9496 is '┘'
# A list of chr() coes is at https://inventwithpython.com/chr
# All the color/shape tiles used on the board:
tile_types = (0, 1, 2, 3 , 4, 5)
COLORS_MAP = {0: 'red', 1: 'green', 2:'blue',
3:'yellow', 4:'cyan', 5:'purple'}
COLOR_MODE = 'color mode'
SHAPES_MAP = {0: HEART, 1: TRIANGLE, 2:DIAMOND,
3: BALL, 4: CLUB, 5: SPADE}
SHAPE_MODE = 'shape mode'
def main():
bext.bg('black')
bext.fg('white')
bext.clear()
print('''Flooder, by Al sweigart al@inventwithpython.com
Set the upper left color/shape, which fills in all the
adjacent squares of that color/shape. Try to make the
entire board the same color/shape.''')
print('Do you want to play in colorblind mode Y/N')
response = input('> ')
if response.upper().startswith('Y'):
displayMode = SHAPE_MODE
else:
displayMode = COLOR_MODE
gameBoard = getNewBoard()
movesLeft = MOVES_PER_GAME
while True: # Main game loop.
displayBoard(gameBoard, displayMode)
print('Moves left:', movesLeft)
playerMove = askforPlayerMove(displayMode)
changeTile(playerMove, gameBoard, 0, 0)
movesLeft -= 1
if hasWon(gameBoard):
displayBoard(gameBoard, displayMode)
print('You have won!')
break
elif movesLeft == 0:
displayBoard(gameBoard, displayMode)
print('You have won!')
break
elif movesLeft == 0:
displayBoard(gameBoard, displayMode)
print('You have run out of moves!')
break
def getNewBoard():
"""Return a dictionary of a new Flood it board."""
# Keys are (x, y) tuples, values are the tile at that position.
board ={}
# Create random colors for the board.
for x in range(BOARD_WIDTH):
for y in range(BOARD_HEIGHT):
board[(x,y)] = random.choice(TILE_TYPES)
# Make several tiles the same as their neighbor. This creates groups
# of the same color/shape.
for i in range(BOARD_WIDTH * BOARD_HEIGHT):
x = random.randint(0, BOARD_HEIGHT - 2)
y = random.randint(0, BOARD_HEIGHT - 1)
board[(x +1,y )] = board[(x,y)]
return board
def displayBoard(board, displayMode):
""" Display the board on the screen."""
bext.fg('white')
# Display the top edge of the board:
print(DOWNRIGHT + (LEFTRIGHT * BOARD_WIDTH) + DOWNLEFT)
# Display each row:
for y in range(BOARD_HEIGHT):
bext.fg('white')
if y == 0: # the first row begins with '>'.
print('>', end='')
else: # ater rows begin with a white vertical line.
print(UPDOWN, end='')
# Display each tile in this row:
for x in range(BOARD_WIDTH):
bext.fg(COLORS_MAP[board[(x, y)]])
if displayMode == COLOR_MODE:
print(BLOCK, end='')
elif displayMode == SHAPE_MODE:
print(SHAPES_MAP[board[x,y]], end='')
bext.fg('white')
print(UPDOWN) # Rows end with a white vertical line.
# Display the bottom edge of the board:
print(UPRIGHT + (LEFTRIGHT + BOARD_WIDTH) + UPLEFT)
def askForPlayerMove(displayMode):
"""Let the player select a color to paint te uppper left tile."""
while True:
bext.fg('white')
print('Choose one of ', end='')
if displayMode == COLOR_MODE:
bext.fg('red')
print('(R)ed ', end='')
bext.fg('green')
print('(G)reen ', end='')
bext.fg('blue')
print('(B)lue ', end='')
bext.fg('yellow')
print('(Y)ellow ', end='')
bext.fg('cyan')
print('(C)yan ', end='')
bext.fg('purple')
print('(P)urple ', end='')
elif displayMode == SHAPE_MODE:
bext.fg('red')
print('(H)eart ', end='')
bext.fg('green')
print('(T)riangle ', end='')
bext.fg('blue')
print('(D)iamond ', end='')
bext.fg('yellow')
print('(B)all ', end='')
bext.fg('cyan')
print('(C)lub ', end='')
bext.fg('purple')
print('(S)pade ', end='')
bext.fg('white')
print('or QUIT:')
response = input('> ').upper()
if response == 'QUIT':
print('thanks for playing!')
sys.exit()
if displyMode == COLOR_MODE and response in tuple('RGBYCP'):
# Return a tile type number based on the respone:
return {'R': 0, 'G': 1, 'B': 2,
'Y': 3, 'C': 4, 'P': 5}[response]
if displayMode == SHAPE_MODE and response in tuple('HTDBCS'):
# Return a tile type number based on the response:
return {'H': 0, 'T': 1, 'D':2,
'B': 3, 'C': 4, 'S': 5}[response]
def changTile(tileType, board, x, y, charToChange=None):
"""Change the color/shape of a tile using the recursive flood fill
algorithm."""
if x == 0 and y == 0:
charToChange = board[(x, y)]
if tileType == charToChange:
return # Base Case: Already is the same tile.
board[(x, y)] = tileType