Mystery Game #4
← Back to Games List
// Tic-tac-toe Implementation
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
// Game state
let grid = [
['', '', ''],
['', '', ''],
['', '', '']
];
let currentPlayer = 'X';
let gameOver = false;
// Constants
const cellSize = 100;
const gridSize = 300;
const lineWidth = 4;
// Draw the grid
function drawGrid() {
// Clear canvas
ctx.fillStyle = 'white';
ctx.fillRect(0, 0, canvas.width, canvas.height);
// Draw grid lines
ctx.strokeStyle = 'black';
ctx.lineWidth = lineWidth;
// Vertical lines
ctx.beginPath();
ctx.moveTo(cellSize, 0);
ctx.lineTo(cellSize, gridSize);
ctx.moveTo(cellSize * 2, 0);
ctx.lineTo(cellSize * 2, gridSize);
ctx.stroke();
// Horizontal lines
ctx.beginPath();
ctx.moveTo(0, cellSize);
ctx.lineTo(gridSize, cellSize);
ctx.moveTo(0, cellSize * 2);
ctx.lineTo(gridSize, cellSize * 2);
ctx.stroke();
}
// Draw marker
function drawMarker(row, col) {
const symbol = grid[row][col];
const x = col * cellSize;
const y = row * cellSize;
ctx.strokeStyle = 'black';
ctx.lineWidth = lineWidth;
if (symbol === 'X') {
// Draw X
const padding = 20;
ctx.beginPath();
ctx.moveTo(x + padding, y + padding);
ctx.lineTo(x + cellSize - padding, y + cellSize - padding);
ctx.moveTo(x + cellSize - padding, y + padding);
ctx.lineTo(x + padding, y + cellSize - padding);
ctx.stroke();
} else if (symbol === 'O') {
// Draw O
const radius = cellSize/2 - 20;
ctx.beginPath();
ctx.arc(x + cellSize/2, y + cellSize/2, radius, 0, Math.PI * 2);
ctx.stroke();
}
}
// Handle mouse click
canvas.addEventListener('click', function(e) {
if (gameOver) return;
const rect = canvas.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
// Convert click to grid position
const row = Math.floor(y / cellSize);
const col = Math.floor(x / cellSize);
// Check if valid move
if (row >= 0 && row < 3 && col >= 0 && col < 3 && grid[row][col] === '') {
// Make move
grid[row][col] = currentPlayer;
drawMarker(row, col);
// Check for win
if (checkWin(currentPlayer)) {
gameOver = true;
drawWinMessage(currentPlayer + ' Wins!');
return;
}
// Check for draw
if (checkDraw()) {
gameOver = true;
drawWinMessage('Draw!');
return;
}
// Switch player
currentPlayer = currentPlayer === 'X' ? 'O' : 'X';
}
});
// Check for win
function checkWin(player) {
// Check rows
for (let i = 0; i < 3; i++) {
if (grid[i][0] === player &&
grid[i][1] === player &&
grid[i][2] === player) {
return true;
}
}
// Check columns
for (let i = 0; i < 3; i++) {
if (grid[0][i] === player &&
grid[1][i] === player &&
grid[2][i] === player) {
return true;
}
}
// Check diagonals
if (grid[0][0] === player &&
grid[1][1] === player &&
grid[2][2] === player) {
return true;
}
if (grid[0][2] === player &&
grid[1][1] === player &&
grid[2][0] === player) {
return true;
}
return false;
}
// Check for draw
function checkDraw() {
return grid.every(row => row.every(cell => cell !== ''));
}
// Draw win/draw message
function drawWinMessage(message) {
ctx.fillStyle = 'rgba(0, 0, 0, 0.7)';
ctx.fillRect(0, gridSize/2 - 30, gridSize, 60);
ctx.fillStyle = 'white';
ctx.font = '30px Arial';
ctx.textAlign = 'center';
ctx.fillText(message, gridSize/2, gridSize/2 + 10);
// Add restart button
const button = document.createElement('button');
button.textContent = 'Play Again';
button.style.marginTop = '20px';
button.onclick = function() {
location.reload();
};
canvas.parentElement.appendChild(button);
}
// Initialize game
drawGrid();
# Tic-tac-toe Implementation
import pygame
from typing import List, Tuple, Optional
class TicTacToe:
def __init__(self):
pygame.init()
self.cell_size = 100
self.grid_size = 300
self.line_width = 4
self.screen = pygame.display.set_mode((self.grid_size, self.grid_size))
pygame.display.set_caption('Tic-tac-toe')
self.grid: List[List[str]] = [
['', '', ''],
['', '', ''],
['', '', '']
]
self.current_player = 'X'
self.game_over = False
self.draw_grid()
pygame.display.flip()
def draw_grid(self):
# Clear screen
self.screen.fill((255, 255, 255))
# Draw grid lines
for i in range(1, 3):
# Vertical lines
pygame.draw.line(self.screen, (0, 0, 0),
(i * self.cell_size, 0),
(i * self.cell_size, self.grid_size),
self.line_width)
# Horizontal lines
pygame.draw.line(self.screen, (0, 0, 0),
(0, i * self.cell_size),
(self.grid_size, i * self.cell_size),
self.line_width)
def draw_marker(self, row: int, col: int):
symbol = self.grid[row][col]
x = col * self.cell_size
y = row * self.cell_size
if symbol == 'X':
# Draw X
padding = 20
pygame.draw.line(self.screen, (0, 0, 0),
(x + padding, y + padding),
(x + self.cell_size - padding,
y + self.cell_size - padding),
self.line_width)
pygame.draw.line(self.screen, (0, 0, 0),
(x + self.cell_size - padding, y + padding),
(x + padding, y + self.cell_size - padding),
self.line_width)
elif symbol == 'O':
# Draw O
radius = self.cell_size//2 - 20
center = (x + self.cell_size//2,
y + self.cell_size//2)
pygame.draw.circle(self.screen, (0, 0, 0),
center, radius, self.line_width)
def handle_click(self, pos: Tuple[int, int]) -> bool:
if self.game_over:
return False
# Convert click to grid position
col = pos[0] // self.cell_size
row = pos[1] // self.cell_size
# Check if valid move
if (row >= 0 and row < 3 and
col >= 0 and col < 3 and
self.grid[row][col] == ''):
# Make move
self.grid[row][col] = self.current_player
self.draw_marker(row, col)
# Check for win
if self.check_win(self.current_player):
self.game_over = True
self.draw_win_message(f'{self.current_player} Wins!')
return True
# Check for draw
if self.check_draw():
self.game_over = True
self.draw_win_message('Draw!')
return True
# Switch player
self.current_player = 'O' if self.current_player == 'X' else 'X'
return True
return False
def check_win(self, player: str) -> bool:
# Check rows
for i in range(3):
if (self.grid[i][0] == player and
self.grid[i][1] == player and
self.grid[i][2] == player):
return True
# Check columns
for i in range(3):
if (self.grid[0][i] == player and
self.grid[1][i] == player and
self.grid[2][i] == player):
return True
# Check diagonals
if (self.grid[0][0] == player and
self.grid[1][1] == player and
self.grid[2][2] == player):
return True
if (self.grid[0][2] == player and
self.grid[1][1] == player and
self.grid[2][0] == player):
return True
return False
def check_draw(self) -> bool:
return all(cell != '' for row in self.grid for cell in row)
def draw_win_message(self, message: str):
# Draw semi-transparent overlay
overlay = pygame.Surface((self.grid_size, 60))
overlay.fill((0, 0, 0))
overlay.set_alpha(178) # ~0.7 opacity
self.screen.blit(overlay,
(0, self.grid_size//2 - 30))
# Draw message
font = pygame.font.Font(None, 48)
text = font.render(message, True, (255, 255, 255))
text_rect = text.get_rect(
center=(self.grid_size//2,
self.grid_size//2 + 10))
self.screen.blit(text, text_rect)
def run(self):
clock = pygame.time.Clock()
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1: # Left click
self.handle_click(event.pos)
elif (event.type == pygame.KEYDOWN and
event.key == pygame.K_r and
self.game_over):
# Reset game
self.__init__()
pygame.display.flip()
clock.tick(60)
pygame.quit()
if __name__ == '__main__':
game = TicTacToe()
game.run()
Play Game