66# Set up logging
77logging .basicConfig (level = logging .DEBUG , format = '%(asctime)s - %(levelname)s - %(message)s' )
88
9- # List of 24 phrases (excluding the center "FREE MEAT")
10- phrases = [
11- "CAN'T HAVE NICE THINGS" , "TECHNO BABBLE" , "HELL YEAH!" , "WE GET A RAID" , "NOICE" ,
12- "POSITION ONE" , "HOWS MY AUDIO" , "SOMEONE REDEEMS HYDRATE" , "THREATEN GOOD TIME" , "MENTIONS MODS" ,
13- "SAYS TEXAS" , "SPINS BONUS WHEEL" , "JOIN DISCORD" , "HOLY SMOKES" ,
14- "SAYS CATS OR DOGS" , "DOOT DOOTS" , "MAKES AIR QUOTES" , "TALKS ABOUT ELLEE" , "ZOOM" ,
15- "SIGHT LINES" , "TALKS ABOUT PALIA" , "SAYS DISCORD" , "DANCE PARTY" , "THATS NUTS!"
16- ]
9+ # Read phrases from a text file and convert them to uppercase.
10+ with open ("phrases.txt" , "r" ) as f :
11+ phrases = [line .strip ().upper () for line in f if line .strip ()]
1712
1813# Use today's date as the seed for deterministic shuffling
1914today_seed = datetime .date .today ().strftime ("%Y%m%d" )
2823clicked_tiles = set ()
2924tile_buttons = {} # {(row, col): chip}
3025
26+ def split_phrase_into_lines (phrase : str ) -> list :
27+ """
28+ Splits the phrase into balanced lines.
29+ If the phrase has two or fewer words, return it as a single line.
30+ Otherwise, split into two lines at the midpoint.
31+ """
32+ words = phrase .split ()
33+ if len (words ) == 1 :
34+ return [words [0 ]]
35+ elif len (words ) == 2 :
36+ return [words [0 ], words [1 ]]
37+ else :
38+ mid = round (len (words ) / 2 )
39+ return [" " .join (words [:mid ]), " " .join (words [mid :])]
40+
3141# Function to create the Bingo board UI
3242def create_bingo_board ():
43+ # The header and seed label are handled outside this function.
3344 logging .info ("Creating Bingo board" )
34- ui .label ("Commit Bingo!" ).classes ("text-3xl font-bold mt-4 text-yellow-400" )
35- ui .label (f"Seed: { today_seed } " ).classes ("text-md text-gray-300" )
3645
3746 with ui .element ("div" ).classes ("flex justify-center items-center w-full" ):
3847 with ui .grid (columns = 5 ).classes ("gap-2 mt-4" ):
@@ -42,22 +51,31 @@ def create_bingo_board():
4251 card = ui .card ().classes ("p-2 bg-yellow-500 hover:bg-yellow-400 rounded-lg w-full flex items-center justify-center" ).style ("cursor: pointer; aspect-ratio: 1;" )
4352 with card :
4453 with ui .column ().classes ("flex flex-col items-center justify-center gap-0 w-full" ):
45- # Split the phrase into words and make each word a separate label.
46- for word in phrase .split ():
47- tile = ui .label (word ).classes ("text-lg text-center" )
48- tile .style ("font-family: 'Super Carnival', sans-serif; padding: 0; margin: 0;" )
54+ # Set text color: free meat gets #FF7f33, others black
55+ default_text_color = "#FF7f33" if phrase .upper () == "FREE MEAT" else "black"
56+ # Split the phrase into balanced lines.
57+ for line in split_phrase_into_lines (phrase ):
58+ tile = ui .label (line ).classes ("fit-text text-center" )
59+ tile .style (f"font-family: 'Super Carnival', sans-serif; padding: 0; margin: 0; color: { default_text_color } ;" )
4960 # Save the card reference.
5061 tile_buttons [(row_idx , col_idx )] = card
51- # When the card is clicked, toggle its state.
52- card .on ("click" , lambda e , r = row_idx , c = col_idx : toggle_tile (r , c ))
62+ if phrase .upper () == "FREE MEAT" :
63+ clicked_tiles .add ((row_idx , col_idx ))
64+ # Set the free meat cell's style: text color, background, etc.
65+ card .style ("color: #FF7f33; background: #facc15; border: none;" )
66+ else :
67+ card .on ("click" , lambda e , r = row_idx , c = col_idx : toggle_tile (r , c ))
5368
5469# Toggle tile click state (for example usage)
5570def toggle_tile (row , col ):
71+ # Do not allow toggling for the FREE MEAT cell (center cell)
72+ if (row , col ) == (2 , 2 ):
73+ return
5674 key = (row , col )
5775 if key in clicked_tiles :
5876 logging .debug (f"Tile at { key } unclicked" )
5977 clicked_tiles .remove (key )
60- tile_buttons [key ].style ("background: #facc15; border: none;" )
78+ tile_buttons [key ].style ("background: #facc15; border: none; color: black; " )
6179 else :
6280 logging .debug (f"Tile at { key } clicked" )
6381 clicked_tiles .add (key )
@@ -77,5 +95,15 @@ def check_winner():
7795# Set up NiceGUI page and head elements
7896ui .page ("/" )
7997ui .add_head_html ('<link href="https://fonts.cdnfonts.com/css/super-carnival" rel="stylesheet">' )
98+ ui .add_head_html ('<script src="https://cdn.jsdelivr.net/npm/fitty@2.3.6/dist/fitty.min.js"></script>' )
99+
100+ with ui .element ("div" ).classes ("w-full max-w-3xl mx-auto" ):
101+ ui .label ("COMMIT BINGO!" ).classes ("fit-header text-center" ).style ("font-family: 'Super Carnival', sans-serif;" )
102+
80103create_bingo_board ()
104+
105+ with ui .element ("div" ).classes ("w-full mt-4" ):
106+ ui .label (f"Seed: { today_seed } " ).classes ("text-md text-gray-300 text-center" )
107+
108+ ui .timer (0.5 , lambda : ui .run_javascript ("fitty('.fit-text', { multiLine: true, maxSize: 100 }); fitty('.fit-header', { multiLine: true, maxSize: 200 });" ), once = True )
81109ui .run (port = 8080 , title = "Commit Bingo" , dark = True )
0 commit comments