1+ # Win condition detection
2+ from typing import List , Set , Tuple
3+ from nicegui import ui
4+
5+ # Global state
6+ bingo_patterns = set ()
7+
8+ def check_winner (clicked_tiles : Set [Tuple [int , int ]]) -> List [str ]:
9+ """Check for winning patterns and return newly found ones."""
10+ global bingo_patterns
11+ new_patterns = []
12+
13+ # Check rows and columns
14+ for i in range (5 ):
15+ if all ((i , j ) in clicked_tiles for j in range (5 )):
16+ if f"row{ i } " not in bingo_patterns :
17+ new_patterns .append (f"row{ i } " )
18+ if all ((j , i ) in clicked_tiles for j in range (5 )):
19+ if f"col{ i } " not in bingo_patterns :
20+ new_patterns .append (f"col{ i } " )
21+
22+ # Check main diagonal
23+ if all ((i , i ) in clicked_tiles for i in range (5 )):
24+ if "diag_main" not in bingo_patterns :
25+ new_patterns .append ("diag_main" )
26+
27+ # Check anti-diagonal
28+ if all ((i , 4 - i ) in clicked_tiles for i in range (5 )):
29+ if "diag_anti" not in bingo_patterns :
30+ new_patterns .append ("diag_anti" )
31+
32+ # Special patterns
33+
34+ # Blackout: every cell is clicked
35+ if all ((r , c ) in clicked_tiles for r in range (5 ) for c in range (5 )):
36+ if "blackout" not in bingo_patterns :
37+ new_patterns .append ("blackout" )
38+
39+ # 4 Corners
40+ if all (pos in clicked_tiles for pos in [(0 ,0 ), (0 ,4 ), (4 ,0 ), (4 ,4 )]):
41+ if "four_corners" not in bingo_patterns :
42+ new_patterns .append ("four_corners" )
43+
44+ # Plus shape
45+ plus_cells = {(2 , c ) for c in range (5 )} | {(r , 2 ) for r in range (5 )}
46+ if all (cell in clicked_tiles for cell in plus_cells ):
47+ if "plus" not in bingo_patterns :
48+ new_patterns .append ("plus" )
49+
50+ # X shape
51+ 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 )):
52+ if "x_shape" not in bingo_patterns :
53+ new_patterns .append ("x_shape" )
54+
55+ # Perimeter
56+ 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 )}
57+ if all (cell in clicked_tiles for cell in perimeter_cells ):
58+ if "perimeter" not in bingo_patterns :
59+ new_patterns .append ("perimeter" )
60+
61+ return new_patterns
62+
63+ def process_win_notifications (new_patterns : List [str ]) -> None :
64+ """Process new win patterns and show appropriate notifications."""
65+ global bingo_patterns
66+
67+ if not new_patterns :
68+ return
69+
70+ # Separate new win patterns into standard and special ones
71+ special_set = {"blackout" , "four_corners" , "plus" , "x_shape" , "perimeter" }
72+ standard_new = [p for p in new_patterns if p not in special_set ]
73+ special_new = [p for p in new_patterns if p in special_set ]
74+
75+ # Process standard win conditions
76+ if standard_new :
77+ for pattern in standard_new :
78+ bingo_patterns .add (pattern )
79+ standard_total = sum (1 for p in bingo_patterns if p not in special_set )
80+
81+ if standard_total == 1 :
82+ message = "BINGO!"
83+ elif standard_total == 2 :
84+ message = "DOUBLE BINGO!"
85+ elif standard_total == 3 :
86+ message = "TRIPLE BINGO!"
87+ elif standard_total == 4 :
88+ message = "QUADRUPLE BINGO!"
89+ elif standard_total == 5 :
90+ message = "QUINTUPLE BINGO!"
91+ else :
92+ message = f"{ standard_total } -WAY BINGO!"
93+
94+ ui .notify (message , color = "green" , duration = 5 )
95+
96+ # Process special win conditions
97+ for sp in special_new :
98+ bingo_patterns .add (sp )
99+ sp_message = sp .replace ("_" , " " ).title () + " Bingo!"
100+ ui .notify (sp_message , color = "blue" , duration = 5 )
0 commit comments