❌ Tic Tac Toe – JavaScript Spiel programmieren

In dieser Anleitung lernst du Schritt fĂĽr Schritt, wie du das bekannte Tic Tac Toe (Drei gewinnt) Spiel in JavaScript programmierst. Du baust ein Spiel fĂĽr zwei Spieler, bei dem abwechselnd X und O gesetzt werden.

📝 Was du brauchst:
âś… Einen Texteditor (z.B. Notepad, VS Code, oder direkt hier im Browser)
âś… Einen Webbrowser (Chrome, Firefox, Safari)
âś… Etwas Geduld und SpaĂź am Programmieren!

🎯 Das fertige Spiel – mit KI zum Ausprobieren!

Klicke auf "Gegen Computer" und fordere die KI heraus!

❌⭕ TIC TAC TOE Demo mit KI

❌ Spieler X ist dran
Schwierigkeit:
❌ Du ⭕ Computer Klicke auf ein Feld zum Setzen

📚 Schritt-für-Schritt Anleitung

Kopiere den Code aus jedem Schritt in deine Datei und teste ihn!

1

HTML-GrundgerĂĽst erstellen

Erstelle eine neue Datei mit dem Namen tictactoe.html auf deinem Desktop. FĂĽge dieses GrundgerĂĽst ein:

<!DOCTYPE html> <html> <head> <title>Tic Tac Toe</title> <style> body { display: flex; justify-content: center; align-items: center; height: 100vh; background: #1a1a2e; font-family: Arial, sans-serif; } .board { display: grid; grid-template-columns: repeat(3, 100px); gap: 5px; } .cell { width: 100px; height: 100px; background: #2d2d44; border: 2px solid #4a4a6a; border-radius: 10px; font-size: 50px; display: flex; align-items: center; justify-content: center; cursor: pointer; color: white; font-weight: bold; } .cell:hover { background: #3d3d5a; } .status { color: white; font-size: 24px; text-align: center; margin-top: 20px; } .reset { display: block; margin: 20px auto; padding: 10px 30px; background: #ff6b6b; border: none; border-radius: 10px; color: white; font-size: 18px; cursor: pointer; } </style> </head> <body> <div> <div class="board" id="board"> <div class="cell" data-index="0"></div> <div class="cell" data-index="1"></div> <div class="cell" data-index="2"></div> <div class="cell" data-index="3"></div> <div class="cell" data-index="4"></div> <div class="cell" data-index="5"></div> <div class="cell" data-index="6"></div> <div class="cell" data-index="7"></div> <div class="cell" data-index="8"></div> </div> <div class="status" id="status">Spieler X ist dran</div> <button class="reset" id="reset">🔄 Neues Spiel</button> </div> <script> // Hier kommt später der JavaScript-Code rein console.log("Tic Tac Toe geladen!"); </script> </body> </html>
✅ Teste es! Öffne die Datei im Browser. Du solltest ein leeres Spielfeld mit 9 Kästchen sehen.
2

JavaScript – Spielvariablen und Felder verwalten

Ersetze den Inhalt von <script> mit diesem Code:

// ====== 1. DOM-Elemente holen ====== const cells = document.querySelectorAll('.cell'); const statusDisplay = document.getElementById('status'); const resetButton = document.getElementById('reset'); // ====== 2. Spielvariablen ====== let board = ['', '', '', '', '', '', '', '', '']; let currentPlayer = 'X'; let gameActive = true; // ====== 3. Gewinnkombinationen ====== const winConditions = [ [0, 1, 2], [3, 4, 5], [6, 7, 8], // Waagerecht [0, 3, 6], [1, 4, 7], [2, 5, 8], // Senkrecht [0, 4, 8], [2, 4, 6] // Diagonal ]; // ====== 4. Status anzeigen ====== function updateStatus() { statusDisplay.textContent = gameActive ? `Spieler ${currentPlayer} ist dran` : `Spiel vorbei!`; } updateStatus(); console.log('âś… Spiel geladen! Spieler X beginnt.');
âś… Teste es! In der Konsole (F12) siehst du "Spiel geladen! Spieler X beginnt." Der Status zeigt "Spieler X ist dran".
💡 Erklärung: board speichert den Zustand aller 9 Felder. currentPlayer wechselt zwischen X und O. winConditions enthält alle 8 möglichen Gewinnlinien.
3

Klick-Event und Spielzug ausfĂĽhren

FĂĽge diesen Code hinzu (nach den Variablen):

// ====== 5. Spielzug ausführen ====== function handleCellClick(index) { // Prüfen ob Feld leer ist und Spiel aktiv ist if (board[index] !== '' || !gameActive) { return; } // Feld belegen board[index] = currentPlayer; cells[index].textContent = currentPlayer; cells[index].classList.add(currentPlayer.toLowerCase()); // Prüfen ob jemand gewonnen hat const winner = checkWinner(); if (winner) { statusDisplay.textContent = `🎉 Spieler ${winner} hat gewonnen!`; gameActive = false; return; } // Prüfen ob Unentschieden if (board.every(cell => cell !== '')) { statusDisplay.textContent = '🤝 Unentschieden!'; gameActive = false; return; } // Spieler wechseln currentPlayer = currentPlayer === 'X' ? 'O' : 'X'; updateStatus(); } // ====== 6. Klick-Listener für alle Felder ====== cells.forEach(cell => { cell.addEventListener('click', () => { const index = parseInt(cell.dataset.index); handleCellClick(index); }); });
✅ Teste es! Klicke auf ein Feld – es erscheint ein X! Klicke auf ein anderes Feld – es erscheint ein O!
4

Gewinner prĂĽfen und Reset-Button

FĂĽge diesen Code hinzu:

// ====== 7. Gewinner prüfen ====== function checkWinner() { for (let condition of winConditions) { const [a, b, c] = condition; if (board[a] && board[a] === board[b] && board[a] === board[c]) { // Gewinner-Felder hervorheben cells[a].classList.add('winner'); cells[b].classList.add('winner'); cells[c].classList.add('winner'); return board[a]; } } return null; } // ====== 8. Spiel zurücksetzen ====== function resetGame() { board = ['', '', '', '', '', '', '', '', '']; currentPlayer = 'X'; gameActive = true; cells.forEach(cell => { cell.textContent = ''; cell.classList.remove('x', 'o', 'winner'); }); updateStatus(); console.log('🔄 Spiel zurückgesetzt!'); } // ====== 9. Reset-Button ====== resetButton.addEventListener('click', resetGame);
✅ Teste es! Spiele eine Runde zu Ende – der Gewinner wird angezeigt! Klicke auf "Neues Spiel" – das Spielfeld wird zurückgesetzt!
💡 Erklärung: checkWinner() prüft alle 8 Gewinnlinien. Bei einem Gewinn werden die Felder mit der CSS-Klasse "winner" hervorgehoben. resetGame() setzt das komplette Spiel zurück.

đź“‹ Kompletter Code mit KI-Gegner

Hier ist der ganze Code mit KI – perfekt zum Reinkopieren!

<!DOCTYPE html> <html> <head> <title>Tic Tac Toe - mit KI</title> <style> body { display: flex; justify-content: center; align-items: center; min-height: 100vh; background: #1a1a2e; font-family: Arial, sans-serif; margin: 0; padding: 20px; } .container { background: #2d2d44; padding: 30px; border-radius: 20px; box-shadow: 0 10px 30px rgba(0,0,0,0.5); } .board { display: grid; grid-template-columns: repeat(3, 100px); gap: 5px; } .cell { width: 100px; height: 100px; background: #3d3d5a; border: 2px solid #4a4a6a; border-radius: 10px; font-size: 50px; display: flex; align-items: center; justify-content: center; cursor: pointer; color: white; font-weight: bold; transition: all 0.2s; } .cell:hover { background: #4a4a6a; transform: scale(1.02); } .cell.x { color: #ff6b6b; } .cell.o { color: #4ecdc4; } .cell.winner { background: #4a7a4a; border-color: #6bcb77; animation: glow 0.5s ease-in-out infinite alternate; } @keyframes glow { from { box-shadow: 0 0 10px #6bcb77; } to { box-shadow: 0 0 30px #6bcb77; } } .status { color: white; font-size: 24px; text-align: center; margin-top: 20px; padding: 10px; background: #1a1a2e; border-radius: 10px; } .controls { display: flex; justify-content: center; gap: 10px; margin-top: 15px; flex-wrap: wrap; } .reset { padding: 10px 30px; background: #ff6b6b; border: none; border-radius: 10px; color: white; font-size: 18px; cursor: pointer; transition: all 0.2s; } .reset:hover { background: #ff5252; transform: scale(1.05); } .mode-btn { padding: 10px 20px; background: #4a6fa5; border: none; border-radius: 10px; color: white; font-size: 16px; cursor: pointer; transition: all 0.2s; } .mode-btn:hover { transform: scale(1.05); } .mode-btn.active { background: #ff6b6b; } .difficulty-btn { padding: 8px 20px; border: none; border-radius: 10px; color: white; cursor: pointer; transition: all 0.2s; opacity: 0.6; } .difficulty-btn:hover { transform: scale(1.05); } .difficulty-btn.active { opacity: 1; transform: scale(1.1); } .difficulty-easy { background: #6bcb77; } .difficulty-medium { background: #ffd93d; color: #333; } .difficulty-hard { background: #ff6b6b; } @media (max-width: 400px) { .board { grid-template-columns: repeat(3, 80px); } .cell { width: 80px; height: 80px; font-size: 40px; } } </style> </head> <body> <div class="container"> <h1 style="color: white; text-align: center; margin-bottom: 20px;">❌⭕ Tic Tac Toe</h1> <div class="board" id="board"> <div class="cell" data-index="0"></div> <div class="cell" data-index="1"></div> <div class="cell" data-index="2"></div> <div class="cell" data-index="3"></div> <div class="cell" data-index="4"></div> <div class="cell" data-index="5"></div> <div class="cell" data-index="6"></div> <div class="cell" data-index="7"></div> <div class="cell" data-index="8"></div> </div> <div class="status" id="status">❌ Spieler X ist dran</div> <div class="controls"> <button class="reset" id="reset">🔄 Neues Spiel</button> <button class="mode-btn" id="modeToggle">🤖 Gegen Computer</button> </div> <div class="controls" style="margin-top: 10px;"> <span style="color: white; margin-right: 10px;">Schwierigkeit:</span> <button class="difficulty-btn difficulty-easy active" data-diff="easy">Leicht</button> <button class="difficulty-btn difficulty-medium" data-diff="medium">Mittel</button> <button class="difficulty-btn difficulty-hard" data-diff="hard">Schwer</button> </div> <div style="color: #888; text-align: center; margin-top: 15px; font-size: 14px;"> <span style="color: #ff6b6b;">❌</span> Du <span style="margin: 0 15px;">|</span> <span style="color: #4ecdc4;">⭕</span> Computer </div> </div> <script> // ============================================================ // 1. DOM-Elemente // ============================================================ const cells = document.querySelectorAll('.cell'); const statusDisplay = document.getElementById('status'); const resetButton = document.getElementById('reset'); const modeToggle = document.getElementById('modeToggle'); // ============================================================ // 2. Spielvariablen // ============================================================ let board = ['', '', '', '', '', '', '', '', '']; let currentPlayer = 'X'; let gameActive = true; let isComputerMode = false; let difficulty = 'easy'; let isComputerThinking = false; // ============================================================ // 3. Gewinnkombinationen // ============================================================ 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] ]; // ============================================================ // 4. Status anzeigen // ============================================================ function updateStatus() { if (!gameActive) return; if (isComputerMode && currentPlayer === 'O') { statusDisplay.textContent = '🤖 Computer denkt...'; } else { statusDisplay.textContent = `❌ Spieler ${currentPlayer} ist dran`; } } // ============================================================ // 5. Leere Felder finden // ============================================================ function getEmptyCells() { const empty = []; for (let i = 0; i < board.length; i++) { if (board[i] === '') { empty.push(i); } } return empty; } // ============================================================ // 6. Gewinner prüfen (für KI) // ============================================================ function checkWinnerFor(boardState) { for (let condition of winConditions) { const [a, b, c] = condition; if (boardState[a] && boardState[a] === boardState[b] && boardState[a] === boardState[c]) { return boardState[a]; } } return null; } // ============================================================ // 7. SCHNELLE KI: Gewinnzug oder Blockierung // ============================================================ function getSmartMove() { const emptyCells = getEmptyCells(); // 1. Kann Computer (O) gewinnen? for (let i of emptyCells) { const testBoard = [...board]; testBoard[i] = 'O'; if (checkWinnerFor(testBoard) === 'O') { return i; } } // 2. Muss Computer blockieren (X kann gewinnen)? for (let i of emptyCells) { const testBoard = [...board]; testBoard[i] = 'X'; if (checkWinnerFor(testBoard) === 'X') { return i; } } // 3. Priorisiere Mitte, dann Ecken, dann Seiten const priorities = [4, 0, 2, 6, 8, 1, 3, 5, 7]; for (let pos of priorities) { if (board[pos] === '') { return pos; } } return emptyCells[0] || -1; } // ============================================================ // 8. MiniMax mit Alpha-Beta (nur für schwer) // ============================================================ function minimax(boardState, depth, isMaximizing, alpha = -Infinity, beta = Infinity) { const winner = checkWinnerFor(boardState); if (winner === 'O') return 10 - depth; if (winner === 'X') return depth - 10; if (boardState.every(cell => cell !== '')) return 0; if (depth > 6) return 0; if (isMaximizing) { let bestScore = -Infinity; for (let i = 0; i < boardState.length; i++) { if (boardState[i] === '') { boardState[i] = 'O'; const score = minimax(boardState, depth + 1, false, alpha, beta); boardState[i] = ''; bestScore = Math.max(score, bestScore); alpha = Math.max(alpha, bestScore); if (beta <= alpha) break; } } return bestScore; } else { let bestScore = Infinity; for (let i = 0; i < boardState.length; i++) { if (boardState[i] === '') { boardState[i] = 'X'; const score = minimax(boardState, depth + 1, true, alpha, beta); boardState[i] = ''; bestScore = Math.min(score, bestScore); beta = Math.min(beta, bestScore); if (beta <= alpha) break; } } return bestScore; } } function getBestMoveMinimax() { const emptyCells = getEmptyCells(); if (emptyCells.length === 0) return -1; if (emptyCells.length > 6) return getSmartMove(); let bestScore = -Infinity; let bestMove = -1; const boardCopy = [...board]; for (let i = 0; i < boardCopy.length; i++) { if (boardCopy[i] === '') { boardCopy[i] = 'O'; const score = minimax(boardCopy, 0, false); boardCopy[i] = ''; if (score > bestScore) { bestScore = score; bestMove = i; } } } return bestMove; } // ============================================================ // 9. Gewinner prüfen (für Spiel) // ============================================================ function checkWinner() { for (let condition of winConditions) { const [a, b, c] = condition; if (board[a] && board[a] === board[b] && board[a] === board[c]) { cells[a].classList.add('winner'); cells[b].classList.add('winner'); cells[c].classList.add('winner'); return board[a]; } } return null; } // ============================================================ // 10. Spielzug ausführen // ============================================================ function handleCellClick(index) { if (board[index] !== '' || !gameActive || isComputerThinking) return; if (isComputerMode && currentPlayer === 'O') return; board[index] = currentPlayer; cells[index].textContent = currentPlayer; cells[index].classList.add(currentPlayer.toLowerCase()); cells[index].style.transition = 'transform 0.1s'; cells[index].style.transform = 'scale(0.8)'; setTimeout(() => { cells[index].style.transform = 'scale(1)'; }, 100); const winner = checkWinner(); if (winner) { statusDisplay.textContent = `🎉 ${winner === 'X' ? 'Du' : 'Computer'} hat gewonnen!`; gameActive = false; return; } if (board.every(cell => cell !== '')) { statusDisplay.textContent = '🤝 Unentschieden!'; gameActive = false; return; } currentPlayer = currentPlayer === 'X' ? 'O' : 'X'; updateStatus(); if (gameActive && isComputerMode && currentPlayer === 'O') { isComputerThinking = true; setTimeout(makeComputerMove, 200); } } // ============================================================ // 11. KI-Zug (SCHNELL) // ============================================================ function makeComputerMove() { if (!gameActive || currentPlayer !== 'O' || !isComputerMode) { isComputerThinking = false; return; } const emptyCells = getEmptyCells(); if (emptyCells.length === 0) { isComputerThinking = false; return; } let move = -1; switch(difficulty) { case 'easy': if (Math.random() < 0.4) { const randomIndex = Math.floor(Math.random() * emptyCells.length); move = emptyCells[randomIndex]; } else { move = getSmartMove(); } break; case 'medium': if (Math.random() < 0.3) { const randomIndex = Math.floor(Math.random() * emptyCells.length); move = emptyCells[randomIndex]; } else { move = getSmartMove(); } break; case 'hard': default: move = getBestMoveMinimax(); break; } isComputerThinking = false; if (move !== -1) { setTimeout(() => { handleCellClick(move); }, 150); } } // ============================================================ // 12. Spiel zurücksetzen // ============================================================ function resetGame() { board = ['', '', '', '', '', '', '', '', '']; currentPlayer = 'X'; gameActive = true; isComputerThinking = false; cells.forEach(cell => { cell.textContent = ''; cell.classList.remove('x', 'o', 'winner'); cell.style.transform = 'scale(1)'; }); statusDisplay.textContent = '❌ Spieler X ist dran'; if (isComputerMode && currentPlayer === 'O') { isComputerThinking = true; setTimeout(makeComputerMove, 300); } } // ============================================================ // 13. Modus umschalten // ============================================================ modeToggle.addEventListener('click', function() { isComputerMode = !isComputerMode; resetGame(); if (isComputerMode) { this.textContent = '👫 Mit Freund spielen'; this.classList.add('active'); } else { this.textContent = '🤖 Gegen Computer'; this.classList.remove('active'); } }); // ============================================================ // 14. Schwierigkeitsstufen // ============================================================ document.querySelectorAll('.difficulty-btn').forEach(btn => { btn.addEventListener('click', function() { difficulty = this.dataset.diff; document.querySelectorAll('.difficulty-btn').forEach(b => b.classList.remove('active')); this.classList.add('active'); if (isComputerMode) resetGame(); }); }); // ============================================================ // 15. Event-Listener // ============================================================ cells.forEach(cell => { cell.addEventListener('click', () => { handleCellClick(parseInt(cell.dataset.index)); }); }); resetButton.addEventListener('click', resetGame); // ============================================================ // 16. Spiel starten // ============================================================ statusDisplay.textContent = '❌ Spieler X ist dran'; console.log('❌⭕ Tic Tac Toe mit KI geladen!'); </script> </body> </html>
🎯 JETZT BIST DU DRAN!
1. Kopiere den kompletten Code in eine neue Datei.
2. Speichere sie als tictactoe_ki.html.
3. Ă–ffne die Datei im Browser.
4. Klicke auf "Gegen Computer" und fordere die KI heraus!

đź’ˇ Probiere die Schwierigkeitsstufen aus:
- Leicht: Der Computer macht oft Fehler
- Mittel: Eine gute Mischung
- Schwer: Der Computer spielt perfekt!

🎉 GLÜCKWUNSCH!
Du hast dein erstes Tic Tac Toe Spiel mit KI programmiert!
Du hast den MiniMax-Algorithmus kennengelernt –
einen der wichtigsten Algorithmen fĂĽr Spiele-KIs.
🔄 Seite neu laden