Mystery Game #13

← Back to Games List
// Mastermind Game Implementation const canvas = document.getElementById('gameCanvas'); const ctx = canvas.getContext('2d'); // Game settings const rows = 10; // Number of guesses const cols = 4; // Code length const colors = ['red', 'blue', 'green', 'yellow', 'purple', 'orange']; const cellSize = 40; const pegSize = 10; const padding = 10; canvas.width = (cols * cellSize + padding * 4 + pegSize * 2) * 2; canvas.height = rows * (cellSize + padding) + padding * 2; // Game state let secretCode = []; let guesses = Array(rows).fill().map(() => Array(cols).fill(-1)); let feedback = Array(rows).fill().map(() => Array(cols).fill(-1)); let currentRow = 0; let selectedColor = 0; let gameOver = false; let won = false; // Generate secret code function generateCode() { secretCode = Array(cols).fill().map(() => Math.floor(Math.random() * colors.length)); } // Check guess against secret code function checkGuess(row) { const guess = guesses[row]; const code = [...secretCode]; const result = Array(cols).fill(-1); // First check for exact matches (black pegs) for (let i = 0; i < cols; i++) { if (guess[i] === code[i]) { result[i] = 1; // Black peg code[i] = -1; guess[i] = -2; } } // Then check for color matches (white pegs) for (let i = 0; i < cols; i++) { if (guess[i] === -2) continue; const colorIndex = code.indexOf(guess[i]); if (colorIndex !== -1) { result[i] = 0; // White peg code[colorIndex] = -1; } } feedback[row] = result; // Check for win if (result.every(peg => peg === 1)) { won = true; gameOver = true; } // Check for game over if (currentRow === rows - 1 && !won) { gameOver = true; } } // Handle mouse click canvas.addEventListener('click', (e) => { if (gameOver) { if (e.offsetY > canvas.height - 50) { // Reset game initGame(); return; } } const rect = canvas.getBoundingClientRect(); const x = e.clientX - rect.left; const y = e.clientY - rect.top; // Color palette click if (x > canvas.width / 2) { const colorX = Math.floor((x - canvas.width / 2) / cellSize); const colorY = Math.floor(y / cellSize); const index = colorY * 2 + colorX; if (index >= 0 && index < colors.length) { selectedColor = index; } return; } // Board click if (!gameOver) { const col = Math.floor(x / cellSize); const row = Math.floor(y / (cellSize + padding)); if (row === currentRow && col < cols) { guesses[row][col] = selectedColor; } // Check button click if (col === cols + 1 && row === currentRow) { if (!guesses[currentRow].includes(-1)) { checkGuess(currentRow); if (!gameOver) { currentRow++; } } } } }); function draw() { // Clear canvas ctx.fillStyle = '#333'; ctx.fillRect(0, 0, canvas.width, canvas.height); // Draw board for (let row = 0; row < rows; row++) { for (let col = 0; col < cols; col++) { const x = col * cellSize + padding; const y = row * (cellSize + padding) + padding; // Draw cell ctx.fillStyle = guesses[row][col] === -1 ? '#666' : colors[guesses[row][col]]; ctx.fillRect(x, y, cellSize - padding, cellSize - padding); } // Draw check button if (row === currentRow && !gameOver) { const x = cols * cellSize + padding * 2; const y = row * (cellSize + padding) + padding; ctx.fillStyle = '#0f0'; ctx.fillRect(x, y, cellSize - padding, cellSize - padding); } // Draw feedback pegs if (feedback[row][0] !== -1) { const startX = (cols + 2) * cellSize; const startY = row * (cellSize + padding) + padding; feedback[row].forEach((peg, i) => { if (peg !== -1) { ctx.fillStyle = peg === 1 ? 'black' : 'white'; ctx.beginPath(); ctx.arc( startX + (i % 2) * pegSize * 2, startY + Math.floor(i / 2) * pegSize * 2, pegSize/2, 0, Math.PI * 2 ); ctx.fill(); } }); } } // Draw color palette for (let i = 0; i < colors.length; i++) { const x = canvas.width/2 + (i % 2) * cellSize + padding; const y = Math.floor(i / 2) * cellSize + padding; ctx.fillStyle = colors[i]; ctx.fillRect(x, y, cellSize - padding, cellSize - padding); if (i === selectedColor) { ctx.strokeStyle = 'white'; ctx.lineWidth = 3; ctx.strokeRect(x, y, cellSize - padding, cellSize - padding); } } // Draw game over if (gameOver) { ctx.fillStyle = 'rgba(0, 0, 0, 0.7)'; ctx.fillRect(0, 0, canvas.width, canvas.height); ctx.fillStyle = 'white'; ctx.font = '40px Arial'; ctx.textAlign = 'center'; ctx.fillText(won ? 'You Win!' : 'Game Over!', canvas.width/2, canvas.height/2 - 50); // Show secret code ctx.font = '20px Arial'; ctx.fillText('Secret Code:', canvas.width/2, canvas.height/2); secretCode.forEach((color, i) => { const x = canvas.width/2 - (cols * cellSize)/2 + i * cellSize + padding; const y = canvas.height/2 + 20; ctx.fillStyle = colors[color]; ctx.fillRect(x, y, cellSize - padding, cellSize - padding); }); // Draw play again button ctx.fillStyle = '#0f0'; ctx.fillRect(canvas.width/2 - 100, canvas.height - 50, 200, 40); ctx.fillStyle = 'black'; ctx.font = '20px Arial'; ctx.fillText('Play Again', canvas.width/2, canvas.height - 25); } } function initGame() { secretCode = []; guesses = Array(rows).fill().map(() => Array(cols).fill(-1)); feedback = Array(rows).fill().map(() => Array(cols).fill(-1)); currentRow = 0; selectedColor = 0; gameOver = false; won = false; generateCode(); } // Game loop function gameLoop() { draw(); requestAnimationFrame(gameLoop); } // Start game initGame(); gameLoop();
# Mastermind Game Implementation import pygame import random from dataclasses import dataclass from typing import List, Tuple import numpy as np @dataclass class Colors: RED: Tuple[int, int, int] = (255, 0, 0) BLUE: Tuple[int, int, int] = (0, 0, 255) GREEN: Tuple[int, int, int] = (0, 255, 0) YELLOW: Tuple[int, int, int] = (255, 255, 0) PURPLE: Tuple[int, int, int] = (160, 0, 160) ORANGE: Tuple[int, int, int] = (255, 160, 0) @property def palette(self) -> List[Tuple[int, int, int]]: return [self.RED, self.BLUE, self.GREEN, self.YELLOW, self.PURPLE, self.ORANGE] class MastermindGame: def __init__(self): pygame.init() # Game settings self.rows = 10 # Number of guesses self.cols = 4 # Code length self.cell_size = 40 self.peg_size = 10 self.padding = 10 # Calculate window size self.width = (self.cols * self.cell_size + self.padding * 4 + self.peg_size * 2) * 2 self.height = self.rows * (self.cell_size + self.padding) + self.padding * 2 # Initialize display self.screen = pygame.display.set_mode((self.width, self.height)) pygame.display.set_caption('Mastermind') self.clock = pygame.time.Clock() # Colors self.colors = Colors() # Game state self.init_game() def init_game(self): """Initialize or reset game state""" self.secret_code = self.generate_code() self.guesses = np.full((self.rows, self.cols), -1, dtype=int) self.feedback = np.full((self.rows, self.cols), -1, dtype=int) self.current_row = 0 self.selected_color = 0 self.game_over = False self.won = False def generate_code(self) -> List[int]: """Generate random secret code""" return [random.randint(0, len(self.colors.palette) - 1) for _ in range(self.cols)] def check_guess(self, row: int): """Check guess against secret code""" guess = self.guesses[row].copy() code = self.secret_code.copy() result = [-1] * self.cols # Check for exact matches (black pegs) for i in range(self.cols): if guess[i] == code[i]: result[i] = 1 # Black peg code[i] = -1 guess[i] = -2 # Check for color matches (white pegs) for i in range(self.cols): if guess[i] == -2: continue try: color_index = code.index(guess[i]) result[i] = 0 # White peg code[color_index] = -1 except ValueError: pass self.feedback[row] = result # Check for win if all(peg == 1 for peg in result): self.won = True self.game_over = True # Check for game over if self.current_row == self.rows - 1 and not self.won: self.game_over = True def handle_input(self) -> bool: """Handle mouse input""" for event in pygame.event.get(): if event.type == pygame.QUIT: return False if event.type == pygame.MOUSEBUTTONDOWN: mouse_x, mouse_y = event.pos if self.game_over: # Check for play again button if mouse_y > self.height - 50: self.init_game() return True # Color palette click if mouse_x > self.width / 2: color_x = (mouse_x - self.width / 2) // self.cell_size color_y = mouse_y // self.cell_size index = color_y * 2 + color_x if 0 <= index < len(self.colors.palette): self.selected_color = index return True # Board click col = mouse_x // self.cell_size row = mouse_y // (self.cell_size + self.padding) if row == self.current_row and col < self.cols: self.guesses[row][col] = self.selected_color # Check button click if (col == self.cols + 1 and row == self.current_row and -1 not in self.guesses[self.current_row]): self.check_guess(self.current_row) if not self.game_over: self.current_row += 1 return True def draw(self): """Draw the game state""" # Clear screen self.screen.fill((51, 51, 51)) # Dark gray background # Draw board for row in range(self.rows): for col in range(self.cols): x = col * self.cell_size + self.padding y = row * (self.cell_size + self.padding) + self.padding # Draw cell color = ((102, 102, 102) if self.guesses[row][col] == -1 else self.colors.palette[self.guesses[row][col]]) pygame.draw.rect(self.screen, color, (x, y, self.cell_size - self.padding, self.cell_size - self.padding)) # Draw check button if row == self.current_row and not self.game_over: x = self.cols * self.cell_size + self.padding * 2 y = row * (self.cell_size + self.padding) + self.padding pygame.draw.rect(self.screen, (0, 255, 0), (x, y, self.cell_size - self.padding, self.cell_size - self.padding)) # Draw feedback pegs if self.feedback[row][0] != -1: start_x = (self.cols + 2) * self.cell_size start_y = row * (self.cell_size + self.padding) + self.padding for i, peg in enumerate(self.feedback[row]): if peg != -1: color = (0, 0, 0) if peg == 1 else (255, 255, 255) pygame.draw.circle(self.screen, color, (start_x + (i % 2) * self.peg_size * 2, start_y + (i // 2) * self.peg_size * 2), self.peg_size // 2) # Draw color palette for i, color in enumerate(self.colors.palette): x = self.width/2 + (i % 2) * self.cell_size + self.padding y = (i // 2) * self.cell_size + self.padding pygame.draw.rect(self.screen, color, (x, y, self.cell_size - self.padding, self.cell_size - self.padding)) if i == self.selected_color: pygame.draw.rect(self.screen, (255, 255, 255), (x, y, self.cell_size - self.padding, self.cell_size - self.padding), 3) # Draw game over if self.game_over: overlay = pygame.Surface((self.width, self.height)) overlay.fill((0, 0, 0)) overlay.set_alpha(178) # 70% opacity self.screen.blit(overlay, (0, 0)) # Draw game over message font = pygame.font.Font(None, 64) text = font.render('You Win!' if self.won else 'Game Over!', True, (255, 255, 255)) text_rect = text.get_rect( center=(self.width/2, self.height/2 - 50)) self.screen.blit(text, text_rect) # Show secret code font = pygame.font.Font(None, 36) text = font.render('Secret Code:', True, (255, 255, 255)) text_rect = text.get_rect(center=(self.width/2, self.height/2)) self.screen.blit(text, text_rect) for i, color_index in enumerate(self.secret_code): x = (self.width/2 - (self.cols * self.cell_size)/2 + i * self.cell_size + self.padding) y = self.height/2 + 20 pygame.draw.rect(self.screen, self.colors.palette[color_index], (x, y, self.cell_size - self.padding, self.cell_size - self.padding)) # Draw play again button pygame.draw.rect(self.screen, (0, 255, 0), (self.width/2 - 100, self.height - 50, 200, 40)) font = pygame.font.Font(None, 36) text = font.render('Play Again', True, (0, 0, 0)) text_rect = text.get_rect( center=(self.width/2, self.height - 30)) self.screen.blit(text, text_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 = MastermindGame() game.run()
Play Game