diff --git a/index.html b/index.html new file mode 100644 index 0000000..688f489 --- /dev/null +++ b/index.html @@ -0,0 +1,26 @@ + + + + + + Brno Scrum Workshop - Tic Tac Toe + + + +
+

Brno Scrum Workshop

+
+ +
+
+
+ +
+
Player X's turn
+ +
+
+ + + + diff --git a/script.js b/script.js new file mode 100644 index 0000000..fc3b9c7 --- /dev/null +++ b/script.js @@ -0,0 +1,84 @@ +document.addEventListener("DOMContentLoaded", () => { + const boardElement = document.getElementById("board"); + const statusElement = document.getElementById("status"); + const newGameButton = document.getElementById("newGame"); + + let board; // array of 9 elements ("", "X", "O") + let currentPlayer; + let gameActive; + + function initBoard() { + boardElement.innerHTML = ""; + for (let i = 0; i < 9; i++) { + const cell = document.createElement("div"); + cell.classList.add("cell"); + cell.dataset.index = i; + cell.addEventListener("click", () => handleCellClick(i)); + boardElement.appendChild(cell); + } + } + + function startGame() { + board = Array(9).fill(""); + currentPlayer = "X"; + gameActive = true; + updateStatus(`Player ${currentPlayer}'s turn`); + render(); + } + + function handleCellClick(index) { + if (!gameActive || board[index] !== "") return; + board[index] = currentPlayer; + render(); + + const winner = checkWinner(); + if (winner) { + updateStatus(`Player ${winner} wins! 🎉`); + gameActive = false; + } else if (board.every((cell) => cell !== "")) { + updateStatus("It's a draw! 🤝"); + gameActive = false; + } else { + currentPlayer = currentPlayer === "X" ? "O" : "X"; + updateStatus(`Player ${currentPlayer}'s turn`); + } + } + + function checkWinner() { + const winConditions = [ + [0, 1, 2], + [3, 4, 5], + [6, 7, 8], + [0, 3, 6], + [1, 4, 7], + [2, 5, 8], + [0, 4, 8], + [2, 4, 6], + ]; + + for (const [a, b, c] of winConditions) { + if (board[a] && board[a] === board[b] && board[a] === board[c]) { + return board[a]; + } + } + return null; + } + + function render() { + const cellDivs = boardElement.querySelectorAll(".cell"); + cellDivs.forEach((cellDiv, idx) => { + cellDiv.textContent = board[idx]; + }); + } + + function updateStatus(message) { + statusElement.textContent = message; + } + + // Event Listeners + newGameButton.addEventListener("click", startGame); + + // Initialize + initBoard(); + startGame(); +}); diff --git a/style.css b/style.css new file mode 100644 index 0000000..e38b7f6 --- /dev/null +++ b/style.css @@ -0,0 +1,89 @@ +/* Global styles */ +* { + box-sizing: border-box; + margin: 0; + padding: 0; + font-family: Arial, Helvetica, sans-serif; +} + +body { + background: linear-gradient(135deg, #ff9a9e 0%, #fad0c4 100%); + min-height: 100vh; + display: flex; + flex-direction: column; + align-items: center; + justify-content: flex-start; + color: #333; +} + +header { + padding: 2rem 0 1rem; + text-align: center; +} + +header h1 { + font-size: 2.5rem; + color: #fff; + text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3); +} + +main { + width: 100%; + max-width: 450px; + display: flex; + flex-direction: column; + align-items: center; +} + +.board { + display: grid; + grid-template-columns: repeat(3, 1fr); + grid-template-rows: repeat(3, 1fr); + gap: 5px; + width: 100%; + max-width: 450px; + aspect-ratio: 1 / 1; + margin-bottom: 1rem; +} + +.cell { + background-color: rgba(255, 255, 255, 0.8); + border-radius: 8px; + display: flex; + align-items: center; + justify-content: center; + font-size: 3rem; + font-weight: bold; + cursor: pointer; + transition: background-color 0.2s ease; +} + +.cell:hover { + background-color: rgba(255, 255, 255, 1); +} + +.status { + font-size: 1.2rem; + margin-bottom: 1rem; + height: 1.5rem; + text-align: center; + color: #fff; + text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3); +} + +.new-game { + padding: 0.75rem 1.5rem; + border: none; + border-radius: 6px; + background-color: #4CAF50; + color: #fff; + font-size: 1rem; + font-weight: bold; + cursor: pointer; + transition: background-color 0.2s ease; + margin-bottom: 2rem; +} + +.new-game:hover { + background-color: #45a049; +}