Merge pull request #79 from pavelmachek/m_11_flood

floodit: simple game
This commit is contained in:
Thomas Farstrike
2026-03-11 09:36:19 +01:00
committed by GitHub
3 changed files with 234 additions and 0 deletions
@@ -0,0 +1,24 @@
{
"name": "Floodit",
"publisher": "Pavel Machek",
"short_description": "Simple game with colors.",
"long_description": "Game with colors, where objective is to turn whole board into single color in minimum number of steps.",
"icon_url": "https://apps.micropythonos.com/apps/cz.ucw.pavel.floodit/icons/cz.ucw.pavel.floodit_0.0.1_64x64.png",
"download_url": "https://apps.micropythonos.com/apps/cz.ucw.pavel.floodit/mpks/cz.ucw.pavel.floodit_0.0.1.mpk",
"fullname": "cz.ucw.pavel.floodit",
"version": "0.0.1",
"category": "utilities",
"activities": [
{
"entrypoint": "assets/main.py",
"classname": "Main",
"intent_filters": [
{
"action": "main",
"category": "launcher"
}
]
}
]
}
@@ -0,0 +1,210 @@
import time
import random
"""
Flood-It game
Fill the entire board with a single color
using the smallest number of moves.
Touch a color button to flood the region
starting from the top-left corner.
"""
from mpos import Activity
try:
import lvgl as lv
except ImportError:
pass
class Main(Activity):
COLS = 10
ROWS = 10
COLORS = [
0xE74C3C, # red
0xF1C40F, # yellow
0x2ECC71, # green
0x3498DB, # blue
0x9B59B6, # purple
0xE67E22, # orange
]
def __init__(self):
super().__init__()
self.board = []
self.cells = []
self.moves = 0
# ---------------------------------------------------------------------
def onCreate(self):
self.screen = lv.obj()
self.screen.remove_flag(lv.obj.FLAG.SCROLLABLE)
font = lv.font_montserrat_20
score = lv.label(self.screen)
score.align(lv.ALIGN.TOP_LEFT, 5, 25)
score.set_text("Moves")
score.set_style_text_font(font, 0)
self.lb_score = score
d = lv.display_get_default()
self.SCREEN_WIDTH = d.get_horizontal_resolution()
self.SCREEN_HEIGHT = d.get_vertical_resolution()
# color buttons
btn_size = 45
spacing = 5
self.CELL = min(
self.SCREEN_WIDTH // (self.COLS + 2),
(self.SCREEN_HEIGHT - btn_size) // (self.ROWS + 3)
)
board_x = (self.SCREEN_WIDTH - self.CELL * self.COLS) // 2
board_y = (self.SCREEN_HEIGHT - self.CELL * self.ROWS) // 2
for r in range(self.ROWS):
row = []
for c in range(self.COLS):
o = lv.obj(self.screen)
o.set_size(self.CELL - 2, self.CELL - 2)
o.set_pos(
board_x + c * self.CELL + 1,
board_y + r * self.CELL + 1 - btn_size // 2
)
o.set_style_radius(4, 0)
o.set_style_border_width(1, 0)
row.append(o)
self.cells.append(row)
for i, col in enumerate(self.COLORS):
btn = lv.button(self.screen)
btn.set_size(btn_size, btn_size)
btn.align(
lv.ALIGN.BOTTOM_LEFT,
5 + i * (btn_size + spacing),
-5
)
btn.set_style_bg_color(lv.color_hex(col), 0)
btn.add_event_cb(
lambda e, c=i: self.pick_color(c),
lv.EVENT.CLICKED,
None
)
focusgroup = lv.group_get_default()
if focusgroup:
focusgroup.add_obj(self.screen)
self.setContentView(self.screen)
self.new_game()
# ---------------------------------------------------------------------
def new_game(self):
self.moves = 0
self.lb_score.set_text("Moves\n0")
self.board = [
[random.randrange(len(self.COLORS)) for _ in range(self.COLS)]
for _ in range(self.ROWS)
]
self.redraw()
# ---------------------------------------------------------------------
def pick_color(self, color):
start_color = self.board[0][0]
if start_color == color:
return
self.flood_fill(start_color, color)
self.moves += 1
self.lb_score.set_text("Moves\n%d" % self.moves)
self.redraw()
if self.check_win():
self.win()
# ---------------------------------------------------------------------
def flood_fill(self, old, new):
stack = [(0, 0)]
while stack:
r, c = stack.pop()
if not (0 <= r < self.ROWS and 0 <= c < self.COLS):
continue
if self.board[r][c] != old:
continue
self.board[r][c] = new
stack.append((r + 1, c))
stack.append((r - 1, c))
stack.append((r, c + 1))
stack.append((r, c - 1))
# ---------------------------------------------------------------------
def check_win(self):
color = self.board[0][0]
for r in range(self.ROWS):
for c in range(self.COLS):
if self.board[r][c] != color:
return False
return True
# ---------------------------------------------------------------------
def win(self):
label = lv.label(self.screen)
label.set_text("Finished in %d moves!" % self.moves)
label.center()
# ---------------------------------------------------------------------
def redraw(self):
for r in range(self.ROWS):
for c in range(self.COLS):
v = self.board[r][c]
self.cells[r][c].set_style_bg_color(
lv.color_hex(self.COLORS[v]), 0
)
Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB