Mystery Game #8

← Back to Games List
// Simon Says Game Implementation const canvas = document.getElementById('gameCanvas'); const ctx = canvas.getContext('2d'); // Game settings const centerX = canvas.width / 2; const centerY = canvas.height / 2; const radius = 150; const buttonRadius = radius * 0.8; const colors = ['red', 'blue', 'green', 'yellow']; const brightColors = ['#ff6666', '#6666ff', '#66ff66', '#ffff66']; const tones = [329.63, 261.63, 392.00, 196.00]; // E4, C4, G4, G3 // Game state let sequence = []; let playerSequence = []; let gameStarted = false; let playerTurn = false; let currentIndex = 0; let score = 0; let highlightedButton = -1; let audioContext = null; // Calculate button positions const buttons = colors.map((color, index) => { const angle = (index * Math.PI / 2) + Math.PI / 4; return { x: centerX + Math.cos(angle) * radius * 0.5, y: centerY + Math.sin(angle) * radius * 0.5, color: color, brightColor: brightColors[index], tone: tones[index] }; }); // Handle mouse click canvas.addEventListener('click', function(e) { if (!gameStarted) { startGame(); return; } if (!playerTurn) return; const rect = canvas.getBoundingClientRect(); const clickX = e.clientX - rect.left; const clickY = e.clientY - rect.top; // Check which button was clicked buttons.forEach((button, index) => { const dx = clickX - button.x; const dy = clickY - button.y; if (dx * dx + dy * dy < buttonRadius * buttonRadius) { playerClick(index); } }); }); function startGame() { // Initialize audio context if (!audioContext) { audioContext = new (window.AudioContext || window.webkitAudioContext)(); } sequence = []; playerSequence = []; gameStarted = true; playerTurn = false; currentIndex = 0; score = 0; addToSequence(); } function addToSequence() { sequence.push(Math.floor(Math.random() * 4)); playerSequence = []; currentIndex = 0; playerTurn = false; playSequence(); } function playSequence() { if (currentIndex < sequence.length) { highlightedButton = sequence[currentIndex]; playTone(buttons[highlightedButton].tone); setTimeout(() => { highlightedButton = -1; setTimeout(() => { currentIndex++; playSequence(); }, 200); }, 500); } else { playerTurn = true; currentIndex = 0; } } function playerClick(buttonIndex) { if (!playerTurn) return; highlightedButton = buttonIndex; playTone(buttons[buttonIndex].tone); playerSequence.push(buttonIndex); setTimeout(() => { highlightedButton = -1; // Check if the move was correct if (buttonIndex !== sequence[currentIndex]) { gameOver(); return; } currentIndex++; // Check if sequence is complete if (currentIndex === sequence.length) { score++; setTimeout(addToSequence, 1000); } }, 200); } function playTone(frequency) { const oscillator = audioContext.createOscillator(); const gainNode = audioContext.createGain(); oscillator.connect(gainNode); gainNode.connect(audioContext.destination); oscillator.type = 'sine'; oscillator.frequency.value = frequency; gainNode.gain.setValueAtTime(0, audioContext.currentTime); gainNode.gain.linearRampToValueAtTime(0.5, audioContext.currentTime + 0.01); gainNode.gain.linearRampToValueAtTime(0, audioContext.currentTime + 0.3); oscillator.start(audioContext.currentTime); oscillator.stop(audioContext.currentTime + 0.3); } function gameOver() { gameStarted = false; playerTurn = false; } function draw() { // Clear canvas ctx.fillStyle = 'black'; ctx.fillRect(0, 0, canvas.width, canvas.height); // Draw buttons buttons.forEach((button, index) => { ctx.beginPath(); ctx.arc(button.x, button.y, buttonRadius, 0, Math.PI * 2); ctx.fillStyle = index === highlightedButton ? button.brightColor : button.color; ctx.fill(); ctx.strokeStyle = 'white'; ctx.lineWidth = 2; ctx.stroke(); }); // Draw score ctx.fillStyle = 'white'; ctx.font = '24px Arial'; ctx.textAlign = 'center'; ctx.fillText('Score: ' + score, centerX, 30); // Draw game state message if (!gameStarted) { ctx.fillStyle = 'rgba(0, 0, 0, 0.7)'; ctx.fillRect(0, 0, canvas.width, canvas.height); ctx.fillStyle = 'white'; ctx.font = '30px Arial'; if (score === 0) { ctx.fillText('Click to Start!', centerX, centerY); } else { ctx.fillText('Game Over!', centerX, centerY - 20); ctx.font = '24px Arial'; ctx.fillText('Final Score: ' + score, centerX, centerY + 20); ctx.fillText('Click to Play Again', centerX, centerY + 60); } } } // Game loop function gameLoop() { draw(); requestAnimationFrame(gameLoop); } // Initialize canvas size canvas.width = 500; canvas.height = 500; // Start game loop gameLoop();
# Simon Says Game Implementation import pygame import random import math from dataclasses import dataclass from typing import List, Tuple @dataclass class Button: x: int y: int color: Tuple[int, int, int] bright_color: Tuple[int, int, int] tone_freq: float sound: pygame.mixer.Sound = None class SimonGame: def __init__(self): pygame.init() pygame.mixer.init() # Game settings self.width = 500 self.height = 500 self.center_x = self.width // 2 self.center_y = self.height // 2 self.radius = 150 self.button_radius = self.radius * 0.8 # Initialize display self.screen = pygame.display.set_mode((self.width, self.height)) pygame.display.set_caption('Simon Says') self.clock = pygame.time.Clock() # Colors and tones self.colors = [ ((255, 0, 0), (255, 102, 102), 329.63), # Red, E4 ((0, 0, 255), (102, 102, 255), 261.63), # Blue, C4 ((0, 255, 0), (102, 255, 102), 392.00), # Green, G4 ((255, 255, 0), (255, 255, 102), 196.00) # Yellow, G3 ] # Create buttons self.buttons = self.create_buttons() # Game state self.sequence: List[int] = [] self.player_sequence: List[int] = [] self.game_started = False self.player_turn = False self.current_index = 0 self.score = 0 self.highlighted_button = -1 # Generate tone sounds self.generate_sounds() def create_buttons(self) -> List[Button]: buttons = [] for i, (color, bright_color, tone) in enumerate(self.colors): angle = (i * math.pi / 2) + math.pi / 4 x = self.center_x + math.cos(angle) * self.radius * 0.5 y = self.center_y + math.sin(angle) * self.radius * 0.5 buttons.append(Button(x, y, color, bright_color, tone)) return buttons def generate_sounds(self): sample_rate = 44100 duration = 0.3 # seconds for button in self.buttons: # Generate a sine wave samples = [] for i in range(int(duration * sample_rate)): t = i / sample_rate amplitude = max(0, 1 - t/duration) # Linear fade out sample = int(32767 * amplitude * math.sin(2 * math.pi * button.tone_freq * t)) samples.append(sample) # Convert to pygame sound sound_array = bytes(samples) button.sound = pygame.mixer.Sound(buffer=sound_array) def handle_input(self) -> bool: for event in pygame.event.get(): if event.type == pygame.QUIT: return False if event.type == pygame.MOUSEBUTTONDOWN: if not self.game_started: self.start_game() elif self.player_turn: self.handle_click(event.pos) return True def handle_click(self, pos: Tuple[int, int]): x, y = pos for i, button in enumerate(self.buttons): dx = x - button.x dy = y - button.y if dx * dx + dy * dy < self.button_radius * self.button_radius: self.player_click(i) break def start_game(self): self.sequence = [] self.player_sequence = [] self.game_started = True self.player_turn = False self.current_index = 0 self.score = 0 self.add_to_sequence() def add_to_sequence(self): self.sequence.append(random.randint(0, 3)) self.player_sequence = [] self.current_index = 0 self.player_turn = False pygame.time.set_timer(pygame.USEREVENT, 1000) # Start sequence playback def play_sequence(self): if self.current_index < len(self.sequence): self.highlighted_button = self.sequence[self.current_index] self.buttons[self.highlighted_button].sound.play() pygame.time.set_timer(pygame.USEREVENT + 1, 500) # Button off timer else: self.player_turn = True self.current_index = 0 pygame.time.set_timer(pygame.USEREVENT, 0) # Stop sequence playback def player_click(self, button_index: int): if not self.player_turn: return self.highlighted_button = button_index self.buttons[button_index].sound.play() self.player_sequence.append(button_index) pygame.time.set_timer(pygame.USEREVENT + 1, 200) # Button off timer # Check if move was correct if button_index != self.sequence[self.current_index]: self.game_over() return self.current_index += 1 # Check if sequence is complete if self.current_index == len(self.sequence): self.score += 1 pygame.time.set_timer(pygame.USEREVENT, 1000) # Start next sequence def game_over(self): self.game_started = False self.player_turn = False pygame.time.set_timer(pygame.USEREVENT, 0) def draw(self): # Clear screen self.screen.fill((0, 0, 0)) # Draw buttons for i, button in enumerate(self.buttons): color = button.bright_color if i == self.highlighted_button else button.color pygame.draw.circle(self.screen, color, (int(button.x), int(button.y)), int(self.button_radius)) pygame.draw.circle(self.screen, (255, 255, 255), (int(button.x), int(button.y)), int(self.button_radius), 2) # Draw score font = pygame.font.Font(None, 36) score_text = font.render(f'Score: {self.score}', True, (255, 255, 255)) score_rect = score_text.get_rect(center=(self.center_x, 30)) self.screen.blit(score_text, score_rect) # Draw game state message if not self.game_started: overlay = pygame.Surface((self.width, self.height)) overlay.fill((0, 0, 0)) overlay.set_alpha(178) # 70% opacity self.screen.blit(overlay, (0, 0)) if self.score == 0: text = font.render('Click to Start!', True, (255, 255, 255)) text_rect = text.get_rect(center=(self.center_x, self.center_y)) self.screen.blit(text, text_rect) else: game_over = font.render('Game Over!', True, (255, 255, 255)) game_over_rect = game_over.get_rect( center=(self.center_x, self.center_y - 20)) self.screen.blit(game_over, game_over_rect) score = font.render(f'Final Score: {self.score}', True, (255, 255, 255)) score_rect = score.get_rect( center=(self.center_x, self.center_y + 20)) self.screen.blit(score, score_rect) play_again = font.render('Click to Play Again', True, (255, 255, 255)) play_again_rect = play_again.get_rect( center=(self.center_x, self.center_y + 60)) self.screen.blit(play_again, play_again_rect) pygame.display.flip() def run(self): running = True while running: running = self.handle_input() for event in pygame.event.get(): if event.type == pygame.USEREVENT: # Sequence playback self.play_sequence() elif event.type == pygame.USEREVENT + 1: # Button off timer self.highlighted_button = -1 pygame.time.set_timer(pygame.USEREVENT + 1, 0) self.draw() self.clock.tick(60) pygame.quit() if __name__ == '__main__': game = SimonGame() game.run()
Play Game