Skip to content

Commit f75c13a

Browse files
Merge pull request #79 from pavelmachek/m_11_flood
floodit: simple game
2 parents 7b3501e + 0b85528 commit f75c13a

3 files changed

Lines changed: 234 additions & 0 deletions

File tree

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"name": "Floodit",
3+
"publisher": "Pavel Machek",
4+
"short_description": "Simple game with colors.",
5+
"long_description": "Game with colors, where objective is to turn whole board into single color in minimum number of steps.",
6+
"icon_url": "https://apps.micropythonos.com/apps/cz.ucw.pavel.floodit/icons/cz.ucw.pavel.floodit_0.0.1_64x64.png",
7+
"download_url": "https://apps.micropythonos.com/apps/cz.ucw.pavel.floodit/mpks/cz.ucw.pavel.floodit_0.0.1.mpk",
8+
"fullname": "cz.ucw.pavel.floodit",
9+
"version": "0.0.1",
10+
"category": "utilities",
11+
"activities": [
12+
{
13+
"entrypoint": "assets/main.py",
14+
"classname": "Main",
15+
"intent_filters": [
16+
{
17+
"action": "main",
18+
"category": "launcher"
19+
}
20+
]
21+
}
22+
]
23+
}
24+
Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
import time
2+
import random
3+
4+
"""
5+
Flood-It game
6+
7+
Fill the entire board with a single color
8+
using the smallest number of moves.
9+
10+
Touch a color button to flood the region
11+
starting from the top-left corner.
12+
"""
13+
14+
from mpos import Activity
15+
16+
try:
17+
import lvgl as lv
18+
except ImportError:
19+
pass
20+
21+
22+
class Main(Activity):
23+
24+
COLS = 10
25+
ROWS = 10
26+
27+
COLORS = [
28+
0xE74C3C, # red
29+
0xF1C40F, # yellow
30+
0x2ECC71, # green
31+
0x3498DB, # blue
32+
0x9B59B6, # purple
33+
0xE67E22, # orange
34+
]
35+
36+
def __init__(self):
37+
super().__init__()
38+
39+
self.board = []
40+
self.cells = []
41+
42+
self.moves = 0
43+
44+
# ---------------------------------------------------------------------
45+
46+
def onCreate(self):
47+
48+
self.screen = lv.obj()
49+
self.screen.remove_flag(lv.obj.FLAG.SCROLLABLE)
50+
51+
font = lv.font_montserrat_20
52+
53+
score = lv.label(self.screen)
54+
score.align(lv.ALIGN.TOP_LEFT, 5, 25)
55+
score.set_text("Moves")
56+
score.set_style_text_font(font, 0)
57+
self.lb_score = score
58+
59+
d = lv.display_get_default()
60+
self.SCREEN_WIDTH = d.get_horizontal_resolution()
61+
self.SCREEN_HEIGHT = d.get_vertical_resolution()
62+
63+
# color buttons
64+
btn_size = 45
65+
spacing = 5
66+
67+
self.CELL = min(
68+
self.SCREEN_WIDTH // (self.COLS + 2),
69+
(self.SCREEN_HEIGHT - btn_size) // (self.ROWS + 3)
70+
)
71+
72+
board_x = (self.SCREEN_WIDTH - self.CELL * self.COLS) // 2
73+
board_y = (self.SCREEN_HEIGHT - self.CELL * self.ROWS) // 2
74+
75+
for r in range(self.ROWS):
76+
row = []
77+
for c in range(self.COLS):
78+
79+
o = lv.obj(self.screen)
80+
o.set_size(self.CELL - 2, self.CELL - 2)
81+
82+
o.set_pos(
83+
board_x + c * self.CELL + 1,
84+
board_y + r * self.CELL + 1 - btn_size // 2
85+
)
86+
87+
o.set_style_radius(4, 0)
88+
o.set_style_border_width(1, 0)
89+
90+
row.append(o)
91+
92+
self.cells.append(row)
93+
94+
95+
for i, col in enumerate(self.COLORS):
96+
97+
btn = lv.button(self.screen)
98+
btn.set_size(btn_size, btn_size)
99+
100+
btn.align(
101+
lv.ALIGN.BOTTOM_LEFT,
102+
5 + i * (btn_size + spacing),
103+
-5
104+
)
105+
106+
btn.set_style_bg_color(lv.color_hex(col), 0)
107+
108+
btn.add_event_cb(
109+
lambda e, c=i: self.pick_color(c),
110+
lv.EVENT.CLICKED,
111+
None
112+
)
113+
114+
focusgroup = lv.group_get_default()
115+
if focusgroup:
116+
focusgroup.add_obj(self.screen)
117+
118+
self.setContentView(self.screen)
119+
120+
self.new_game()
121+
122+
# ---------------------------------------------------------------------
123+
124+
def new_game(self):
125+
126+
self.moves = 0
127+
self.lb_score.set_text("Moves\n0")
128+
129+
self.board = [
130+
[random.randrange(len(self.COLORS)) for _ in range(self.COLS)]
131+
for _ in range(self.ROWS)
132+
]
133+
134+
self.redraw()
135+
136+
# ---------------------------------------------------------------------
137+
138+
def pick_color(self, color):
139+
140+
start_color = self.board[0][0]
141+
142+
if start_color == color:
143+
return
144+
145+
self.flood_fill(start_color, color)
146+
147+
self.moves += 1
148+
self.lb_score.set_text("Moves\n%d" % self.moves)
149+
150+
self.redraw()
151+
152+
if self.check_win():
153+
self.win()
154+
155+
# ---------------------------------------------------------------------
156+
157+
def flood_fill(self, old, new):
158+
159+
stack = [(0, 0)]
160+
161+
while stack:
162+
163+
r, c = stack.pop()
164+
165+
if not (0 <= r < self.ROWS and 0 <= c < self.COLS):
166+
continue
167+
168+
if self.board[r][c] != old:
169+
continue
170+
171+
self.board[r][c] = new
172+
173+
stack.append((r + 1, c))
174+
stack.append((r - 1, c))
175+
stack.append((r, c + 1))
176+
stack.append((r, c - 1))
177+
178+
# ---------------------------------------------------------------------
179+
180+
def check_win(self):
181+
182+
color = self.board[0][0]
183+
184+
for r in range(self.ROWS):
185+
for c in range(self.COLS):
186+
if self.board[r][c] != color:
187+
return False
188+
189+
return True
190+
191+
# ---------------------------------------------------------------------
192+
193+
def win(self):
194+
195+
label = lv.label(self.screen)
196+
label.set_text("Finished in %d moves!" % self.moves)
197+
label.center()
198+
199+
# ---------------------------------------------------------------------
200+
201+
def redraw(self):
202+
203+
for r in range(self.ROWS):
204+
for c in range(self.COLS):
205+
206+
v = self.board[r][c]
207+
208+
self.cells[r][c].set_style_bg_color(
209+
lv.color_hex(self.COLORS[v]), 0
210+
)
10 KB
Loading

0 commit comments

Comments
 (0)