const boardSize = 8; let board = [], currentPlayer = 1,รป selectedPiece = null, validMoves = [], gameRunning = false, vsCPU = false; const playerColors = { 1: "168, 208, 230", 2: "246, 171, 182", }; let players = { 1: { name: "Spieler 1", color: "168, 208, 230" }, 2: { name: "Spieler 2", color: "246, 171, 182" }, }; const captureHighlightColors = { 1: "128, 168, 190", 2: "206, 131, 142", }; const pieceColors = { 1: "77, 129, 199", 2: "214, 106, 139", }; const body = document.body; body.style.setProperty("--player1-color", players[1].color); body.style.setProperty("--player2-color", players[2].color); const inputPlayerName1 = document.getElementById("inputPlayerName1"); inputPlayerName1.value = players[1].name; const inputPlayerName2 = document.getElementById("inputPlayerName2"); inputPlayerName2.value = players[2].name; const savePlayerNamesButton = document.getElementById("savePlayerNames"); const boardElement = document.getElementById("board"); const statusElement = document.getElementById("status"); const newGameButton = document.getElementById("new-game"); const winMessageElement = document.getElementById("winMessage"); const cpuToggle = document.getElementById("cpuToggle"); function inBounds(row, col) { return row >= 0 && row < boardSize && col >= 0 && col < boardSize; } function isEmpty(row, col) { return board[row][col] === 0; } function isOpponent(piece, player) { return piece !== 0 && (player === 1 ? piece === 2 || piece === 4 : piece === 1 || piece === 3); } function isPlayerPiece(piece, player) { return player === 1 ? piece === 1 || piece === 3 : player === 2 && (piece === 2 || piece === 4); } function isKing(piece) { return piece === 3 || piece === 4; } function initGame() { board = Array.from({ length: boardSize }, () => Array(boardSize).fill(0)); for (let row = 0; row < 3; row++) { for (let col = 0; col < boardSize; col++) { if ((row + col) % 2 === 1) board[row][col] = 1; } } for (let row = boardSize - 3; row < boardSize; row++) { for (let col = 0; col < boardSize; col++) { if ((row + col) % 2 === 1) board[row][col] = 2; } } currentPlayer = 1; selectedPiece = null; validMoves = []; gameRunning = true; winMessageElement.style.display = "none"; newGameButton.style.display = "inline-block"; vsCPU = cpuToggle.checked; cpuToggle.disabled = false; updateStatus(); updateBackground(); renderBoard(); if (vsCPU && currentPlayer === 2) { setTimeout(cpuMove, 500); } } function updateStatus() { statusElement.textContent = `${players[currentPlayer].name} ist am Zug`; } function updateBackground() { body.style.setProperty("--active-background-color", players[currentPlayer].color); } function getValidMoves(row, col) { const moves = []; const piece = board[row][col]; if (!isPlayerPiece(piece, currentPlayer)) return moves; const directions = isKing(piece) ? [[1, 1], [1, -1], [-1, 1], [-1, -1]] : currentPlayer === 1 ? [[1, -1], [1, 1]] : [[-1, -1], [-1, 1]]; directions.forEach(([dr, dc]) => { const newRow = row + dr, newCol = col + dc; if (inBounds(newRow, newCol) && isEmpty(newRow, newCol)) { moves.push({ row: newRow, col: newCol, capture: false }); } const captureRow = row + 2 * dr, captureCol = col + 2 * dc; if (inBounds(newRow, newCol) && inBounds(captureRow, captureCol) && isOpponent(board[newRow][newCol], currentPlayer) && isEmpty(captureRow, captureCol)) { moves.push({ row: captureRow, col: captureCol, capture: true, captured: { row: newRow, col: newCol } }); } }); return moves; } function getValidMovesForPlayer(row, col, player) { const moves = []; const piece = board[row][col]; if (!isPlayerPiece(piece, player)) return moves; const directions = isKing(piece) ? [[1, 1], [1, -1], [-1, 1], [-1, -1]] : player === 1 ? [[1, -1], [1, 1]] : [[-1, -1], [-1, 1]]; directions.forEach(([dr, dc]) => { const newRow = row + dr, newCol = col + dc; if (inBounds(newRow, newCol) && isEmpty(newRow, newCol)) { moves.push({ row: newRow, col: newCol, capture: false }); } const captureRow = row + 2 * dr, captureCol = col + 2 * dc; if (inBounds(newRow, newCol) && inBounds(captureRow, captureCol) && isOpponent(board[newRow][newCol], player) && isEmpty(captureRow, captureCol)) { moves.push({ row: captureRow, col: captureCol, capture: true, captured: { row: newRow, col: newCol } }); } }); return moves; } function hasAnyMoves(player) { for (let row = 0; row < boardSize; row++) { for (let col = 0; col < boardSize; col++) { if (isPlayerPiece(board[row][col], player) && getValidMovesForPlayer(row, col, player).length > 0) { return true; } } } return false; } function hasAnyCapture() { for (let row = 0; row < boardSize; row++) { for (let col = 0; col < boardSize; col++) { if (isPlayerPiece(board[row][col], currentPlayer) && getValidMoves(row, col).some(move => move.capture)) { return true; } } } return false; } function makeMove(fromRow, fromCol, move) { board[move.row][move.col] = board[fromRow][fromCol]; board[fromRow][fromCol] = 0; if (move.capture) { const captured = move.captured; board[captured.row][captured.col] = 0; } if (currentPlayer === 1 && move.row === boardSize - 1 && board[move.row][move.col] === 1) { board[move.row][move.col] = 3; } else if (currentPlayer === 2 && move.row === 0 && board[move.row][move.col] === 2) { board[move.row][move.col] = 4; } } function switchPlayer() { currentPlayer = currentPlayer === 1 ? 2 : 1; selectedPiece = null; renderBoard(); validMoves = []; updateStatus(); updateBackground(); if (hasAnyMoves(currentPlayer)) { if (vsCPU && currentPlayer === 2) { setTimeout(cpuMove, 500); } } else { endGame(currentPlayer === 1 ? 2 : 1); } } function cpuMove() { let possibleMoves = []; const mustCapture = hasAnyCapture(); for (let row = 0; row < boardSize; row++) { for (let col = 0; col < boardSize; col++) { if (isPlayerPiece(board[row][col], currentPlayer)) { let moves = getValidMoves(row, col); if (mustCapture) { moves = moves.filter(move => move.capture); } if (moves.length > 0) { possibleMoves.push({ row, col, moves }); } } } } if (possibleMoves.length === 0) { endGame(currentPlayer === 1 ? 2 : 1); return; } const { row, col, moves } = possibleMoves[Math.floor(Math.random() * possibleMoves.length)]; const move = moves[Math.floor(Math.random() * moves.length)]; setTimeout(() => { makeMove(row, col, move); renderBoard(); if (move.capture) { cpuCaptureChain(move.row, move.col); } else { checkWin() || switchPlayer(); } }, 500); } function cpuCaptureChain(row, col) { let captureMoves = getValidMoves(row, col).filter(move => move.capture); if (captureMoves.length > 0) { const move = captureMoves[Math.floor(Math.random() * captureMoves.length)]; setTimeout(() => { makeMove(row, col, move); renderBoard(); cpuCaptureChain(move.row, move.col); }, 500); } else { checkWin() || switchPlayer(); } } function checkWin() { let player1Pieces = 0, player2Pieces = 0; for (let row = 0; row < boardSize; row++) { for (let col = 0; col < boardSize; col++) { if (board[row][col] === 1 || board[row][col] === 3) { player1Pieces++; } else if (board[row][col] === 2 || board[row][col] === 4) { player2Pieces++; } } } if (player1Pieces === 0) { endGame(2); return true; } else if (player2Pieces === 0) { endGame(1); return true; } else if (!hasAnyMoves(currentPlayer === 1 ? 2 : 1)) { endGame(currentPlayer); return true; } return false; } function endGame(winner) { gameRunning = false; newGameButton.style.display = "none"; winMessageElement.textContent = `Spieler ${winner} hat gewonnen! (Zum Neustart klicken)`; winMessageElement.style.display = "block"; winMessageElement.style.backgroundColor = `rgba(${players[winner].color}, 1.0)`; cpuToggle.disabled = false; winMessageElement.addEventListener("click", initGame, { once: true }); } function renderBoard() { boardElement.innerHTML = ""; for (let row = 0; row < boardSize; row++) { for (let col = 0; col < boardSize; col++) { const cell = document.createElement("div"); cell.classList.add("cell"); cell.classList.add((row + col) % 2 === 0 ? "light" : "dark"); cell.dataset.row = row; cell.dataset.col = col; if (validMoves.some(move => move.row === row && move.col === col)) { cell.classList.add("highlight"); } if (selectedPiece && selectedPiece.row === row && selectedPiece.col === col) { cell.classList.add("selected"); } const piece = board[row][col]; if (piece !== 0) { const pieceElement = document.createElement("div"); pieceElement.classList.add("piece"); pieceElement.style.setProperty("--player-color", players[piece % 2 === 0 ? 2 : 1].color); if (isKing(piece)) { pieceElement.classList.add("king"); } if (getValidMoves(row, col).some(move => move.capture)) { pieceElement.classList.add("must-capture"); } else { pieceElement.classList.remove("must-capture"); } cell.appendChild(pieceElement); } cell.addEventListener("click", handleCellClick); boardElement.appendChild(cell); } } } function handleCellClick(event) { if (!gameRunning || (vsCPU && currentPlayer === 2)) return; const row = parseInt(event.currentTarget.dataset.row); const col = parseInt(event.currentTarget.dataset.col); if (selectedPiece) { const move = validMoves.find(move => move.row === row && move.col === col); if (move) { makeMove(selectedPiece.row, selectedPiece.col, move); renderBoard(); if (move.capture) { const captureMoves = getValidMoves(move.row, move.col).filter(move => move.capture); if (captureMoves.length > 0) { selectedPiece = { row: move.row, col: move.col }; validMoves = captureMoves; return; } } selectedPiece = null; validMoves = []; checkWin() || switchPlayer(); return; } } if (isPlayerPiece(board[row][col], currentPlayer)) { if (hasAnyCapture()) { const captureMoves = getValidMoves(row, col).filter(move => move.capture); if (captureMoves.length === 0) return; selectedPiece = { row, col }; validMoves = captureMoves; } else { selectedPiece = { row, col }; validMoves = getValidMoves(row, col); } renderBoard(); } } function openSavePlayerNamesDialog() { if (!cpuToggle.checked) { inputPlayerName2.value = inputPlayerName2.value === "CPU" ? "Spieler 2" : inputPlayerName2.value; } else { inputPlayerName2.value = "CPU"; } inputPlayerName2.disabled = cpuToggle.checked; document.getElementById("setPlayerNamesWrapperBackdrop").style.display = "block"; } savePlayerNamesButton.addEventListener("click", () => { players[1].name = inputPlayerName1.value.length > 0 ? inputPlayerName1.value : "Spieler 1"; players[2].name = inputPlayerName2.value.length > 0 ? inputPlayerName2.value : "Spieler 2"; document.getElementById("setPlayerNamesWrapperBackdrop").style.display = "none"; cpuToggle.disabled = false; initGame(); }); newGameButton.addEventListener("click", openSavePlayerNamesDialog); cpuToggle.addEventListener("click", openSavePlayerNamesDialog); initGame();