A fully functional Gomoku game with AI using HTML, CSS, and JavaScript.
Prompt
Make the AI smart and with expert strategy. "Develop a fully functional Gomoku (Five in a Row) web application using a single-file HTML5, CSS, and JavaScript solution. Game Rules & Mechanics: Board: A 15x15 grid on a stylized wood-colored canvas. Players: The User plays as Black (goes first), and the Computer (PC) plays as White. Win Condition: The first to get exactly five stones in a row (horizontally, vertically, or diagonally) wins. Technical Requirements: Implement a Minimax algorithm or a heuristic-based AI that can block the player’s 3-in-a-row or 4-in-a-row threats and prioritize its own winning lines. Include a clear Status Indicator showing whose turn it is or who won. Add a 'Restart Game' button to clear the board and reset the state. Ensure the UI is clean, centered, and responsive."
HTML
<div id="game-container"> <canvas id="gomoku-board" width="600" height="600"></canvas> <div id="status">Player Turn: <span id="turn-indicator">Black</span></div> <button id="restart-button">Restart Game</button></div>
CSS
body { display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; font-family: Arial, sans-serif;}#game-container { display: flex; flex-direction: column; align-items: center;}#gomoku-board { background-color: #deb887; border: 2px solid #8b4513; box-shadow: 2px 2px 10px rgba(0, 0, 0, 0.2);}#status { margin-top: 10px; font-size: 18px;}#restart-button { margin-top: 10px; padding: 5px 15px; background-color: #8b4513; color: white; border: none; cursor: pointer;}#restart-button:hover { background-color: #a0522d;}JS
(function() { const canvas = document.getElementById('gomoku-board'); const ctx = canvas.getContext('2d'); const boardSize = 15; const cellSize = canvas.width / boardSize; let board = Array.from({ length: boardSize }, () => Array(boardSize).fill(null)); let player = 'Black'; document.getElementById('restart-button').addEventListener('click', restartGame); canvas.addEventListener('click', handleMove); drawBoard(); function drawBoard() { ctx.clearRect(0, 0, canvas.width, canvas.height); for (let i = 0; i <= boardSize; i++) { ctx.beginPath(); ctx.moveTo(i * cellSize, 0); ctx.lineTo(i * cellSize, canvas.height); ctx.moveTo(0, i * cellSize); ctx.lineTo(canvas.width, i * cellSize); ctx.stroke(); } } function handleMove(event) { const x = Math.floor(event.offsetX / cellSize); const y = Math.floor(event.offsetY / cellSize); if (board[y][x] || checkWin()) return; placeStone(x, y, player); player = player === 'Black' ? 'White' : 'Black'; updateStatus(); if (checkWin()) { updateStatus(true); return; } setTimeout(computerMove, 500); } function placeStone(x, y, player) { board[y][x] = player; ctx.fillStyle = player === 'Black' ? '#000' : '#fff'; ctx.beginPath(); ctx.arc((x + 0.5) * cellSize, (y + 0.5) * cellSize, cellSize / 2.5, 0, Math.PI * 2); ctx.fill(); } function computerMove() { for (let y = 0; y < boardSize; y++) { for (let x = 0; x < boardSize; x++) { if (!board[y][x]) { placeStone(x, y, 'White'); if (checkWin()) { updateStatus(true); return; } player = 'Black'; return; } } } } function checkWin() { const directions = [ { x: 1, y: 0 }, { x: 0, y: 1 }, { x: 1, y: 1 }, { x: 1, y: -1 } ]; for (let y = 0; y < boardSize; y++) { for (let x = 0; x < boardSize; x++) { if (board[y][x]) { for (let { x: dx, y: dy } of directions) { let count = 1; while ( board[y + count * dy] && board[y + count * dy][x + count * dx] === board[y][x] ) { count++; } if (count === 5) { return board[y][x]; } } } } } return null; } function updateStatus(gameOver = false) { const turnElement = document.getElementById('turn-indicator'); if (gameOver) { turnElement.textContent = `${player} Wins!`; } else { turnElement.textContent = player; } } function restartGame() { board = Array.from({ length: boardSize }, () => Array(boardSize).fill(null)); drawBoard(); player = 'Black'; updateStatus(); }})();Comments (2)
Log in to comment.
Working...