Skip to content

Commit 0fb3879

Browse files
Merge pull request #272 from choidf/main
2048 python gui clone
2 parents 3a1225b + 927c5e5 commit 0fb3879

File tree

4 files changed

+289
-0
lines changed

4 files changed

+289
-0
lines changed

Projects/2048/2048.py

Lines changed: 271 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,271 @@
1+
import pygame
2+
import random
3+
4+
pygame.init()
5+
6+
# initial set up
7+
WIDTH = 400
8+
HEIGHT = 500
9+
screen = pygame.display.set_mode([WIDTH, HEIGHT])
10+
pygame.display.set_caption("2048")
11+
timer = pygame.time.Clock()
12+
fps = 60
13+
font = pygame.font.Font("freesansbold.ttf", 24)
14+
15+
# 2048 game color library
16+
colors = {
17+
0: (204, 192, 179),
18+
2: (238, 228, 218),
19+
4: (237, 224, 200),
20+
8: (242, 177, 121),
21+
16: (245, 149, 99),
22+
32: (246, 124, 95),
23+
64: (246, 94, 59),
24+
128: (237, 207, 114),
25+
256: (237, 204, 97),
26+
512: (237, 200, 80),
27+
1024: (237, 197, 63),
28+
2048: (237, 194, 46),
29+
"light text": (249, 246, 242),
30+
"dark text": (119, 110, 101),
31+
"other": (0, 0, 0),
32+
"bg": (187, 173, 160),
33+
}
34+
35+
# game variables initialize
36+
board_values = [[0 for _ in range(4)] for _ in range(4)]
37+
game_over = False
38+
spawn_new = True
39+
init_count = 0
40+
direction = ""
41+
score = 0
42+
file = open("high_score.txt", "r")
43+
init_high = int(file.readline())
44+
file.close()
45+
high_score = init_high
46+
47+
48+
# draw game over and restart text
49+
def draw_over():
50+
pygame.draw.rect(screen, "black", [50, 50, 300, 100], 0, 10)
51+
game_over_text1 = font.render("Game Over!", True, "white")
52+
game_over_text2 = font.render("Press Enter to Restart!", True, "white")
53+
screen.blit(game_over_text1, (130, 65))
54+
screen.blit(game_over_text2, (70, 105))
55+
56+
57+
# draw background for the board
58+
def draw_board():
59+
pygame.draw.rect(screen, colors["bg"], [0, 0, 400, 400], 0, 10)
60+
score_text = font.render(f"Score: {score}", True, "black")
61+
high_score_text = font.render(f"High Score: {high_score}", True, "black")
62+
screen.blit(score_text, (10, 410))
63+
screen.blit(high_score_text, (10, 450))
64+
pass
65+
66+
67+
# draw tiles for game
68+
def draw_pieces(board):
69+
for i in range(4):
70+
for j in range(4):
71+
value = board[i][j]
72+
if value > 8:
73+
value_color = colors["light text"]
74+
else:
75+
value_color = colors["dark text"]
76+
if value <= 2048:
77+
color = colors[value]
78+
else:
79+
color = color["other"]
80+
pygame.draw.rect(
81+
screen, color, [j * 95 + 20, i * 95 + 20, 75, 75], 0, 5
82+
)
83+
if value > 0:
84+
value_len = len(str(value))
85+
font = pygame.font.Font(
86+
"freesansbold.ttf", 48 - (5 * value_len)
87+
)
88+
value_text = font.render(str(value), True, value_color)
89+
text_rect = value_text.get_rect(
90+
center=(j * 95 + 57, i * 95 + 57)
91+
)
92+
screen.blit(value_text, text_rect)
93+
pygame.draw.rect(
94+
screen, "black", [j * 95 + 20, i * 95 + 20, 75, 75], 2, 5
95+
)
96+
97+
98+
# function to check if there is any valid move
99+
# to decide if the game is over
100+
def is_game_over(board):
101+
for i in range(3):
102+
for j in range(3):
103+
if (board[i][j] == board[i + 1][j] or
104+
board[i][j] == board[i][j + 1]):
105+
return False
106+
107+
for j in range(3):
108+
if board[3][j] == board[3][j + 1]:
109+
return False
110+
111+
for i in range(3):
112+
if board[i][3] == board[i + 1][3]:
113+
return False
114+
# if there's no valid move left, the game is over
115+
return True
116+
117+
118+
# spawn in new pieces randomly when turns start
119+
def new_pieces(board):
120+
count = 0
121+
full = False
122+
while any(0 in row for row in board) and count < 1:
123+
row = random.randint(0, 3)
124+
col = random.randint(0, 3)
125+
if board[row][col] == 0:
126+
count += 1
127+
if random.randint(1, 10) == 10:
128+
board[row][col] = 4
129+
else:
130+
board[row][col] = 2
131+
if count < 1:
132+
full = is_game_over(board)
133+
return board, full
134+
135+
136+
# take your turn based on direction
137+
def take_turn(direc, board):
138+
global score
139+
merged = [[False for _ in range(4)] for _ in range(4)]
140+
if direc == "UP":
141+
for i in range(4):
142+
for j in range(4):
143+
shift = 0
144+
if i > 0:
145+
for q in range(i):
146+
if board[q][j] == 0:
147+
shift += 1
148+
if shift > 0:
149+
board[i - shift][j] = board[i][j]
150+
board[i][j] = 0
151+
if (
152+
board[i - shift - 1][j] == board[i - shift][j]
153+
and not merged[i - shift][j]
154+
and not merged[i - shift - 1][j]
155+
):
156+
board[i - shift - 1][j] *= 2
157+
score += board[i - shift - 1][j]
158+
board[i - shift][j] = 0
159+
merged[i - shift - 1][j] = True
160+
elif direc == "DOWN":
161+
for i in range(3):
162+
for j in range(4):
163+
shift = 0
164+
for q in range(i + 1):
165+
if board[3 - q][j] == 0:
166+
shift += 1
167+
if shift > 0:
168+
board[2 - i + shift][j] = board[2 - i][j]
169+
board[2 - i][j] = 0
170+
if 3 - i + shift <= 3:
171+
if (
172+
board[2 - i + shift][j] == board[3 - i + shift][j]
173+
and not merged[3 - i + shift][j]
174+
and not merged[2 - i + shift][j]
175+
):
176+
board[3 - i + shift][j] *= 2
177+
score += board[3 - i + shift][j]
178+
board[2 - i + shift][j] = 0
179+
merged[3 - i + shift][j] = True
180+
elif direc == "LEFT":
181+
for i in range(4):
182+
for j in range(4):
183+
shift = 0
184+
for q in range(j):
185+
if board[i][q] == 0:
186+
shift += 1
187+
if shift > 0:
188+
board[i][j - shift] = board[i][j]
189+
board[i][j] = 0
190+
if (
191+
board[i][j - shift] == board[i][j - shift - 1]
192+
and not merged[i][j - shift - 1]
193+
and not merged[i][j - shift]
194+
):
195+
board[i][j - shift - 1] *= 2
196+
score += board[i][j - shift - 1]
197+
board[i][j - shift] = 0
198+
merged[i][j - shift - 1] = True
199+
elif direc == "RIGHT":
200+
for i in range(4):
201+
for j in range(4):
202+
shift = 0
203+
for q in range(j):
204+
if board[i][3 - q] == 0:
205+
shift += 1
206+
if shift > 0:
207+
board[i][3 - j + shift] = board[i][3 - j]
208+
board[i][3 - j] = 0
209+
if 4 - j + shift <= 3:
210+
if (
211+
board[i][4 - j + shift] == board[i][3 - j + shift]
212+
and not merged[i][3 - j + shift]
213+
and not merged[i][4 - j + shift]
214+
):
215+
board[i][4 - j + shift] *= 2
216+
score += board[i][4 - j + shift]
217+
board[i][3 - j + shift] = 0
218+
merged[i][4 - j + shift] = True
219+
220+
return board
221+
222+
223+
# main game loop
224+
run = True
225+
while run:
226+
timer.tick(fps)
227+
screen.fill("gray")
228+
draw_board()
229+
draw_pieces(board_values)
230+
if spawn_new or init_count < 2:
231+
board_values, game_over = new_pieces(board_values)
232+
spawn_new = False
233+
init_count += 1
234+
if direction != "":
235+
board_values = take_turn(direction, board_values)
236+
direction = ""
237+
spawn_new = True
238+
if game_over:
239+
draw_over()
240+
if high_score > init_high:
241+
file = open("high_score.txt", "w")
242+
file.write(f"{high_score}")
243+
file.close()
244+
init_high = high_score
245+
246+
for event in pygame.event.get():
247+
if event.type == pygame.QUIT:
248+
run = False
249+
if event.type == pygame.KEYUP:
250+
if event.key == pygame.K_UP:
251+
direction = "UP"
252+
elif event.key == pygame.K_DOWN:
253+
direction = "DOWN"
254+
elif event.key == pygame.K_LEFT:
255+
direction = "LEFT"
256+
elif event.key == pygame.K_RIGHT:
257+
direction = "RIGHT"
258+
259+
if game_over:
260+
if event.key == pygame.K_RETURN:
261+
board_values = [[0 for _ in range(4)] for _ in range(4)]
262+
spawn_new = True
263+
init_count = 0
264+
score = 0
265+
direction = ""
266+
game_over = False
267+
268+
if score > high_score:
269+
high_score = score
270+
pygame.display.flip()
271+
pygame.quit()

Projects/2048/README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# 2048
2+
3+
The script is a recreation attempt of 2048 game using pygame library for GUI
4+
5+
## Installation
6+
7+
Use the package manager [pip](https://pip.pypa.io/en/stable/) to install pygame library or requirements.txt.
8+
9+
```bash
10+
pip install -r requirements.txt
11+
```
12+
13+
or
14+
15+
```bash
16+
pip install pygame
17+
```

Projects/2048/high_score.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
0

Projects/2048/requirements.txt

28 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)