Mystery Game #11

← Back to Games List
// 2048 Game Implementation const canvas = document.getElementById('gameCanvas'); const ctx = canvas.getContext('2d'); // Game settings const gridSize = 4; const cellSize = 100; const padding = 10; canvas.width = gridSize * (cellSize + padding) + padding; canvas.height = canvas.width; // Colors for different numbers const colors = { 2: '#eee4da', 4: '#ede0c8', 8: '#f2b179', 16: '#f59563', 32: '#f67c5f', 64: '#f65e3b', 128: '#edcf72', 256: '#edcc61', 512: '#edc850', 1024: '#edc53f', 2048: '#edc22e' }; // Game state let grid = []; let score = 0; let gameOver = false; let won = false; // Initialize grid function initGrid() { grid = Array(gridSize).fill().map(() => Array(gridSize).fill(0)); addNewTile(); addNewTile(); } // Add new tile (2 or 4) function addNewTile() { const emptyCells = []; for (let i = 0; i < gridSize; i++) { for (let j = 0; j < gridSize; j++) { if (grid[i][j] === 0) { emptyCells.push({x: i, y: j}); } } } if (emptyCells.length > 0) { const cell = emptyCells[Math.floor(Math.random() * emptyCells.length)]; grid[cell.x][cell.y] = Math.random() < 0.9 ? 2 : 4; } } // Move tiles in a direction function moveTiles(direction) { let moved = false; const tempGrid = grid.map(row => [...row]); // Rotate grid to simplify movement logic for (let i = 0; i < direction; i++) { grid = rotateGrid(grid); } // Move and merge tiles for (let i = 0; i < gridSize; i++) { let row = grid[i].filter(cell => cell !== 0); for (let j = 0; j < row.length - 1; j++) { if (row[j] === row[j + 1]) { row[j] *= 2; score += row[j]; row.splice(j + 1, 1); if (row[j] === 2048 && !won) { won = true; } } } row = row.concat(Array(gridSize - row.length).fill(0)); grid[i] = row; } // Rotate back for (let i = 0; i < (4 - direction) % 4; i++) { grid = rotateGrid(grid); } // Check if grid changed for (let i = 0; i < gridSize; i++) { for (let j = 0; j < gridSize; j++) { if (grid[i][j] !== tempGrid[i][j]) { moved = true; } } } return moved; } // Rotate grid clockwise function rotateGrid(grid) { const newGrid = Array(gridSize).fill().map(() => Array(gridSize).fill(0)); for (let i = 0; i < gridSize; i++) { for (let j = 0; j < gridSize; j++) { newGrid[j][gridSize - 1 - i] = grid[i][j]; } } return newGrid; } // Check if game is over function checkGameOver() { // Check for empty cells for (let i = 0; i < gridSize; i++) { for (let j = 0; j < gridSize; j++) { if (grid[i][j] === 0) return false; } } // Check for possible merges for (let i = 0; i < gridSize; i++) { for (let j = 0; j < gridSize; j++) { if (j < gridSize - 1 && grid[i][j] === grid[i][j + 1]) return false; if (i < gridSize - 1 && grid[i][j] === grid[i + 1][j]) return false; } } return true; } // Handle keyboard input document.addEventListener('keydown', (e) => { if (gameOver || won) { if (e.key === 'Enter') { grid = Array(gridSize).fill().map(() => Array(gridSize).fill(0)); score = 0; gameOver = false; won = false; initGrid(); } return; } let moved = false; switch(e.key) { case 'ArrowLeft': moved = moveTiles(3); // Left movement break; case 'ArrowRight': moved = moveTiles(1); // Right movement break; case 'ArrowUp': moved = moveTiles(0); // Up movement break; case 'ArrowDown': moved = moveTiles(2); // Down movement break; } if (moved) { addNewTile(); if (checkGameOver()) { gameOver = true; } } }); function draw() { // Clear canvas ctx.fillStyle = '#bbada0'; ctx.fillRect(0, 0, canvas.width, canvas.height); // Draw grid for (let i = 0; i < gridSize; i++) { for (let j = 0; j < gridSize; j++) { const value = grid[i][j]; const x = j * (cellSize + padding) + padding; const y = i * (cellSize + padding) + padding; // Draw cell background ctx.fillStyle = value === 0 ? '#cdc1b4' : colors[value] || '#edc22e'; ctx.fillRect(x, y, cellSize, cellSize); // Draw number if (value !== 0) { ctx.fillStyle = value <= 4 ? '#776e65' : '#f9f6f2'; ctx.font = value >= 1000 ? '35px Arial' : '40px Arial'; ctx.textAlign = 'center'; ctx.textBaseline = 'middle'; ctx.fillText(value, x + cellSize/2, y + cellSize/2); } } } // Draw score ctx.fillStyle = '#776e65'; ctx.font = '20px Arial'; ctx.textAlign = 'left'; ctx.fillText('Score: ' + score, padding, canvas.height - padding); // Draw game over or win message if (gameOver || won) { ctx.fillStyle = 'rgba(238, 228, 218, 0.8)'; ctx.fillRect(0, 0, canvas.width, canvas.height); ctx.fillStyle = '#776e65'; ctx.font = '40px Arial'; ctx.textAlign = 'center'; ctx.fillText(won ? 'You Win!' : 'Game Over!', canvas.width/2, canvas.height/2 - 20); ctx.font = '20px Arial'; ctx.fillText('Score: ' + score, canvas.width/2, canvas.height/2 + 20); ctx.fillText('Press Enter to Play Again', canvas.width/2, canvas.height/2 + 50); } } // Start game initGrid(); gameLoop();
# 2048 Game Implementation import pygame import random from dataclasses import dataclass from typing import List, Dict, Tuple import numpy as np @dataclass class Colors: GRID_COLOR: Tuple[int, int, int] = (187, 173, 160) # #bbada0 EMPTY_CELL: Tuple[int, int, int] = (205, 193, 180) # #cdc1b4 TEXT_DARK: Tuple[int, int, int] = (119, 110, 101) # #776e65 TEXT_LIGHT: Tuple[int, int, int] = (249, 246, 242) # #f9f6f2 # Tile colors TILE_COLORS: Dict[int, Tuple[int, int, int]] = { 2: (238, 228, 218), # #eee4da 4: (237, 224, 200), # #ede0c8 8: (242, 177, 121), # #f2b179 16: (245, 149, 99), # #f59563 32: (246, 124, 95), # #f67c5f 64: (246, 94, 59), # #f65e3b 128: (237, 207, 114), # #edcf72 256: (237, 204, 97), # #edcc61 512: (237, 200, 80), # #edc850 1024: (237, 197, 63), # #edc53f 2048: (237, 194, 46) # #edc22e } class Game2048: def __init__(self): pygame.init() # Game settings self.grid_size = 4 self.cell_size = 100 self.padding = 10 self.width = self.grid_size * (self.cell_size + self.padding) + self.padding self.height = self.width # Initialize display self.screen = pygame.display.set_mode((self.width, self.height)) pygame.display.set_caption('2048') self.clock = pygame.time.Clock() # Colors self.colors = Colors() # Game state self.grid = np.zeros((self.grid_size, self.grid_size), dtype=int) self.score = 0 self.game_over = False self.won = False # Initialize game self.init_grid() def init_grid(self): """Initialize grid with two random tiles""" self.add_new_tile() self.add_new_tile() def add_new_tile(self): """Add a new tile (2 or 4) to a random empty cell""" empty_cells = list(zip(*np.where(self.grid == 0))) if empty_cells: i, j = random.choice(empty_cells) self.grid[i][j] = 2 if random.random() < 0.9 else 4 def move_tiles(self, direction: int) -> bool: """Move tiles in specified direction (0:up, 1:right, 2:down, 3:left)""" # Save original grid for comparison original = self.grid.copy() # Rotate grid to handle all directions uniformly self.grid = np.rot90(self.grid, direction) # Process each row for i in range(self.grid_size): # Remove zeros and get non-empty tiles row = self.grid[i][self.grid[i] != 0] # Merge adjacent equal tiles for j in range(len(row) - 1): if row[j] == row[j + 1]: row[j] *= 2 self.score += row[j] row = np.delete(row, j + 1) if row[j] == 2048: self.won = True break # Pad with zeros new_row = np.zeros(self.grid_size, dtype=int) new_row[:len(row)] = row self.grid[i] = new_row # Rotate back self.grid = np.rot90(self.grid, -direction) # Check if grid changed return not np.array_equal(original, self.grid) def check_game_over(self) -> bool: """Check if no moves are possible""" if np.any(self.grid == 0): return False # Check for possible merges for i in range(self.grid_size): for j in range(self.grid_size): value = self.grid[i][j] if (j < self.grid_size - 1 and value == self.grid[i][j + 1]) or \ (i < self.grid_size - 1 and value == self.grid[i + 1][j]): return False return True def handle_input(self) -> bool: """Handle keyboard input""" for event in pygame.event.get(): if event.type == pygame.QUIT: return False if event.type == pygame.KEYDOWN: if self.game_over or self.won: if event.key == pygame.K_RETURN: self.grid = np.zeros((self.grid_size, self.grid_size), dtype=int) self.score = 0 self.game_over = False self.won = False self.init_grid() else: moved = False if event.key == pygame.K_LEFT: moved = self.move_tiles(3) elif event.key == pygame.K_RIGHT: moved = self.move_tiles(1) elif event.key == pygame.K_UP: moved = self.move_tiles(0) elif event.key == pygame.K_DOWN: moved = self.move_tiles(2) if moved: self.add_new_tile() if self.check_game_over(): self.game_over = True return True def draw(self): """Draw the game state""" # Clear screen with background color self.screen.fill(self.colors.GRID_COLOR) # Draw grid for i in range(self.grid_size): for j in range(self.grid_size): value = self.grid[i][j] x = j * (self.cell_size + self.padding) + self.padding y = i * (self.cell_size + self.padding) + self.padding # Draw cell background color = self.colors.EMPTY_CELL if value == 0 else \ self.colors.TILE_COLORS.get(value, self.colors.TILE_COLORS[2048]) pygame.draw.rect(self.screen, color, (x, y, self.cell_size, self.cell_size)) # Draw number if value != 0: font_size = 35 if value >= 1000 else 40 font = pygame.font.Font(None, font_size) text_color = self.colors.TEXT_DARK if value <= 4 else self.colors.TEXT_LIGHT text = font.render(str(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 score font = pygame.font.Font(None, 36) score_text = font.render(f'Score: {self.score}', True, self.colors.TEXT_DARK) self.screen.blit(score_text, (self.padding, self.height - self.padding - 20)) # Draw game over or win message if self.game_over or self.won: overlay = pygame.Surface((self.width, self.height)) overlay.fill((238, 228, 218)) overlay.set_alpha(204) # 80% opacity self.screen.blit(overlay, (0, 0)) font = pygame.font.Font(None, 64) message = 'You Win!' if self.won else 'Game Over!' text = font.render(message, True, self.colors.TEXT_DARK) text_rect = text.get_rect(center=(self.width/2, self.height/2 - 20)) self.screen.blit(text, text_rect) font = pygame.font.Font(None, 36) score = font.render(f'Score: {self.score}', True, self.colors.TEXT_DARK) score_rect = score.get_rect(center=(self.width/2, self.height/2 + 20)) self.screen.blit(score, score_rect) play_again = font.render('Press Enter to Play Again', True, self.colors.TEXT_DARK) play_again_rect = play_again.get_rect( center=(self.width/2, self.height/2 + 50)) self.screen.blit(play_again, play_again_rect) pygame.display.flip() def run(self): """Main game loop""" running = True while running: running = self.handle_input() self.draw() self.clock.tick(60) pygame.quit() if __name__ == '__main__': game = Game2048() game.run()
Play Game