From 03f082c7201797ce4c4ccb19c72daaee369f39ac Mon Sep 17 00:00:00 2001 From: choidf <39011839+choidf@users.noreply.github.com> Date: Sun, 5 Nov 2023 17:08:58 +0700 Subject: [PATCH 1/3] initial 2048 commit --- Projects/2048/2048.py | 263 +++++++++++++++++++++++++++++++++ Projects/2048/README.md | 17 +++ Projects/2048/high_score.txt | 1 + Projects/2048/requirements.txt | Bin 0 -> 28 bytes 4 files changed, 281 insertions(+) create mode 100644 Projects/2048/2048.py create mode 100644 Projects/2048/README.md create mode 100644 Projects/2048/high_score.txt create mode 100644 Projects/2048/requirements.txt diff --git a/Projects/2048/2048.py b/Projects/2048/2048.py new file mode 100644 index 0000000..81f208e --- /dev/null +++ b/Projects/2048/2048.py @@ -0,0 +1,263 @@ +import pygame +import random + +pygame.init() + +# initial set up +WIDTH = 400 +HEIGHT = 500 +screen = pygame.display.set_mode([WIDTH, HEIGHT]) +pygame.display.set_caption("2048") +timer = pygame.time.Clock() +fps = 60 +font = pygame.font.Font("freesansbold.ttf", 24) + +# 2048 game color library +colors = { + 0: (204, 192, 179), + 2: (238, 228, 218), + 4: (237, 224, 200), + 8: (242, 177, 121), + 16: (245, 149, 99), + 32: (246, 124, 95), + 64: (246, 94, 59), + 128: (237, 207, 114), + 256: (237, 204, 97), + 512: (237, 200, 80), + 1024: (237, 197, 63), + 2048: (237, 194, 46), + "light text": (249, 246, 242), + "dark text": (119, 110, 101), + "other": (0, 0, 0), + "bg": (187, 173, 160), +} + +# game variables initialize +board_values = [[0 for _ in range(4)] for _ in range(4)] +game_over = False +spawn_new = True +init_count = 0 +direction = "" +score = 0 +file = open("2048\high_score.txt", "r") +init_high = int(file.readline()) +file.close() +high_score = init_high + +# draw game over and restart text +def draw_over(): + pygame.draw.rect(screen, "black", [50, 50, 300, 100], 0, 10) + game_over_text1 = font.render("Game Over!", True, "white") + game_over_text2 = font.render("Press Enter to Restart!", True, "white") + screen.blit(game_over_text1, (130, 65)) + screen.blit(game_over_text2, (70, 105)) + + +# draw background for the board +def draw_board(): + pygame.draw.rect(screen, colors["bg"], [0, 0, 400, 400], 0, 10) + score_text = font.render(f"Score: {score}", True, "black") + high_score_text = font.render(f"High Score: {high_score}", True, "black") + screen.blit(score_text, (10, 410)) + screen.blit(high_score_text, (10, 450)) + pass + + +# draw tiles for game +def draw_pieces(board): + for i in range(4): + for j in range(4): + value = board[i][j] + if value > 8: + value_color = colors["light text"] + else: + value_color = colors["dark text"] + if value <= 2048: + color = colors[value] + else: + color = color["other"] + pygame.draw.rect(screen, color, [j * 95 + 20, i * 95 + 20, 75, 75], 0, 5) + if value > 0: + value_len = len(str(value)) + font = pygame.font.Font("freesansbold.ttf", 48 - (5 * value_len)) + value_text = font.render(str(value), True, value_color) + text_rect = value_text.get_rect(center=(j * 95 + 57, i * 95 + 57)) + screen.blit(value_text, text_rect) + pygame.draw.rect( + screen, "black", [j * 95 + 20, i * 95 + 20, 75, 75], 2, 5 + ) + + +# function to check if there is any valid move +# to decide if the game is over +def is_game_over(board): + for i in range(3): + for j in range(3): + if board[i][j] == board[i + 1][j] or board[i][j] == board[i][j + 1]: + return False + + for j in range(3): + if board[3][j] == board[3][j + 1]: + return False + + for i in range(3): + if board[i][3] == board[i + 1][3]: + return False + ## if there's no valid move left, the game is over + return True + + +# spawn in new pieces randomly when turns start +def new_pieces(board): + count = 0 + full = False + while any(0 in row for row in board) and count < 1: + row = random.randint(0, 3) + col = random.randint(0, 3) + if board[row][col] == 0: + count += 1 + if random.randint(1, 10) == 10: + board[row][col] = 4 + else: + board[row][col] = 2 + if count < 1: + full = is_game_over(board) + return board, full + + +# take your turn based on direction +def take_turn(direc, board): + global score + merged = [[False for _ in range(4)] for _ in range(4)] + if direc == "UP": + for i in range(4): + for j in range(4): + shift = 0 + if i > 0: + for q in range(i): + if board[q][j] == 0: + shift += 1 + if shift > 0: + board[i - shift][j] = board[i][j] + board[i][j] = 0 + if ( + board[i - shift - 1][j] == board[i - shift][j] + and not merged[i - shift][j] + and not merged[i - shift - 1][j] + ): + board[i - shift - 1][j] *= 2 + score += board[i - shift - 1][j] + board[i - shift][j] = 0 + merged[i - shift - 1][j] = True + elif direc == "DOWN": + for i in range(3): + for j in range(4): + shift = 0 + for q in range(i + 1): + if board[3 - q][j] == 0: + shift += 1 + if shift > 0: + board[2 - i + shift][j] = board[2 - i][j] + board[2 - i][j] = 0 + if 3 - i + shift <= 3: + if ( + board[2 - i + shift][j] == board[3 - i + shift][j] + and not merged[3 - i + shift][j] + and not merged[2 - i + shift][j] + ): + board[3 - i + shift][j] *= 2 + score += board[3 - i + shift][j] + board[2 - i + shift][j] = 0 + merged[3 - i + shift][j] = True + elif direc == "LEFT": + for i in range(4): + for j in range(4): + shift = 0 + for q in range(j): + if board[i][q] == 0: + shift += 1 + if shift > 0: + board[i][j - shift] = board[i][j] + board[i][j] = 0 + if ( + board[i][j - shift] == board[i][j - shift - 1] + and not merged[i][j - shift - 1] + and not merged[i][j - shift] + ): + board[i][j - shift - 1] *= 2 + score += board[i][j - shift - 1] + board[i][j - shift] = 0 + merged[i][j - shift - 1] = True + elif direc == "RIGHT": + for i in range(4): + for j in range(4): + shift = 0 + for q in range(j): + if board[i][3 - q] == 0: + shift += 1 + if shift > 0: + board[i][3 - j + shift] = board[i][3 - j] + board[i][3 - j] = 0 + if 4 - j + shift <= 3: + if ( + board[i][4 - j + shift] == board[i][3 - j + shift] + and not merged[i][3 - j + shift] + and not merged[i][4 - j + shift] + ): + board[i][4 - j + shift] *= 2 + score += board[i][4 - j + shift] + board[i][3 - j + shift] = 0 + merged[i][4 - j + shift] = True + + return board + + +# main game loop +run = True +while run: + timer.tick(fps) + screen.fill("gray") + draw_board() + draw_pieces(board_values) + if spawn_new or init_count < 2: + board_values, game_over = new_pieces(board_values) + spawn_new = False + init_count += 1 + if direction != "": + board_values = take_turn(direction, board_values) + direction = "" + spawn_new = True + if game_over: + draw_over() + if high_score > init_high: + file = open("2048\high_score.txt", "w") + file.write(f"{high_score}") + file.close() + init_high = high_score + + for event in pygame.event.get(): + if event.type == pygame.QUIT: + run = False + if event.type == pygame.KEYUP: + if event.key == pygame.K_UP: + direction = "UP" + elif event.key == pygame.K_DOWN: + direction = "DOWN" + elif event.key == pygame.K_LEFT: + direction = "LEFT" + elif event.key == pygame.K_RIGHT: + direction = "RIGHT" + + if game_over: + if event.key == pygame.K_RETURN: + board_values = [[0 for _ in range(4)] for _ in range(4)] + spawn_new = True + init_count = 0 + score = 0 + direction = "" + game_over = False + + if score > high_score: + high_score = score + pygame.display.flip() +pygame.quit() diff --git a/Projects/2048/README.md b/Projects/2048/README.md new file mode 100644 index 0000000..6926a68 --- /dev/null +++ b/Projects/2048/README.md @@ -0,0 +1,17 @@ +# 2048 + +The script is a recreation attempt of 2048 game using pygame library for GUI + +## Installation + +Use the package manager [pip](https://pip.pypa.io/en/stable/) to install pygame library or requirements.txt. + +```bash +pip install -r requirements.txt +``` + +or + +```bash +pip install pygame +``` diff --git a/Projects/2048/high_score.txt b/Projects/2048/high_score.txt new file mode 100644 index 0000000..c227083 --- /dev/null +++ b/Projects/2048/high_score.txt @@ -0,0 +1 @@ +0 \ No newline at end of file diff --git a/Projects/2048/requirements.txt b/Projects/2048/requirements.txt new file mode 100644 index 0000000000000000000000000000000000000000..f955b7df5f33ccf8faa4161797f9665ae9fe1b49 GIT binary patch literal 28 gcmezWuYjSFA)O(SA(tVQ!4?RO81xuSf!K%v0C(C2@Bjb+ literal 0 HcmV?d00001 From 670ed389c2eb7a923c46e66449d722df65f444d5 Mon Sep 17 00:00:00 2001 From: choidf <39011839+choidf@users.noreply.github.com> Date: Sun, 5 Nov 2023 17:11:36 +0700 Subject: [PATCH 2/3] update directory --- Projects/2048/2048.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Projects/2048/2048.py b/Projects/2048/2048.py index 81f208e..46edbac 100644 --- a/Projects/2048/2048.py +++ b/Projects/2048/2048.py @@ -39,7 +39,7 @@ init_count = 0 direction = "" score = 0 -file = open("2048\high_score.txt", "r") +file = open("high_score.txt", "r") init_high = int(file.readline()) file.close() high_score = init_high @@ -230,7 +230,7 @@ def take_turn(direc, board): if game_over: draw_over() if high_score > init_high: - file = open("2048\high_score.txt", "w") + file = open("high_score.txt", "w") file.write(f"{high_score}") file.close() init_high = high_score From 927c5e55fb3bdb3e3507d686abc8f8a5aee4a4f9 Mon Sep 17 00:00:00 2001 From: choidf <39011839+choidf@users.noreply.github.com> Date: Sun, 5 Nov 2023 21:22:56 +0700 Subject: [PATCH 3/3] linting 2048.py --- Projects/2048/2048.py | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/Projects/2048/2048.py b/Projects/2048/2048.py index 46edbac..981d847 100644 --- a/Projects/2048/2048.py +++ b/Projects/2048/2048.py @@ -44,6 +44,7 @@ file.close() high_score = init_high + # draw game over and restart text def draw_over(): pygame.draw.rect(screen, "black", [50, 50, 300, 100], 0, 10) @@ -76,12 +77,18 @@ def draw_pieces(board): color = colors[value] else: color = color["other"] - pygame.draw.rect(screen, color, [j * 95 + 20, i * 95 + 20, 75, 75], 0, 5) + pygame.draw.rect( + screen, color, [j * 95 + 20, i * 95 + 20, 75, 75], 0, 5 + ) if value > 0: value_len = len(str(value)) - font = pygame.font.Font("freesansbold.ttf", 48 - (5 * value_len)) + font = pygame.font.Font( + "freesansbold.ttf", 48 - (5 * value_len) + ) value_text = font.render(str(value), True, value_color) - text_rect = value_text.get_rect(center=(j * 95 + 57, i * 95 + 57)) + text_rect = value_text.get_rect( + center=(j * 95 + 57, i * 95 + 57) + ) screen.blit(value_text, text_rect) pygame.draw.rect( screen, "black", [j * 95 + 20, i * 95 + 20, 75, 75], 2, 5 @@ -93,7 +100,8 @@ def draw_pieces(board): def is_game_over(board): for i in range(3): for j in range(3): - if board[i][j] == board[i + 1][j] or board[i][j] == board[i][j + 1]: + if (board[i][j] == board[i + 1][j] or + board[i][j] == board[i][j + 1]): return False for j in range(3): @@ -103,7 +111,7 @@ def is_game_over(board): for i in range(3): if board[i][3] == board[i + 1][3]: return False - ## if there's no valid move left, the game is over + # if there's no valid move left, the game is over return True