A single-page Gomoku game with a 15x15 board. The player plays as Black, and the computer as White, with a basic AI opponent.
Prompt
"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="gameContainer">
<canvas id="gameCanvas" width="600" height="600"></canvas>
<div id="statusIndicator">Turn: Player (Black)</div>
<button id="restartButton">Restart Game</button>
</div>CSS
body {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background-color: #f0f0f0;
margin: 0;
font-family: Arial, sans-serif;
}
#gameContainer {
text-align: center;
}
#gameCanvas {
background-color: #DEB887;
border: 1px solid #333;
display: block;
margin: 0 auto;
}
#statusIndicator {
margin-top: 10px;
font-size: 18px;
}
#restartButton {
margin-top: 10px;
padding: 10px 20px;
font-size: 16px;
cursor: pointer;
}JS
(function() {
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
const statusIndicator = document.getElementById('statusIndicator');
const restartButton = document.getElementById('restartButton');
const boardSize = 15;
const cellSize = canvas.width / boardSize;
const board = Array.from({ length: boardSize }, () => Array(boardSize).fill(null));
const player = 'black';
const computer = 'white';
let currentPlayer = player;
function drawBoard() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
for (let i = 0; i < boardSize; i++) {
for (let j = 0; j < boardSize; j++) {
ctx.strokeRect(i * cellSize, j * cellSize, cellSize, cellSize);
if (board[i][j]) drawStone(i, j, board[i][j]);
}
}
}
function drawStone(x, y, color) {
ctx.fillStyle = color;
ctx.beginPath();
ctx.arc((x + 0.5) * cellSize, (y + 0.5) * cellSize, cellSize / 2.5, 0, 2 * Math.PI);
ctx.fill();
ctx.closePath();
}
function handleClick(event) {
const { offsetX, offsetY } = event;
const x = Math.floor(offsetX / cellSize);
const y = Math.floor(offsetY / cellSize);
if (!board[x][y]) {
board[x][y] = currentPlayer;
drawBoard();
if (checkWin(x, y, currentPlayer)) {
statusIndicator.textContent = currentPlayer === player ? 'Player (Black) Wins!' : 'Computer (White) Wins!';
canvas.removeEventListener('click', handleClick);
return;
}
currentPlayer = currentPlayer === player ? computer : player;
statusIndicator.textContent = `Turn: ${currentPlayer === player ? 'Player (Black)' : 'Computer (White)'}`;
if (currentPlayer === computer) setTimeout(computerMove, 500);
}
}
function checkWin(x, y, color) {
return checkDirection(x, y, color, 1, 0) || // Horizontal
checkDirection(x, y, color, 0, 1) || // Vertical
checkDirection(x, y, color, 1, 1) || // Diagonal /
checkDirection(x, y, color, 1, -1); // Diagonal \
}
function checkDirection(x, y, color, dx, dy) {
let count = 1;
for (let sign of [-1, 1]) {
let step = 1;
while (true) {
const nx = x + sign * step * dx;
const ny = y + sign * step * dy;
if (nx >= 0 && nx < boardSize && ny >= 0 && ny < boardSize && board[nx][ny] === color) {
count++;
step++;
} else {
break;
}
}
}
return count >= 5;
}
function computerMove() {
// Placeholder simple AI - chooses random empty cell
let emptyCells = [];
for (let i = 0; i < boardSize; i++) {
for (let j = 0; j < boardSize; j++) {
if (!board[i][j]) emptyCells.push([i, j]);
}
}
const [x, y] = emptyCells[Math.floor(Math.random() * emptyCells.length)];
board[x][y] = computer;
drawBoard();
if (checkWin(x, y, computer)) {
statusIndicator.textContent = 'Computer (White) Wins!';
canvas.removeEventListener('click', handleClick);
return;
}
currentPlayer = player;
statusIndicator.textContent = 'Turn: Player (Black)';
}
function restartGame() {
for (let i = 0; i < boardSize; i++) {
for (let j = 0; j < boardSize; j++) {
board[i][j] = null;
}
}
currentPlayer = player;
statusIndicator.textContent = 'Turn: Player (Black)';
drawBoard();
canvas.addEventListener('click', handleClick);
}
canvas.addEventListener('click', handleClick);
restartButton.addEventListener('click', restartGame);
drawBoard();
})();Comments (0)
Log in to comment.
Working...