feat: initial tictactoe web app with CI/CD pipeline
Some checks failed
homelab-k8s-services/tictactoe/pipeline/head There was a failure building this commit
Some checks failed
homelab-k8s-services/tictactoe/pipeline/head There was a failure building this commit
- Express app serving vanilla JS 2-player TicTacToe game - Dockerfile (multi-stage node:18-slim) - Jenkinsfile (K8s pod: test → Harbor push → Helm bump → Gitea push) - Helm chart v1.0.0 with HTTPRoute for tictactoe.fireflylab.local Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
61
public/game.js
Normal file
61
public/game.js
Normal file
@@ -0,0 +1,61 @@
|
||||
(function () {
|
||||
const WINS = [
|
||||
[0,1,2],[3,4,5],[6,7,8],
|
||||
[0,3,6],[1,4,7],[2,5,8],
|
||||
[0,4,8],[2,4,6]
|
||||
];
|
||||
|
||||
let board, current, over;
|
||||
const cells = document.querySelectorAll('.cell');
|
||||
const status = document.getElementById('status');
|
||||
const resetBtn = document.getElementById('reset');
|
||||
|
||||
function init() {
|
||||
board = Array(9).fill(null);
|
||||
current = 'X';
|
||||
over = false;
|
||||
cells.forEach(c => {
|
||||
c.textContent = '';
|
||||
c.className = 'cell';
|
||||
});
|
||||
status.textContent = "Player X's turn";
|
||||
}
|
||||
|
||||
function checkWinner() {
|
||||
for (const [a, b, c] of WINS) {
|
||||
if (board[a] && board[a] === board[b] && board[a] === board[c]) {
|
||||
return { winner: board[a], line: [a, b, c] };
|
||||
}
|
||||
}
|
||||
return board.every(Boolean) ? { winner: null, draw: true } : null;
|
||||
}
|
||||
|
||||
function handleClick(e) {
|
||||
const idx = parseInt(e.target.dataset.index);
|
||||
if (over || board[idx]) return;
|
||||
|
||||
board[idx] = current;
|
||||
const cell = cells[idx];
|
||||
cell.textContent = current;
|
||||
cell.classList.add('taken', current.toLowerCase());
|
||||
|
||||
const result = checkWinner();
|
||||
if (result) {
|
||||
over = true;
|
||||
if (result.draw) {
|
||||
status.textContent = "It's a draw!";
|
||||
} else {
|
||||
result.line.forEach(i => cells[i].classList.add('winner'));
|
||||
status.textContent = `Player ${result.winner} wins!`;
|
||||
}
|
||||
} else {
|
||||
current = current === 'X' ? 'O' : 'X';
|
||||
status.textContent = `Player ${current}'s turn`;
|
||||
}
|
||||
}
|
||||
|
||||
cells.forEach(c => c.addEventListener('click', handleClick));
|
||||
resetBtn.addEventListener('click', init);
|
||||
|
||||
init();
|
||||
})();
|
||||
Reference in New Issue
Block a user