11import tkinter as tk
22import random
3- import os
43from pathlib import Path
54
65GRID_SIZE = 4
@@ -45,12 +44,13 @@ class Game2048:
4544 def __init__ (self , root ):
4645 self .root = root
4746 self .root .title ("2048 Game" )
47+ self .root .resizable (False , False )
4848
4949 self .score = 0
5050 self .high_score = self .load_high_score ()
5151
5252 self .main_frame = tk .Frame (root , bg = BACKGROUND_COLOR )
53- self .main_frame .grid ()
53+ self .main_frame .grid (padx = 10 , pady = 10 )
5454
5555 self .score_label = tk .Label (
5656 root ,
@@ -70,10 +70,10 @@ def __init__(self, root):
7070 self .cells = []
7171 self .board = [[0 ] * GRID_SIZE for _ in range (GRID_SIZE )]
7272
73+ self .game_over_label = None
74+
7375 self .create_grid ()
74- self .add_new_tile ()
75- self .add_new_tile ()
76- self .update_grid ()
76+ self .start_new_game ()
7777
7878 self .root .bind ("<Key>" , self .handle_keypress )
7979
@@ -89,7 +89,7 @@ def save_high_score(self):
8989 try :
9090 HIGH_SCORE_PATH .write_text (str (self .high_score ))
9191 except Exception as e :
92- print (f"⚠️ Warning: Could not save high score: { e } " )
92+ print (f"Warning: Could not save high score: { e } " )
9393
9494 def create_grid (self ):
9595 for row in range (GRID_SIZE ):
@@ -110,27 +110,31 @@ def create_grid(self):
110110 pady = CELL_PADDING
111111 )
112112
113+ frame .grid_propagate (False )
114+
113115 label = tk .Label (
114- self . main_frame ,
116+ frame ,
115117 text = "" ,
116118 bg = EMPTY_CELL_COLOR ,
117119 justify = tk .CENTER ,
118- font = ("Arial" , 24 , "bold" ),
119- width = 4 ,
120- height = 2
120+ font = ("Arial" , 24 , "bold" )
121121 )
122122
123- label .grid (
124- row = row ,
125- column = col ,
126- padx = CELL_PADDING ,
127- pady = CELL_PADDING
128- )
123+ label .place (relx = 0.5 , rely = 0.5 , anchor = "center" )
129124
130125 row_cells .append (label )
131126
132127 self .cells .append (row_cells )
133128
129+ def start_new_game (self ):
130+ self .board = [[0 ] * GRID_SIZE for _ in range (GRID_SIZE )]
131+ self .score = 0
132+
133+ self .add_new_tile ()
134+ self .add_new_tile ()
135+
136+ self .update_grid ()
137+
134138 def add_new_tile (self ):
135139 empty_cells = []
136140
@@ -168,9 +172,7 @@ def update_grid(self):
168172
169173 def compress (self , row ):
170174 new_row = [num for num in row if num != 0 ]
171-
172175 new_row += [0 ] * (GRID_SIZE - len (new_row ))
173-
174176 return new_row
175177
176178 def merge (self , row ):
@@ -184,7 +186,6 @@ def merge(self, row):
184186
185187 def move_left (self ):
186188 moved = False
187-
188189 new_board = []
189190
190191 for row in self .board :
@@ -198,7 +199,6 @@ def move_left(self):
198199 new_board .append (final )
199200
200201 self .board = new_board
201-
202202 return moved
203203
204204 def reverse (self ):
@@ -228,6 +228,7 @@ def move_down(self):
228228 def check_game_over (self ):
229229 for row in range (GRID_SIZE ):
230230 for col in range (GRID_SIZE ):
231+
231232 if self .board [row ][col ] == 0 :
232233 return False
233234
@@ -243,7 +244,6 @@ def check_game_over(self):
243244
244245 def handle_keypress (self , event ):
245246 key = event .keysym
246-
247247 moved = False
248248
249249 if key == "Left" :
@@ -258,6 +258,9 @@ def handle_keypress(self, event):
258258 elif key == "Down" :
259259 moved = self .move_down ()
260260
261+ else :
262+ return
263+
261264 if moved :
262265 self .add_new_tile ()
263266
@@ -267,27 +270,40 @@ def handle_keypress(self, event):
267270
268271 self .update_grid ()
269272
270- if self .check_game_over ():
271- self .game_over ()
273+ # FIXED BUG:
274+ # Game over is now checked even when no movement happens
275+ if self .check_game_over ():
276+ self .game_over ()
272277
273278 def game_over (self ):
279+
280+ # Prevent duplicate labels
281+ if self .game_over_label is not None :
282+ return
283+
284+ # Disable controls after game over
285+ self .root .unbind ("<Key>" )
286+
274287 self .game_over_label = tk .Label (
275288 self .root ,
276289 text = "GAME OVER" ,
277290 font = ("Arial" , 24 , "bold" ),
278291 fg = "red"
279292 )
293+
280294 self .game_over_label .grid (pady = 10 )
281295
282296 def restart_game (self ):
283- if hasattr (self , 'game_over_label' ):
297+
298+ # Remove old game over label
299+ if self .game_over_label is not None :
284300 self .game_over_label .destroy ()
285-
286- self . board = [[ 0 ] * GRID_SIZE for _ in range ( GRID_SIZE )]
287- self .score = 0
288- self . add_new_tile ()
289- self . add_new_tile ()
290- self .update_grid ( )
301+ self . game_over_label = None
302+
303+ self .start_new_game ()
304+
305+ # Re-enable keyboard controls
306+ self .root . bind ( "<Key>" , self . handle_keypress )
291307
292308
293309if __name__ == "__main__" :
0 commit comments