diff --git a/GameCollection/__pycache__/game_2048.cpython-314.pyc b/GameCollection/__pycache__/game_2048.cpython-314.pyc new file mode 100644 index 0000000..7376eb3 Binary files /dev/null and b/GameCollection/__pycache__/game_2048.cpython-314.pyc differ diff --git a/GameCollection/__pycache__/main.cpython-314.pyc b/GameCollection/__pycache__/main.cpython-314.pyc new file mode 100644 index 0000000..6167032 Binary files /dev/null and b/GameCollection/__pycache__/main.cpython-314.pyc differ diff --git a/GameCollection/__pycache__/snake_game.cpython-314.pyc b/GameCollection/__pycache__/snake_game.cpython-314.pyc new file mode 100644 index 0000000..475204a Binary files /dev/null and b/GameCollection/__pycache__/snake_game.cpython-314.pyc differ diff --git a/GameCollection/game_2048.py b/GameCollection/game_2048.py new file mode 100644 index 0000000..cafe37d --- /dev/null +++ b/GameCollection/game_2048.py @@ -0,0 +1,271 @@ +import pygame +import numpy as np +import copy +import os +from pygame.locals import * + +# Colors for different tile values +COLORS = { + 0: (205, 193, 180), + 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), +} + +TEXT_COLORS = { + 2: (119, 110, 101), + 4: (119, 110, 101), + 8: (255, 255, 255), + 16: (255, 255, 255), + 32: (255, 255, 255), + 64: (255, 255, 255), + 128: (255, 255, 255), + 256: (255, 255, 255), + 512: (255, 255, 255), + 1024: (255, 255, 255), + 2048: (255, 255, 255), +} + +BG_COLOR = (187, 173, 160) +GRID_COLOR = (187, 173, 160) +FILENAME = 'out.npy' + + +class Game2048: + def __init__(self, screen=None, standalone=True): + self.score = 0 + self.win = 0 + self.board = self.init_board() + self.rscore = self.load_score() + self.standalone = standalone + self.screen = screen + self.font = None + self.tile_font = None + self.game_over_flag = False + self.cell_size = 100 + self.padding = 10 + self.board_size = 4 * self.cell_size + 5 * self.padding + + if standalone and screen is None: + pygame.init() + self.screen = pygame.display.set_mode((self.board_size, self.board_size + 100)) + pygame.display.set_caption('2048 Game') + self.font = pygame.font.SysFont('Arial', 30) + self.tile_font = pygame.font.SysFont('Arial', 40, bold=True) + + def init_board(self): + if FILENAME not in os.listdir(): + np.save(FILENAME, 0) + board = self.choice(np.zeros((4, 4), dtype=int)) + return board + + def choice(self, board): + udict = {} + count = 0 + for i in range(4): + for j in range(4): + if not board[i, j]: + udict[count] = (i, j) + count += 1 + if count == 0: + return board + random_number = np.random.randint(0, count) + two_or_four = np.random.choice([2, 2, 2, 4]) + board[udict[random_number]] = two_or_four + return board + + def basic(self, board): + for i in range(4): + flag = 1 + while flag: + flag = 0 + j = 2 + while j >= 0: + if board[i, j] != 0: + if board[i, j + 1] == board[i, j]: + board[i, j + 1] = 2 * board[i, j] + if board[i, j + 1] == 2048: + self.win = 1 + board[i, j] = 0 + self.score += 100 + flag = 1 + elif board[i, j + 1] == 0: + temp = board[i, j] + board[i, j] = board[i, j + 1] + board[i, j + 1] = temp + flag = 1 + j -= 1 + return board + + def move_right(self, board): + return self.basic(board) + + def move_up(self, board): + board = board[::-1, ::-1].T + board = self.basic(board) + board = board[::-1, ::-1].T + return board + + def move_left(self, board): + board = board[::-1, ::-1] + board = self.basic(board) + board = board[::-1, ::-1] + return board + + def move_down(self, board): + board = board.T + board = self.basic(board) + board = board.T + return board + + def move(self, order): + change = 1 + tempboard = copy.deepcopy(self.board) + + if order == ord('r') or order == K_r: + self.reset_game() + return + elif order == ord('q') or order == K_q: + self.save_score() + return 'quit' + elif self.win and (order in [ord('w'), ord('a'), ord('s'), ord('d'), K_UP, K_LEFT, K_DOWN, K_RIGHT]): + change = 0 + return + elif order == ord('w') or order == K_UP or order == K_w: + self.board = self.move_up(self.board) + elif order == ord('s') or order == K_DOWN or order == K_s: + self.board = self.move_down(self.board) + elif order == ord('a') or order == K_LEFT or order == K_a: + self.board = self.move_left(self.board) + elif order == ord('d') or order == K_RIGHT or order == K_d: + self.board = self.move_right(self.board) + else: + newboard = self.board + + if (self.board == tempboard).all(): + change = 0 + + if change: + self.board = self.choice(self.board) + + self.check_fail() + self.rscore = max(self.rscore, self.score) + + def check_fail(self): + if (self.board != 0).all(): + diff1 = self.board[:, 1:] - self.board[:, :-1] + diff2 = self.board[1:, :] - self.board[:-1, :] + inter = (diff1 != 0).all() and (diff2 != 0).all() + if inter: + self.game_over_flag = True + self.save_score() + + def load_score(self): + try: + rank_score = np.load(FILENAME) + return int(rank_score) + except: + return 0 + + def save_score(self): + if self.score > self.rscore: + np.save(FILENAME, self.score) + + def reset_game(self): + self.save_score() + self.score = 0 + self.win = 0 + self.game_over_flag = False + self.board = self.init_board() + self.rscore = self.load_score() + + def draw_board(self): + if self.screen is None: + return + + self.screen.fill(BG_COLOR) + + # Draw score + if self.font: + score_text = self.font.render(f'Score: {self.score}', True, (255, 255, 255)) + self.screen.blit(score_text, (10, 10)) + high_score_text = self.font.render(f'Best: {max(self.rscore, self.score)}', True, (255, 255, 255)) + self.screen.blit(high_score_text, (self.board_size - 150, 10)) + + # Draw grid + for i in range(4): + for j in range(4): + value = self.board[i, j] + x = self.padding + j * (self.cell_size + self.padding) + y = 60 + self.padding + i * (self.cell_size + self.padding) + + color = COLORS.get(int(value), (60, 58, 50)) + pygame.draw.rect(self.screen, color, (x, y, self.cell_size, self.cell_size), border_radius=8) + + if value != 0: + text_color = TEXT_COLORS.get(int(value), (255, 255, 255)) + if self.tile_font: + text = self.tile_font.render(str(int(value)), True, text_color) + text_rect = text.get_rect(center=(x + self.cell_size // 2, y + self.cell_size // 2)) + self.screen.blit(text, text_rect) + + # Draw win message + if self.win: + if self.font: + win_text = self.font.render('You Win! Press R to restart', True, (0, 255, 0)) + text_rect = win_text.get_rect(center=(self.board_size // 2, self.board_size // 2 + 30)) + self.screen.blit(win_text, text_rect) + + # Draw game over message + if self.game_over_flag: + if self.font: + over_text = self.font.render('Game Over! Press R to restart', True, (255, 0, 0)) + text_rect = over_text.get_rect(center=(self.board_size // 2, self.board_size // 2 + 30)) + self.screen.blit(over_text, text_rect) + + def handle_event(self, event): + if event.type == KEYDOWN: + if event.key in [K_UP, K_DOWN, K_LEFT, K_RIGHT, K_w, K_s, K_a, K_d, K_r, K_q]: + result = self.move(event.key) + if result == 'quit': + return 'quit' + return None + + def update(self): + self.draw_board() + pygame.display.update() + + def run(self): + if not self.standalone: + return + + clock = pygame.time.Clock() + running = True + + while running: + for event in pygame.event.get(): + if event.type == QUIT: + running = False + else: + result = self.handle_event(event) + if result == 'quit': + running = False + + self.update() + clock.tick(30) + + self.save_score() + pygame.quit() + + +if __name__ == '__main__': + game = Game2048() + game.run() diff --git a/GameCollection/main.py b/GameCollection/main.py new file mode 100644 index 0000000..f26e4f4 --- /dev/null +++ b/GameCollection/main.py @@ -0,0 +1,181 @@ +import pygame +from pygame.locals import * +from game_2048 import Game2048 +from snake_game import SnakeGame + +# Screen dimensions +SCREEN_WIDTH = 960 +SCREEN_HEIGHT = 600 + +# Colors +BG_COLOR = (50, 50, 50) +MENU_BG_COLOR = (30, 30, 30) +TEXT_COLOR = (255, 255, 255) +HIGHLIGHT_COLOR = (0, 200, 255) + + +class GameCollection: + def __init__(self): + pygame.init() + self.screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT)) + pygame.display.set_caption('Game Collection - Press TAB to switch games') + self.clock = pygame.time.Clock() + self.font = pygame.font.SysFont('Arial', 30) + self.small_font = pygame.font.SysFont('Arial', 20) + self.title_font = pygame.font.SysFont('Arial', 40, bold=True) + + # Game states: 'menu', '2048', 'snake' + self.current_state = 'menu' + self.selected_game = 0 # 0 for 2048, 1 for snake + + # Initialize games + self.game_2048 = None + self.snake_game = None + + def draw_menu(self): + self.screen.fill(MENU_BG_COLOR) + + # Draw title + title = self.title_font.render('Game Collection', True, HIGHLIGHT_COLOR) + title_rect = title.get_rect(center=(SCREEN_WIDTH // 2, 100)) + self.screen.blit(title, title_rect) + + # Draw game options + games = ['1. 2048 Game', '2. Snake Game'] + y_start = 250 + for i, game in enumerate(games): + color = HIGHLIGHT_COLOR if i == self.selected_game else TEXT_COLOR + text = self.font.render(game, True, color) + text_rect = text.get_rect(center=(SCREEN_WIDTH // 2, y_start + i * 80)) + self.screen.blit(text, text_rect) + + # Draw instructions + instructions = [ + 'Controls:', + 'UP/DOWN - Select game', + 'ENTER - Start game', + 'TAB - Switch games while playing', + 'ESC - Return to menu / Quit' + ] + y = 450 + for instruction in instructions: + text = self.small_font.render(instruction, True, (150, 150, 150)) + self.screen.blit(text, (50, y)) + y += 25 + + pygame.display.update() + + def init_game_2048(self): + self.game_2048 = Game2048(screen=self.screen, standalone=False) + self.game_2048.font = pygame.font.SysFont('Arial', 30) + self.game_2048.tile_font = pygame.font.SysFont('Arial', 40, bold=True) + # Adjust cell size for the collection screen + self.game_2048.cell_size = 100 + self.game_2048.padding = 10 + self.game_2048.board_size = 4 * self.game_2048.cell_size + 5 * self.game_2048.padding + + def init_snake_game(self): + self.snake_game = SnakeGame(screen=self.screen, standalone=False) + self.snake_game.font = pygame.font.SysFont('Arial', 20) + + def draw_switch_notification(self): + # Draw a small notification at the top + notification = self.small_font.render('Press TAB to switch games | ESC for menu', True, (255, 255, 0)) + self.screen.blit(notification, (10, 5)) + + def run_game_2048(self): + if self.game_2048 is None: + self.init_game_2048() + + for event in pygame.event.get(): + if event.type == QUIT: + return 'quit' + elif event.type == KEYDOWN: + if event.key == K_TAB: + self.current_state = 'snake' + if self.snake_game is None: + self.init_snake_game() + return + elif event.key == K_ESCAPE: + self.current_state = 'menu' + return + else: + result = self.game_2048.handle_event(event) + if result == 'quit': + return 'quit' + + self.game_2048.draw_board() + self.draw_switch_notification() + pygame.display.update() + + def run_snake_game(self): + if self.snake_game is None: + self.init_snake_game() + + for event in pygame.event.get(): + if event.type == QUIT: + return 'quit' + elif event.type == KEYDOWN: + if event.key == K_TAB: + self.current_state = '2048' + if self.game_2048 is None: + self.init_game_2048() + return + elif event.key == K_ESCAPE: + self.current_state = 'menu' + return + else: + self.snake_game.handle_event(event) + + self.snake_game.update() + self.draw_switch_notification() + + def run(self): + running = True + + while running: + if self.current_state == 'menu': + for event in pygame.event.get(): + if event.type == QUIT: + running = False + elif event.type == KEYDOWN: + if event.key == K_ESCAPE: + running = False + elif event.key == K_UP: + self.selected_game = (self.selected_game - 1) % 2 + elif event.key == K_DOWN: + self.selected_game = (self.selected_game + 1) % 2 + elif event.key == K_RETURN: + if self.selected_game == 0: + self.current_state = '2048' + if self.game_2048 is None: + self.init_game_2048() + else: + self.current_state = 'snake' + if self.snake_game is None: + self.init_snake_game() + + self.draw_menu() + + elif self.current_state == '2048': + result = self.run_game_2048() + if result == 'quit': + running = False + + elif self.current_state == 'snake': + result = self.run_snake_game() + if result == 'quit': + running = False + + self.clock.tick(30) + + # Save scores before quitting + if self.game_2048: + self.game_2048.save_score() + + pygame.quit() + + +if __name__ == '__main__': + app = GameCollection() + app.run() diff --git a/GameCollection/out.npy b/GameCollection/out.npy new file mode 100644 index 0000000..748264c Binary files /dev/null and b/GameCollection/out.npy differ diff --git a/GameCollection/snake_game.py b/GameCollection/snake_game.py new file mode 100644 index 0000000..f719a33 --- /dev/null +++ b/GameCollection/snake_game.py @@ -0,0 +1,210 @@ +import pygame +import time +import numpy as np +from pygame.locals import * + +# Board dimensions +BOARDWIDTH = 48 +BOARDHEIGHT = 28 + + +class Food: + def __init__(self): + self.item = (4, 5) + + def _draw(self, screen, i, j): + color = 255, 0, 255 + radius = 10 + width = 10 + position = 10 + 20 * i, 10 + 20 * j + pygame.draw.circle(screen, color, position, radius, width) + + def update(self, screen, enlarge, snack): + if enlarge: + self.item = np.random.randint(1, BOARDWIDTH - 2), np.random.randint(1, BOARDHEIGHT - 2) + while self.item in snack.item: + self.item = np.random.randint(1, BOARDWIDTH - 2), np.random.randint(1, BOARDHEIGHT - 2) + self._draw(screen, self.item[0], self.item[1]) + + +class Snake: + def __init__(self): + self.item = [(3, 25), (2, 25), (1, 25), (1, 24)] + self.x = 0 + self.y = -1 + self.score = 0 + + def move(self, enlarge): + if not enlarge: + self.item.pop() + head = (self.item[0][0] + self.x, self.item[0][1] + self.y) + self.item.insert(0, head) + + def eat_food(self, food): + snake_x, snake_y = self.item[0] + food_x, food_y = food.item + if (food_x == snake_x) and (food_y == snake_y): + self.score += 100 + return 1 + else: + return 0 + + def toward(self, x, y): + if self.x * x >= 0 and self.y * y >= 0: + self.x = x + self.y = y + + def get_head(self): + return self.item[0] + + def draw(self, screen): + radius = 15 + width = 15 + color = 255, 0, 0 + position = 10 + 20 * self.item[0][0], 10 + 20 * self.item[0][1] + pygame.draw.circle(screen, color, position, radius, width) + radius = 10 + width = 10 + color = 255, 255, 0 + for i, j in self.item[1:]: + position = 10 + 20 * i, 10 + 20 * j + pygame.draw.circle(screen, color, position, radius, width) + + +class SnakeGame: + def __init__(self, screen=None, standalone=True): + self.snake = None + self.food = None + self.is_fail = False + self.standalone = standalone + self.screen = screen + self.font = None + self.clock = pygame.time.Clock() + self.last_update = 0 + + if standalone and screen is None: + pygame.init() + self.screen = pygame.display.set_mode((BOARDWIDTH * 20, BOARDHEIGHT * 20)) + pygame.display.set_caption('Snake Game') + self.font = pygame.font.SysFont('SimHei', 20) + + self.reset_game() + + def reset_game(self): + self.snake = Snake() + self.food = Food() + self.is_fail = False + + def init_board(self, screen): + board_width = BOARDWIDTH + board_height = BOARDHEIGHT + color = 10, 255, 255 + width = 0 + for i in range(board_width): + pos = i * 20, 0, 20, 20 + pygame.draw.rect(screen, color, pos, width) + pos = i * 20, (board_height - 1) * 20, 20, 20 + pygame.draw.rect(screen, color, pos, width) + for i in range(board_height - 1): + pos = 0, 20 + i * 20, 20, 20 + pygame.draw.rect(screen, color, pos, width) + pos = (board_width - 1) * 20, 20 + i * 20, 20, 20 + pygame.draw.rect(screen, color, pos, width) + + def game_over(self): + broad_x, broad_y = self.snake.get_head() + flag = 0 + old = len(self.snake.item) + new = len(set(self.snake.item)) + if new < old: + flag = 1 + if broad_x == 0 or broad_x == BOARDWIDTH - 1: + flag = 1 + if broad_y == 0 or broad_y == BOARDHEIGHT - 1: + flag = 1 + return flag == 1 + + def print_text(self, screen, font, x, y, text, color=(255, 0, 0)): + imgText = font.render(text, True, color) + screen.blit(imgText, (x, y)) + + def handle_key(self, keys): + if keys[K_w] or keys[K_UP]: + self.snake.toward(0, -1) + elif keys[K_s] or keys[K_DOWN]: + self.snake.toward(0, 1) + elif keys[K_a] or keys[K_LEFT]: + self.snake.toward(-1, 0) + elif keys[K_d] or keys[K_RIGHT]: + self.snake.toward(1, 0) + elif keys[K_r]: + self.reset_game() + + def handle_event(self, event): + if event.type == KEYDOWN: + if event.key == K_r: + self.reset_game() + + def update(self): + current_time = time.time() + if current_time - self.last_update < 0.1: + return + self.last_update = current_time + + if self.screen is None: + return + + self.screen.fill((0, 0, 100)) + self.init_board(self.screen) + + keys = pygame.key.get_pressed() + self.handle_key(keys) + + if self.is_fail: + if self.font: + font2 = pygame.font.Font(None, 40) + self.print_text(self.screen, self.font, 0, 0, f"Score: {self.snake.score}") + self.print_text(self.screen, font2, 400, 200, "GAME OVER") + else: + font = pygame.font.SysFont('Arial', 40) + text = font.render("GAME OVER - Press R to restart", True, (255, 0, 0)) + text_rect = text.get_rect(center=(BOARDWIDTH * 10, BOARDHEIGHT * 10)) + self.screen.blit(text, text_rect) + else: + enlarge = self.snake.eat_food(self.food) + if self.font: + text = f"Score: {self.snake.score}" + self.print_text(self.screen, self.font, 0, 0, text) + else: + font = pygame.font.SysFont('Arial', 20) + text = font.render(f"Score: {self.snake.score}", True, (255, 255, 255)) + self.screen.blit(text, (10, 10)) + + self.food.update(self.screen, enlarge, self.snake) + self.snake.move(enlarge) + self.is_fail = self.game_over() + self.snake.draw(self.screen) + + pygame.display.update() + + def run(self): + if not self.standalone: + return + + running = True + while running: + for event in pygame.event.get(): + if event.type == QUIT: + running = False + else: + self.handle_event(event) + + self.update() + self.clock.tick(30) + + pygame.quit() + + +if __name__ == '__main__': + game = SnakeGame() + game.run()