/*
A simple Tic‑Tac‑Toe game written in JavaScript (Node.js).
Highlights:
- The board is represented as an array of 9 characters.
- Functions handle printing, move validation, win checking,
and turn progression.
- The game loop is clear and easy to follow.
- Comments explain the reasoning behind each part of the program.
*/
const readline = require("readline");
// Create a small input helper for clean user prompts
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
//---------------------------------------------------------------
// Print the board in a 3×3 layout
//---------------------------------------------------------------
function printBoard(board) {
console.log();
for (let i = 0; i < 9; i++) {
process.stdout.write(board[i]);
if ((i + 1) % 3 === 0) {
console.log();
} else {
process.stdout.write(" | ");
}
}
console.log();
}
//---------------------------------------------------------------
// Check if a player has won
//---------------------------------------------------------------
function checkWin(board, player) {
const wins = [
[0,1,2], [3,4,5], [6,7,8], // rows
[0,3,6], [1,4,7], [2,5,8], // columns
[0,4,8], [2,4,6] // diagonals
];
for (const [a, b, c] of wins) {
if (board[a] === player &&
board[b] === player &&
board[c] === player) {
return true;
}
}
return false;
}
//---------------------------------------------------------------
// Check if the board is full (draw)
//---------------------------------------------------------------
function boardFull(board) {
return board.every(c => c !== " ");
}
//---------------------------------------------------------------
// Attempt to place a move; return true if successful
//---------------------------------------------------------------
function placeMove(board, pos, player) {
if (pos < 0 || pos >= 9) return false;
if (board[pos] !== " ") return false;
board[pos] = player;
return true;
}
//---------------------------------------------------------------
// Main game loop
//---------------------------------------------------------------
function main() {
const board = Array(9).fill(" ");
let currentPlayer = "X";
console.log("Tic‑Tac‑Toe");
printBoard(board);
function nextTurn() {
rl.question(`Player ${currentPlayer}, enter position (0‑8): `, input => {
const pos = Number(input);
if (!Number.isInteger(pos)) {
console.log("Invalid input. Try again.");
return nextTurn();
}
if (!placeMove(board, pos, currentPlayer)) {
console.log("Invalid move. Try again.");
return nextTurn();
}
printBoard(board);
if (checkWin(board, currentPlayer)) {
console.log(`Player ${currentPlayer} wins!`);
rl.close();
return;
}
if (boardFull(board)) {
console.log("It's a draw!");
rl.close();
return;
}
currentPlayer = currentPlayer === "X" ? "O" : "X";
nextTurn();
});
}
nextTurn();
}
main();
/*
run:
Tic‑Tac‑Toe
| |
| |
| |
Player X, enter position (0‑8): 5
| |
| | X
| |
Player O, enter position (0‑8): 0
O | |
| | X
| |
Player X, enter position (0‑8): 4
O | |
| X | X
| |
Player O, enter position (0‑8): 3
O | |
O | X | X
| |
Player X, enter position (0‑8): 6
O | |
O | X | X
X | |
Player O, enter position (0‑8): 3
Invalid move. Try again.
Player O, enter position (0‑8): 2
O | | O
O | X | X
X | |
Player X, enter position (0‑8): 7
O | | O
O | X | X
X | X |
Player O, enter position (0‑8): 1
O | O | O
O | X | X
X | X |
Player O wins!
*/