diff options
| author | Leo Goetz <dev@leogtz.de> | 2026-03-21 16:16:36 +0100 |
|---|---|---|
| committer | Leo Goetz <dev@leogtz.de> | 2026-03-21 16:16:36 +0100 |
| commit | 82969cac5d6f9626bef681ef7d5cea60ed686eb0 (patch) | |
| tree | e5a110d2d6de0e47f65802d073f570ca4d5aacef | |
| -rw-r--r-- | LICENSE | 21 | ||||
| -rw-r--r-- | README.md | 14 | ||||
| -rw-r--r-- | git-daemon-export-ok | 0 | ||||
| -rw-r--r-- | index.js | 3 | ||||
| -rw-r--r-- | package.json | 13 | ||||
| -rw-r--r-- | src/game.js | 118 | ||||
| -rw-r--r-- | src/utils.js | 14 |
7 files changed, 183 insertions, 0 deletions
@@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Leo Goetz + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..44f95da --- /dev/null +++ b/README.md @@ -0,0 +1,14 @@ +Tic Tac Toe +--- + +Like the name says. It is a little Tic Tac Toe game you can play in your +terminal via node.js + +Just clone the repo, go in its directory and type: +```bash +npm run start +// or +node index.js +``` + +Enjoy :) diff --git a/git-daemon-export-ok b/git-daemon-export-ok new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/git-daemon-export-ok diff --git a/index.js b/index.js new file mode 100644 index 0000000..df235b2 --- /dev/null +++ b/index.js @@ -0,0 +1,3 @@ +import start from "./src/game.js"; + +await start(); diff --git a/package.json b/package.json new file mode 100644 index 0000000..9cb3d75 --- /dev/null +++ b/package.json @@ -0,0 +1,13 @@ +{ + "name": "tic-tac-toe", + "version": "1.0.0", + "description": "a terminal tic tac toe game", + "main": "index.js", + "scripts": { + "start": "node index.js" + }, + "keywords": [], + "author": "Leo Goetz", + "license": "MIT", + "type": "module" +} diff --git a/src/game.js b/src/game.js new file mode 100644 index 0000000..0820f8c --- /dev/null +++ b/src/game.js @@ -0,0 +1,118 @@ +import { getInput } from "./utils.js"; + +let game = { + player1: { + symbol: "X", + name: undefined, + }, + player2: { + symbol: "O", + name: undefined, + }, + turn: "player1", + state: "setup", + board: [" ", " ", " ", " ", " ", " ", " ", " ", " "], +}; + +const winningPositions = [ + [0, 1, 2], + [0, 3, 6], + [0, 4, 8], + [1, 4, 7], + [2, 5, 8], + [2, 4, 6], + [3, 4, 5], + [6, 7, 8], +]; + +function checkForWin() { + let winner = ""; + for (let position of winningPositions) { + if ( + // ignore field empty + game.board[position[0]] != " " && + game.board[position[1]] != " " && + game.board[position[2]] != " " && + // check if three in a row + game.board[position[0]] == game.board[position[1]] && + game.board[position[1]] == game.board[position[2]] + ) { + winner = + game.player1.symbol == game.board[position[0]] + ? game.player1.name + : game.player2.name; + } + } + return winner; +} + +async function gameLoop() { + while (game.state == "running") { + outputBoard(); + + let winner = checkForWin(); + if (winner) { + console.log(`${winner} has won!`); + game.state = "finish"; + return; + } + + await questionLoop(); + } + + async function questionLoop() { + let playerMove = await getInput( + `Where would you want to place (${game[game.turn].name})?: `, + ); + + while (game.board[playerMove - 1] != " ") { + console.log("\nThere is already a Symbol. Try again."); + playerMove = await getInput( + `Where would you want to place (${game[game.turn].name})?: `, + ); + } + + if (game.turn == "player2") { + move(game.player2, playerMove); + game.turn = "player1"; + } else { + move(game.player1, playerMove); + game.turn = "player2"; + } + } +} + +async function setupGame() { + console.log("Let's Start a Game of Tic Tac Toe! \n"); + game.player1.name = await getInput("Name of Player 1: "); + game.player2.name = await getInput("Name of Player 2: "); + game.state = "running"; +} + +function move(player, position) { + game.board[position - 1] = player.symbol; +} + +export default async function start() { + if (game.state == "setup") { + await setupGame(); + } + + if (game.state == "running") { + await gameLoop(); + } + + if (game.state == "finish") { + process.exit(); + } +} + +function outputBoard() { + console.log("\n"); + console.log(`${game.board[0]} | ${game.board[1]} | ${game.board[2]}`); + console.log("---------"); + console.log(`${game.board[3]} | ${game.board[4]} | ${game.board[5]}`); + console.log("---------"); + console.log(`${game.board[6]} | ${game.board[7]} | ${game.board[8]}`); + console.log("\n"); +} diff --git a/src/utils.js b/src/utils.js new file mode 100644 index 0000000..ecb2c4a --- /dev/null +++ b/src/utils.js @@ -0,0 +1,14 @@ +import readline from "readline"; + +const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout, +}); + +export function getInput(question) { + return new Promise((resolve) => { + rl.question(question, (userInput) => { + resolve(userInput); + }); + }); +} |
