Herzlich willkommen zum SELF-Treffen 2026
vom 24.04. – 26.04.2026
in Halle (Saale)
Beispiel:Tic-tac-toe-6.html
<!doctype html> <html lang="de"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" media="screen" href="./Beispiel:Grundlayout.css"> <title>Tic-Tac-Toe - 6</title> <style> .tic-tac-toe #gameboard {
width: 60vmin; height: 60vmin; display: grid; grid-template-columns: repeat(3, 1fr); gap: 0;
}
.tic-tac-toe button {
width: 20vmin; height: 20vmin; background: white; border: 1px solid black; margin: 0; font: 0/0 transparent;
}
.tic-tac-toe [aria-label="x"] {
background-image: url('data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%201%201%22%3E%3Cline%20x1%3D%220.1%22%20y1%3D%220.1%22%20x2%3D%220.9%22%20y2%3D%220.9%22%20stroke-width%3D%220.1%22%20stroke%3D%22red%22%2F%3E%3Cline%20x1%3D%220.1%22%20y1%3D%220.9%22%20x2%3D%220.9%22%20y2%3D%220.1%22%20stroke-width%3D%220.1%22%20stroke%3D%22red%22%2F%3E%3C%2Fsvg%3E');
}
.tic-tac-toe [aria-label="o"] {
background-image: url('data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%201%201%22%3E%3Ccircle%20cx%3D%220.5%22%20cy%3D%220.5%22%20r%3D%220.4%22%20fill%3D%22none%22%20stroke-width%3D%220.1%22%20stroke%3D%22blue%22%2F%3E%3C%2Fsvg%3E');
}
.tic-tac-toe .highlighted {
background-color: yellow;
}
.warning {
color: red;
}
.success {
color: green; background-color: yellow;
}
/* Dialog für "Neues Spiel?" */
- newgame-dialog {
display: none; position: fixed; inset: 0; background: rgba(0,0,0,0.4); justify-content: center; align-items: center; z-index: 10;
}
- newgame-dialog.visible {
display: flex;
}
- newgame-dialog > div {
background: white; border: 1px solid black; padding: 1.5em 2em; text-align: center;
}
- newgame-dialog p {
margin: 0 0 1em;
}
- newgame-dialog button {
width: auto; height: auto; font: inherit; padding: 0.4em 1.2em; margin: 0 0.4em; cursor: pointer;
} </style>
<script> 'use strict'; document.addEventListener('DOMContentLoaded', function () {
const gameboard = document.querySelector('#gameboard');
const hint = document.querySelector('#hint');
const dialog = document.querySelector('#newgame-dialog');
const btnYes = document.querySelector('#btn-yes');
const btnNo = document.querySelector('#btn-no');
const players = ['x', 'o']; let current = 0; let winner = null; let finished = false;
gameboard.addEventListener('click', markField);
function markField(e) {
if (finished) return;
const field = e.target; if (field.tagName !== 'BUTTON') return;
field.setAttribute('aria-label', players[current]);
field.setAttribute('disabled', 'disabled');
current = 1 - current;
hint.textContent = 'Spieler ' + players[current] + ' ist am Zug.';
hint.className = ;
checkIfCompleted(); }
function checkIfCompleted() {
const fields = gameboard.querySelectorAll('button');
// Gewinner ermitteln
for (let i = 0; i < 3; i++) {
// 3 senkrecht
if (fields[i].getAttribute('aria-label') !==
&& fields[i].getAttribute('aria-label') === fields[3 + i].getAttribute('aria-label')
&& fields[3 + i].getAttribute('aria-label') === fields[6 + i].getAttribute('aria-label')
) {
winner = fields[i].getAttribute('aria-label');
highlightCells([fields[i], fields[3 + i], fields[6 + i]]);
}
// 3 waagrecht
if (fields[i * 3].getAttribute('aria-label') !==
&& fields[i * 3].getAttribute('aria-label') === fields[i * 3 + 1].getAttribute('aria-label')
&& fields[i * 3 + 1].getAttribute('aria-label') === fields[i * 3 + 2].getAttribute('aria-label')
) {
winner = fields[i * 3].getAttribute('aria-label');
highlightCells([fields[i * 3], fields[i * 3 + 1], fields[i * 3 + 2]]);
}
}
// diagonal links oben nach rechts unten
if (fields[0].getAttribute('aria-label') !==
&& fields[0].getAttribute('aria-label') === fields[4].getAttribute('aria-label')
&& fields[4].getAttribute('aria-label') === fields[8].getAttribute('aria-label')
) {
winner = fields[0].getAttribute('aria-label');
highlightCells([fields[0], fields[4], fields[8]]);
}
// diagonal rechts oben nach links unten
if (fields[2].getAttribute('aria-label') !==
&& fields[2].getAttribute('aria-label') === fields[4].getAttribute('aria-label')
&& fields[4].getAttribute('aria-label') === fields[6].getAttribute('aria-label')
) {
winner = fields[2].getAttribute('aria-label');
highlightCells([fields[2], fields[4], fields[6]]);
}
// alle Felder belegt?
const full = Array.from(fields).every(f => f.hasAttribute('disabled'));
// Spiel vorbei?
if (winner || full) {
finished = true;
if (winner) {
hint.textContent = 'Das Spiel ist zu Ende, weil Spieler ' + winner + ' gewonnen hat!';
hint.className = 'success';
} else {
hint.textContent = 'Das Spiel endet unentschieden, weil alle Felder belegt sind.';
hint.className = 'warning';
}
dialog.classList.add('visible');
}
}
function highlightCells(cells) {
cells.forEach(cell => cell.classList.add('highlighted'));
}
function resetGame() {
const fields = gameboard.querySelectorAll('button');
fields.forEach(field => {
field.setAttribute('aria-label', );
field.removeAttribute('disabled');
field.classList.remove('highlighted');
field.style.backgroundImage = ;
});
current = 0;
winner = null;
finished = false;
hint.textContent = 'Zum Spielen bitte abwechselnd in die Spielfelder klicken/tappen!';
hint.className = ;
dialog.classList.remove('visible');
}
btnYes.addEventListener('click', resetGame);
btnNo.addEventListener('click', () => dialog.classList.remove('visible'));
}); </script> </head>
<body>
Tic-Tac-Toe 6 (Spielende 2)
Zum Spielen bitte abwechselnd in die Spielfelder klicken/tappen!
<button aria-label=""></button> <button aria-label=""></button> <button aria-label=""></button>
<button aria-label=""></button> <button aria-label=""></button> <button aria-label=""></button>
<button aria-label=""></button> <button aria-label=""></button> <button aria-label=""></button>
Neues Spiel?
<button id="btn-yes">Ja</button> <button id="btn-no">Nein</button>
</body> </html>