Skip to content

Commit 2653abc

Browse files
feat: add ability to close the game
1 parent 49b8fdf commit 2653abc

File tree

2 files changed

+421
-4
lines changed

2 files changed

+421
-4
lines changed

main.py

Lines changed: 127 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
HEADER_TEXT = "COMMIT !BINGO"
1717
HEADER_TEXT_COLOR = "#0CB2B3" # Color for header text
18+
CLOSED_HEADER_TEXT = "Bingo Is Closed" # Text to display when game is closed
1819

1920
FREE_SPACE_TEXT = "FREE MEAT"
2021
FREE_SPACE_TEXT_COLOR = "#FF7f33"
@@ -56,6 +57,12 @@
5657
# Global set to track winning patterns (rows, columns, & diagonals)
5758
bingo_patterns = set()
5859

60+
# Global flag to track if the game is closed
61+
is_game_closed = False
62+
63+
# Global variable to store header label reference
64+
header_label = None
65+
5966
def generate_board(seed_val: int):
6067
"""
6168
Generate a new board using the provided seed value.
@@ -359,8 +366,40 @@ def check_winner():
359366
def sync_board_state():
360367
"""
361368
Update tile styles in every board view (e.g., home and stream).
369+
Also handles the game closed state to ensure consistency across views.
362370
"""
363371
try:
372+
global is_game_closed, header_label
373+
374+
# If game is closed, make sure all views reflect that
375+
if is_game_closed:
376+
# Update header if available
377+
if header_label:
378+
header_label.set_text(CLOSED_HEADER_TEXT)
379+
header_label.update()
380+
381+
# Hide all board views
382+
for view_key, (container, _) in board_views.items():
383+
container.style("display: none;")
384+
container.update()
385+
386+
# Make sure controls row is showing only the Start New Game button
387+
if 'controls_row' in globals():
388+
# Check if controls row has been already updated
389+
if controls_row.default_slot and len(controls_row.default_slot.children) != 1:
390+
controls_row.clear()
391+
with controls_row:
392+
with ui.button("", icon="autorenew", on_click=reopen_game).classes("rounded-full w-12 h-12") as new_game_btn:
393+
ui.tooltip("Start New Game")
394+
395+
return
396+
else:
397+
# Ensure header text is correct when game is open
398+
if header_label and header_label.text != HEADER_TEXT:
399+
header_label.set_text(HEADER_TEXT)
400+
header_label.update()
401+
402+
# Normal update if game is not closed
364403
# Update tile styles in every board view (e.g., home and stream)
365404
for view_key, (container, tile_buttons_local) in board_views.items():
366405
update_tile_styles(tile_buttons_local)
@@ -415,12 +454,14 @@ def create_board_view(background_color: str, is_global: bool):
415454
except Exception as e:
416455
logging.warning(f"Error setting up timer: {e}")
417456

418-
global seed_label
419-
with ui.row().classes("w-full mt-4 items-center justify-center gap-4"):
457+
global seed_label, controls_row
458+
with ui.row().classes("w-full mt-4 items-center justify-center gap-4") as controls_row:
420459
with ui.button("", icon="refresh", on_click=reset_board).classes("rounded-full w-12 h-12") as reset_btn:
421460
ui.tooltip("Reset Board")
422461
with ui.button("", icon="autorenew", on_click=generate_new_board).classes("rounded-full w-12 h-12") as new_board_btn:
423462
ui.tooltip("New Board")
463+
with ui.button("", icon="close", on_click=close_game).classes("rounded-full w-12 h-12 bg-red-500") as close_btn:
464+
ui.tooltip("Close Game")
424465
seed_label = ui.label(f"Seed: {today_seed}").classes("text-sm text-center").style(
425466
f"font-family: '{BOARD_TILE_FONT}', sans-serif; color: {TILE_UNCLICKED_BG_COLOR};"
426467
)
@@ -536,7 +577,8 @@ def setup_head(background_color: str):
536577

537578
# Use full width with padding so the header spans edge-to-edge
538579
with ui.element("div").classes("w-full"):
539-
ui.label(f"{HEADER_TEXT}").classes("fit-header text-center").style(f"font-family: {HEADER_FONT_FAMILY}; color: {HEADER_TEXT_COLOR};")
580+
global header_label
581+
header_label = ui.label(f"{HEADER_TEXT}").classes("fit-header text-center").style(f"font-family: {HEADER_FONT_FAMILY}; color: {HEADER_TEXT_COLOR};")
540582

541583
def get_google_font_css(font_name: str, weight: str, style: str, uniquifier: str) -> str:
542584
"""
@@ -739,6 +781,88 @@ def generate_new_board():
739781
seed_label.update()
740782
reset_board()
741783

784+
def close_game():
785+
"""
786+
Close the game - hide the board and update the header text.
787+
This function is called when the close button is clicked.
788+
"""
789+
global is_game_closed, header_label
790+
is_game_closed = True
791+
792+
# Update header text
793+
if header_label:
794+
header_label.set_text(CLOSED_HEADER_TEXT)
795+
header_label.update()
796+
797+
# Hide all board views (both home and stream)
798+
for view_key, (container, tile_buttons_local) in board_views.items():
799+
container.style("display: none;")
800+
container.update()
801+
802+
# Modify the controls row to only show the New Board button
803+
if 'controls_row' in globals():
804+
controls_row.clear()
805+
with controls_row:
806+
with ui.button("", icon="autorenew", on_click=reopen_game).classes("rounded-full w-12 h-12") as new_game_btn:
807+
ui.tooltip("Start New Game")
808+
809+
# Update stream page as well
810+
ui.broadcast() # Broadcast changes to all connected clients
811+
812+
# Notify that game has been closed
813+
ui.notify("Game has been closed", color="red", duration=3)
814+
815+
def reopen_game():
816+
"""
817+
Reopen the game after it has been closed.
818+
This regenerates a new board and resets the UI.
819+
"""
820+
global is_game_closed, header_label, board_iteration, controls_row
821+
822+
# Reset game state
823+
is_game_closed = False
824+
825+
# Update header text back to original
826+
if header_label:
827+
header_label.set_text(HEADER_TEXT)
828+
header_label.update()
829+
830+
# Generate a new board
831+
board_iteration += 1
832+
generate_board(board_iteration)
833+
834+
# Rebuild the controls row with all buttons
835+
if 'controls_row' in globals():
836+
controls_row.clear()
837+
global seed_label
838+
with controls_row:
839+
with ui.button("", icon="refresh", on_click=reset_board).classes("rounded-full w-12 h-12") as reset_btn:
840+
ui.tooltip("Reset Board")
841+
with ui.button("", icon="autorenew", on_click=generate_new_board).classes("rounded-full w-12 h-12") as new_board_btn:
842+
ui.tooltip("New Board")
843+
with ui.button("", icon="close", on_click=close_game).classes("rounded-full w-12 h-12 bg-red-500") as close_btn:
844+
ui.tooltip("Close Game")
845+
seed_label = ui.label(f"Seed: {today_seed}").classes("text-sm text-center").style(
846+
f"font-family: '{BOARD_TILE_FONT}', sans-serif; color: {TILE_UNCLICKED_BG_COLOR};"
847+
)
848+
849+
# Recreate and show all board views
850+
for view_key, (container, tile_buttons_local) in board_views.items():
851+
container.style("display: block;")
852+
container.clear()
853+
tile_buttons_local.clear()
854+
build_board(container, tile_buttons_local, toggle_tile)
855+
container.update()
856+
857+
# Reset clicked tiles except for FREE SPACE
858+
reset_board()
859+
860+
# Notify that a new game has started
861+
ui.notify("New game started", color="green", duration=3)
862+
863+
# Update stream page as well
864+
ui.broadcast()
865+
742866
# Mount the local 'static' directory so that files like "Super Carnival.woff" can be served
743867
app.mount("/static", StaticFiles(directory="static"), name="static")
744868

0 commit comments

Comments
 (0)