Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file not shown.
Binary file not shown.
190 changes: 190 additions & 0 deletions game_collection/game_2048.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
import pygame
import numpy as np
import copy
import os

CELL_SIZE = 100
GRID_SIZE = 4
MARGIN = 10
HEADER_HEIGHT = 80
WINDOW_SIZE = GRID_SIZE * CELL_SIZE + (GRID_SIZE + 1) * MARGIN
TOTAL_HEIGHT = WINDOW_SIZE + HEADER_HEIGHT

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),
}

class Game2048:
def __init__(self, screen):
self.screen = screen
self.font_large = pygame.font.SysFont('Arial', 40, bold=True)
self.font_small = pygame.font.SysFont('Arial', 24)
self.font_score = pygame.font.SysFont('Arial', 28, bold=True)
self.reset()

def reset(self):
self.board = np.zeros((GRID_SIZE, GRID_SIZE), dtype=int)
self.score = 0
self.win = False
self.game_over = False
self.add_random_tile()
self.add_random_tile()

def add_random_tile(self):
empty_cells = []
for i in range(GRID_SIZE):
for j in range(GRID_SIZE):
if self.board[i, j] == 0:
empty_cells.append((i, j))
if empty_cells:
i, j = empty_cells[np.random.randint(len(empty_cells))]
self.board[i, j] = np.random.choice([2, 2, 2, 4])

def move_left(self):
changed = False
for i in range(GRID_SIZE):
row = self.board[i, :]
new_row = []
merged = []
for val in row:
if val != 0:
if new_row and new_row[-1] == val and not merged[-1]:
new_row[-1] *= 2
self.score += new_row[-1]
merged[-1] = True
if new_row[-1] == 2048:
self.win = True
else:
new_row.append(val)
merged.append(False)
new_row += [0] * (GRID_SIZE - len(new_row))
if not np.array_equal(row, new_row):
changed = True
self.board[i, :] = new_row
return changed

def move_right(self):
self.board = self.board[:, ::-1]
changed = self.move_left()
self.board = self.board[:, ::-1]
return changed

def move_up(self):
self.board = self.board.T
changed = self.move_left()
self.board = self.board.T
return changed

def move_down(self):
self.board = self.board.T
changed = self.move_right()
self.board = self.board.T
return changed

def can_move(self):
if (self.board == 0).any():
return True
for i in range(GRID_SIZE):
for j in range(GRID_SIZE - 1):
if self.board[i, j] == self.board[i, j + 1]:
return True
for i in range(GRID_SIZE - 1):
for j in range(GRID_SIZE):
if self.board[i, j] == self.board[i + 1, j]:
return True
return False

def handle_input(self, key):
if self.game_over or self.win:
if key == pygame.K_r:
self.reset()
return

changed = False
if key == pygame.K_LEFT or key == pygame.K_a:
changed = self.move_left()
elif key == pygame.K_RIGHT or key == pygame.K_d:
changed = self.move_right()
elif key == pygame.K_UP or key == pygame.K_w:
changed = self.move_up()
elif key == pygame.K_DOWN or key == pygame.K_s:
changed = self.move_down()

if changed:
self.add_random_tile()
if not self.can_move():
self.game_over = True

def draw(self):
self.screen.fill((250, 248, 239))

title = self.font_large.render('2048', True, (119, 110, 101))
self.screen.blit(title, (MARGIN, 15))

score_text = self.font_score.render(f'Score: {self.score}', True, (119, 110, 101))
self.screen.blit(score_text, (WINDOW_SIZE - score_text.get_width() - MARGIN, 20))

hint = self.font_small.render('Arrow Keys/WASD: Move | R: Reset | ESC: Switch Game', True, (150, 150, 150))
self.screen.blit(hint, (MARGIN, 55))

grid_x = MARGIN
grid_y = HEADER_HEIGHT

pygame.draw.rect(self.screen, (187, 173, 160),
(grid_x, grid_y, WINDOW_SIZE - MARGIN, WINDOW_SIZE - MARGIN),
border_radius=6)

for i in range(GRID_SIZE):
for j in range(GRID_SIZE):
x = grid_x + MARGIN + j * (CELL_SIZE + MARGIN)
y = grid_y + MARGIN + i * (CELL_SIZE + MARGIN)
value = self.board[i, j]
color = COLORS.get(value, (60, 58, 50))
pygame.draw.rect(self.screen, color, (x, y, CELL_SIZE, CELL_SIZE), border_radius=6)

if value != 0:
text_color = TEXT_COLORS.get(value, (255, 255, 255))
if value >= 1024:
font = pygame.font.SysFont('Arial', 28, bold=True)
elif value >= 128:
font = pygame.font.SysFont('Arial', 32, bold=True)
else:
font = self.font_large
text = font.render(str(value), True, text_color)
text_rect = text.get_rect(center=(x + CELL_SIZE // 2, y + CELL_SIZE // 2))
self.screen.blit(text, text_rect)

if self.win:
self.draw_overlay('You Win!', 'Press R to restart')
elif self.game_over:
self.draw_overlay('Game Over!', 'Press R to restart')

def draw_overlay(self, title, subtitle):
overlay = pygame.Surface((WINDOW_SIZE - MARGIN, WINDOW_SIZE - MARGIN))
overlay.fill((255, 255, 255))
overlay.set_alpha(180)
self.screen.blit(overlay, (MARGIN, HEADER_HEIGHT))

title_text = self.font_large.render(title, True, (119, 110, 101))
title_rect = title_text.get_rect(center=(WINDOW_SIZE // 2, HEADER_HEIGHT + (WINDOW_SIZE - HEADER_HEIGHT) // 2 - 20))
self.screen.blit(title_text, title_rect)

sub_text = self.font_small.render(subtitle, True, (150, 150, 150))
sub_rect = sub_text.get_rect(center=(WINDOW_SIZE // 2, HEADER_HEIGHT + (WINDOW_SIZE - HEADER_HEIGHT) // 2 + 20))
self.screen.blit(sub_text, sub_rect)
156 changes: 156 additions & 0 deletions game_collection/game_snake.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
import pygame
import time
import numpy as np
from pygame.locals import *

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 Snack:
def __init__(self):
self.item = [(3, 25), (2, 25), (1, 25), (1, 24)]
self.x = 0
self.y = -1

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):
snack_x, snack_y = self.item[0]
food_x, food_y = food.item
if (food_x == snack_x) and (food_y == snack_y):
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 GameSnake:
def __init__(self, screen):
self.screen = screen
self.font = pygame.font.SysFont('Arial', 20)
self.font_large = pygame.font.SysFont('Arial', 40)
self.reset()

def reset(self):
self.snack = Snack()
self.food = Food()
self.score = 0
self.is_fail = False
self.last_move_time = time.time()
self.move_delay = 0.1

def init_board(self):
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(self.screen, color, pos, width)
pos = i * 20, (board_height - 1) * 20, 20, 20
pygame.draw.rect(self.screen, color, pos, width)
for i in range(board_height - 1):
pos = 0, 20 + i * 20, 20, 20
pygame.draw.rect(self.screen, color, pos, width)
pos = (board_width - 1) * 20, 20 + i * 20, 20, 20
pygame.draw.rect(self.screen, color, pos, width)

def game_over(self):
broad_x, broad_y = self.snack.get_head()
flag = 0
old = len(self.snack.item)
new = len(set(self.snack.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, x, y, text, color=(255, 0, 0)):
imgText = self.font.render(text, True, color)
self.screen.blit(imgText, (x, y))

def handle_input(self, keys):
if keys[K_w] or keys[K_UP]:
self.snack.toward(0, -1)
elif keys[K_s] or keys[K_DOWN]:
self.snack.toward(0, 1)
elif keys[K_a] or keys[K_LEFT]:
self.snack.toward(-1, 0)
elif keys[K_d] or keys[K_RIGHT]:
self.snack.toward(1, 0)
elif keys[K_r]:
self.reset()

def update(self):
current_time = time.time()
if current_time - self.last_move_time >= self.move_delay:
self.last_move_time = current_time
if not self.is_fail:
enlarge = self.snack.eat_food(self.food)
if enlarge:
self.score += 100
self.food.update(self.screen, enlarge, self.snack)
self.snack.move(enlarge)
self.is_fail = self.game_over()

def draw(self):
self.screen.fill((0, 0, 100))
self.init_board()

text = f"Score: {self.score} | WASD/Arrows: Move | R: Reset | ESC: Switch Game"
self.print_text(0, 0, text)

if self.is_fail:
game_over_text = self.font_large.render("GAME OVER", True, (255, 255, 255))
text_rect = game_over_text.get_rect(center=(BOARDWIDTH * 10, BOARDHEIGHT * 10))
self.screen.blit(game_over_text, text_rect)
hint_text = self.font.render("Press R to restart", True, (200, 200, 200))
hint_rect = hint_text.get_rect(center=(BOARDWIDTH * 10, BOARDHEIGHT * 10 + 40))
self.screen.blit(hint_text, hint_rect)
else:
self.food.update(self.screen, False, self.snack)
self.snack.draw(self.screen)
Loading