Skip to content

Commit 5e6e919

Browse files
chore: formatting
Signed-off-by: Jonathan Irvin <djfoxyslpr@gmail.com>
1 parent 6eaa5da commit 5e6e919

File tree

13 files changed

+330
-215
lines changed

13 files changed

+330
-215
lines changed

app.py

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,42 +8,43 @@
88
from fastapi.staticfiles import StaticFiles
99
from nicegui import app, ui
1010

11-
from src.config.constants import (
12-
FREE_SPACE_TEXT,
13-
HEADER_TEXT
14-
)
11+
from src.config.constants import FREE_SPACE_TEXT, HEADER_TEXT
1512
from src.core.game_logic import (
13+
bingo_patterns,
1614
board,
1715
board_iteration,
18-
bingo_patterns,
1916
clicked_tiles,
2017
generate_board,
2118
is_game_closed,
22-
today_seed
19+
today_seed,
2320
)
2421
from src.ui.routes import init_routes
2522
from src.utils.file_operations import read_phrases_file
2623

2724
# Set up logging
28-
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')
25+
logging.basicConfig(
26+
level=logging.DEBUG, format="%(asctime)s - %(levelname)s - %(message)s"
27+
)
28+
2929

3030
# Initialize the application
3131
def init_app():
3232
"""Initialize the Bingo application."""
33-
33+
3434
# Initialize game state
3535
phrases = read_phrases_file()
3636
generate_board(board_iteration, phrases)
37-
37+
3838
# Initialize routes
3939
init_routes()
40-
40+
4141
# Mount the static directory
4242
app.mount("/static", StaticFiles(directory="static"), name="static")
43-
43+
4444
return app
4545

46+
4647
if __name__ in {"__main__", "__mp_main__"}:
4748
# Run the NiceGUI app
4849
init_app()
49-
ui.run(port=8080, title=f"{HEADER_TEXT}", dark=False)
50+
ui.run(port=8080, title=f"{HEADER_TEXT}", dark=False)

main.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@
22
# New development should use the modular structure in src/ with app.py as the entry point
33

44
import warnings
5+
56
warnings.warn(
67
"main.py is deprecated. Use the modular structure in src/ with app.py as the entry point",
78
DeprecationWarning,
8-
stacklevel=2
9+
stacklevel=2,
910
)
1011

1112
import asyncio

src/config/constants.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,12 @@
3030
# UI Class Constants
3131
BOARD_CONTAINER_CLASS = "flex justify-center items-center w-full"
3232
HEADER_CONTAINER_CLASS = "w-full"
33-
CARD_CLASSES = "relative p-2 rounded-xl shadow-8 w-full h-full flex items-center justify-center"
33+
CARD_CLASSES = (
34+
"relative p-2 rounded-xl shadow-8 w-full h-full flex items-center justify-center"
35+
)
3436
COLUMN_CLASSES = "flex flex-col items-center justify-center gap-0 w-full"
3537
GRID_CONTAINER_CLASS = "w-full aspect-square p-4"
3638
GRID_CLASSES = "gap-2 h-full grid-rows-5"
3739
ROW_CLASSES = "w-full"
3840
LABEL_SMALL_CLASSES = "fit-text-small text-center select-none"
39-
LABEL_CLASSES = "fit-text text-center select-none"
41+
LABEL_CLASSES = "fit-text text-center select-none"

src/core/game_logic.py

Lines changed: 55 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
TILE_UNCLICKED_BG_COLOR,
1919
TILE_UNCLICKED_TEXT_COLOR,
2020
)
21-
from src.utils.text_processing import split_phrase_into_lines, get_line_style_for_lines
21+
from src.utils.text_processing import get_line_style_for_lines, split_phrase_into_lines
2222

2323
# Global variables for game state
2424
board = [] # 2D array of phrases
@@ -41,23 +41,23 @@ def generate_board(seed_val: int, phrases):
4141
Also resets the clicked_tiles (ensuring the FREE SPACE is clicked) and sets the global today_seed.
4242
"""
4343
global board, today_seed, clicked_tiles
44-
44+
4545
todays_seed = datetime.date.today().strftime("%Y%m%d")
4646
random.seed(seed_val)
47-
47+
4848
shuffled_phrases = random.sample(phrases, 24)
4949
shuffled_phrases.insert(12, FREE_SPACE_TEXT)
50-
51-
board = [shuffled_phrases[i:i+5] for i in range(0, 25, 5)]
52-
50+
51+
board = [shuffled_phrases[i : i + 5] for i in range(0, 25, 5)]
52+
5353
clicked_tiles.clear()
5454
for r, row in enumerate(board):
5555
for c, phrase in enumerate(row):
5656
if phrase.upper() == FREE_SPACE_TEXT:
5757
clicked_tiles.add((r, c))
58-
58+
5959
today_seed = f"{todays_seed}.{seed_val}"
60-
60+
6161
return board
6262

6363

@@ -67,19 +67,19 @@ def toggle_tile(row, col):
6767
Updates the UI and checks for winner.
6868
"""
6969
global clicked_tiles
70-
70+
7171
# Don't allow toggling the free space
7272
if (row, col) == (2, 2):
7373
return
74-
74+
7575
key = (row, col)
7676
if key in clicked_tiles:
7777
clicked_tiles.remove(key)
7878
else:
7979
clicked_tiles.add(key)
80-
80+
8181
check_winner()
82-
82+
8383
for view_key, (container, tile_buttons_local) in board_views.items():
8484
for (r, c), tile in tile_buttons_local.items():
8585
phrase = board[r][c]
@@ -89,22 +89,22 @@ def toggle_tile(row, col):
8989
else:
9090
new_card_style = f"background-color: {TILE_UNCLICKED_BG_COLOR}; color: {TILE_UNCLICKED_TEXT_COLOR}; border: none;"
9191
new_label_color = TILE_UNCLICKED_TEXT_COLOR
92-
92+
9393
tile["card"].style(new_card_style)
9494
lines = split_phrase_into_lines(phrase)
9595
line_count = len(lines)
9696
new_label_style = get_line_style_for_lines(line_count, new_label_color)
97-
97+
9898
for label_info in tile["labels"]:
9999
lbl = label_info["ref"]
100100
lbl.classes(label_info["base_classes"])
101101
lbl.style(new_label_style)
102102
lbl.update()
103-
103+
104104
tile["card"].update()
105-
105+
106106
container.update()
107-
107+
108108
try:
109109
js_code = """
110110
setTimeout(function() {
@@ -125,7 +125,7 @@ def check_winner():
125125
"""
126126
global bingo_patterns
127127
new_patterns = []
128-
128+
129129
# Check rows and columns.
130130
for i in range(5):
131131
if all((i, j) in clicked_tiles for j in range(5)):
@@ -141,7 +141,7 @@ def check_winner():
141141
new_patterns.append("diag_main")
142142

143143
# Check anti-diagonal.
144-
if all((i, 4-i) in clicked_tiles for i in range(5)):
144+
if all((i, 4 - i) in clicked_tiles for i in range(5)):
145145
if "diag_anti" not in bingo_patterns:
146146
new_patterns.append("diag_anti")
147147

@@ -153,7 +153,7 @@ def check_winner():
153153
new_patterns.append("blackout")
154154

155155
# 4 Corners: top-left, top-right, bottom-left, bottom-right.
156-
if all(pos in clicked_tiles for pos in [(0,0), (0,4), (4,0), (4,4)]):
156+
if all(pos in clicked_tiles for pos in [(0, 0), (0, 4), (4, 0), (4, 4)]):
157157
if "four_corners" not in bingo_patterns:
158158
new_patterns.append("four_corners")
159159

@@ -164,12 +164,19 @@ def check_winner():
164164
new_patterns.append("plus")
165165

166166
# X shape: both diagonals complete.
167-
if all((i, i) in clicked_tiles for i in range(5)) and all((i, 4-i) in clicked_tiles for i in range(5)):
167+
if all((i, i) in clicked_tiles for i in range(5)) and all(
168+
(i, 4 - i) in clicked_tiles for i in range(5)
169+
):
168170
if "x_shape" not in bingo_patterns:
169171
new_patterns.append("x_shape")
170172

171173
# Outside edges (perimeter): all border cells clicked.
172-
perimeter_cells = {(0, c) for c in range(5)} | {(4, c) for c in range(5)} | {(r, 0) for r in range(5)} | {(r, 4) for r in range(5)}
174+
perimeter_cells = (
175+
{(0, c) for c in range(5)}
176+
| {(4, c) for c in range(5)}
177+
| {(r, 0) for r in range(5)}
178+
| {(r, 4) for r in range(5)}
179+
)
173180
if all(cell in clicked_tiles for cell in perimeter_cells):
174181
if "perimeter" not in bingo_patterns:
175182
new_patterns.append("perimeter")
@@ -228,21 +235,21 @@ def generate_new_board(phrases):
228235
global board_iteration
229236
board_iteration += 1
230237
generate_board(board_iteration, phrases)
231-
238+
232239
# Update all board views (both home and stream)
233240
from src.ui.board_builder import build_board
234-
241+
235242
for view_key, (container, tile_buttons_local) in board_views.items():
236243
container.clear()
237244
tile_buttons_local.clear()
238245
build_board(container, tile_buttons_local, toggle_tile, board, clicked_tiles)
239246
container.update()
240-
247+
241248
# Update the seed label if available
242-
if 'seed_label' in globals() and seed_label:
249+
if "seed_label" in globals() and seed_label:
243250
seed_label.set_text(f"Seed: {today_seed}")
244251
seed_label.update()
245-
252+
246253
reset_board()
247254

248255

@@ -253,24 +260,26 @@ def close_game():
253260
"""
254261
global is_game_closed, header_label
255262
is_game_closed = True
256-
263+
257264
# Update header text on the current view
258265
if header_label:
259266
header_label.set_text(CLOSED_HEADER_TEXT)
260267
header_label.update()
261-
268+
262269
# Hide all board views (both home and stream)
263270
for view_key, (container, tile_buttons_local) in board_views.items():
264271
container.style("display: none;")
265272
container.update()
266-
273+
267274
# Modify the controls row to only show the New Board button
268275
if controls_row:
269276
controls_row.clear()
270277
with controls_row:
271-
with ui.button("", icon="autorenew", on_click=reopen_game).classes("rounded-full w-12 h-12") as new_game_btn:
278+
with ui.button("", icon="autorenew", on_click=reopen_game).classes(
279+
"rounded-full w-12 h-12"
280+
) as new_game_btn:
272281
ui.tooltip("Start New Game")
273-
282+
274283
# Update stream page as well - this will trigger sync_board_state on connected clients
275284
# Note: ui.broadcast() was used in older versions of NiceGUI, but may not be available
276285
try:
@@ -279,7 +288,7 @@ def close_game():
279288
# In newer versions of NiceGUI, broadcast might not be available
280289
# We rely on the timer-based sync instead
281290
logging.info("ui.broadcast not available, relying on timer-based sync")
282-
291+
283292
# Notify that game has been closed
284293
ui.notify("Game has been closed", color="red", duration=3)
285294

@@ -290,48 +299,50 @@ def reopen_game():
290299
This regenerates a new board and resets the UI.
291300
"""
292301
global is_game_closed, header_label, board_iteration
293-
302+
294303
# Reset game state
295304
is_game_closed = False
296-
305+
297306
# Update header text back to original for the current view
298307
if header_label:
299308
header_label.set_text(HEADER_TEXT)
300309
header_label.update()
301-
310+
302311
# Generate a new board
303312
from src.utils.file_operations import read_phrases_file
313+
304314
phrases = read_phrases_file()
305-
315+
306316
board_iteration += 1
307317
generate_board(board_iteration, phrases)
308-
318+
309319
# Rebuild the controls row with all buttons
310320
from src.ui.controls import rebuild_controls_row
321+
311322
if controls_row:
312323
rebuild_controls_row(controls_row)
313-
324+
314325
# Recreate and show all board views
315326
from src.ui.board_builder import build_board
316-
327+
317328
for view_key, (container, tile_buttons_local) in board_views.items():
318329
container.style("display: block;")
319330
container.clear()
320331
tile_buttons_local.clear()
321332
build_board(container, tile_buttons_local, toggle_tile, board, clicked_tiles)
322333
container.update()
323-
334+
324335
# Reset clicked tiles except for FREE SPACE
325336
reset_board()
326-
337+
327338
# Notify that a new game has started
328339
ui.notify("New game started", color="green", duration=3)
329-
340+
330341
# Update stream page and all other connected clients
331342
# This will trigger sync_board_state on all clients including the stream view
332343
try:
333344
ui.broadcast() # Broadcast changes to all connected clients
334345
except AttributeError:
335346
# In newer versions of NiceGUI, broadcast might not be available
336347
# We rely on the timer-based sync instead
337-
logging.info("ui.broadcast not available, relying on timer-based sync")
348+
logging.info("ui.broadcast not available, relying on timer-based sync")

0 commit comments

Comments
 (0)