Skip to content
This repository was archived by the owner on Jun 21, 2025. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Brno Scrum Workshop - Tic Tac Toe</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<header>
<h1>Brno Scrum Workshop</h1>
</header>

<main>
<section id="game">
<div id="board" class="board">
<!-- 9 cells will be generated by JS to keep markup clean -->
</div>
<div id="status" class="status">Player X's turn</div>
<button id="newGame" class="new-game">New Game</button>
</section>
</main>

<script src="script.js"></script>
</body>
</html>
84 changes: 84 additions & 0 deletions script.js
Original file line number Diff line number Diff line change
@@ -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();
});
89 changes: 89 additions & 0 deletions style.css
Original file line number Diff line number Diff line change
@@ -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;
}