|
15 | 15 |
|
16 | 16 | HEADER_TEXT = "COMMIT !BINGO" |
17 | 17 | HEADER_TEXT_COLOR = "#0CB2B3" # Color for header text |
| 18 | +CLOSED_HEADER_TEXT = "Bingo Is Closed" # Text to display when game is closed |
18 | 19 |
|
19 | 20 | FREE_SPACE_TEXT = "FREE MEAT" |
20 | 21 | FREE_SPACE_TEXT_COLOR = "#FF7f33" |
|
56 | 57 | # Global set to track winning patterns (rows, columns, & diagonals) |
57 | 58 | bingo_patterns = set() |
58 | 59 |
|
| 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 | + |
59 | 66 | def generate_board(seed_val: int): |
60 | 67 | """ |
61 | 68 | Generate a new board using the provided seed value. |
@@ -359,8 +366,40 @@ def check_winner(): |
359 | 366 | def sync_board_state(): |
360 | 367 | """ |
361 | 368 | Update tile styles in every board view (e.g., home and stream). |
| 369 | + Also handles the game closed state to ensure consistency across views. |
362 | 370 | """ |
363 | 371 | 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 |
364 | 403 | # Update tile styles in every board view (e.g., home and stream) |
365 | 404 | for view_key, (container, tile_buttons_local) in board_views.items(): |
366 | 405 | update_tile_styles(tile_buttons_local) |
@@ -415,12 +454,14 @@ def create_board_view(background_color: str, is_global: bool): |
415 | 454 | except Exception as e: |
416 | 455 | logging.warning(f"Error setting up timer: {e}") |
417 | 456 |
|
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: |
420 | 459 | with ui.button("", icon="refresh", on_click=reset_board).classes("rounded-full w-12 h-12") as reset_btn: |
421 | 460 | ui.tooltip("Reset Board") |
422 | 461 | with ui.button("", icon="autorenew", on_click=generate_new_board).classes("rounded-full w-12 h-12") as new_board_btn: |
423 | 462 | 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") |
424 | 465 | seed_label = ui.label(f"Seed: {today_seed}").classes("text-sm text-center").style( |
425 | 466 | f"font-family: '{BOARD_TILE_FONT}', sans-serif; color: {TILE_UNCLICKED_BG_COLOR};" |
426 | 467 | ) |
@@ -536,7 +577,8 @@ def setup_head(background_color: str): |
536 | 577 |
|
537 | 578 | # Use full width with padding so the header spans edge-to-edge |
538 | 579 | 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};") |
540 | 582 |
|
541 | 583 | def get_google_font_css(font_name: str, weight: str, style: str, uniquifier: str) -> str: |
542 | 584 | """ |
@@ -739,6 +781,88 @@ def generate_new_board(): |
739 | 781 | seed_label.update() |
740 | 782 | reset_board() |
741 | 783 |
|
| 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 | + |
742 | 866 | # Mount the local 'static' directory so that files like "Super Carnival.woff" can be served |
743 | 867 | app.mount("/static", StaticFiles(directory="static"), name="static") |
744 | 868 |
|
|
0 commit comments