Initial commit - Kinderspiele
This commit is contained in:
@@ -0,0 +1,661 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
|
||||
<title>Mensch ärgere dich nicht - KinderWelt</title>
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; user-select: none; }
|
||||
body {
|
||||
background: linear-gradient(135deg, #FEF3C7 0%, #FDE68A 100%);
|
||||
min-height: 100vh; display: flex; flex-direction: column; align-items: center;
|
||||
font-family: 'Comic Sans MS', cursive, sans-serif; padding: 10px;
|
||||
}
|
||||
h1 { color: #92400E; margin-bottom: 5px; font-size: 22px; text-align: center; }
|
||||
|
||||
.setup-screen {
|
||||
background: white; padding: 20px; border-radius: 15px; max-width: 400px;
|
||||
width: 95%; box-shadow: 0 10px 30px rgba(0,0,0,0.2);
|
||||
}
|
||||
.setup-screen h2 { color: #333; margin-bottom: 15px; text-align: center; font-size: 20px; }
|
||||
|
||||
.player-setup { margin: 12px 0; }
|
||||
.player-label {
|
||||
display: flex; align-items: center; padding: 8px 12px; border-radius: 8px;
|
||||
font-weight: bold; margin-bottom: 5px; font-size: 14px;
|
||||
}
|
||||
.player-label.red { background: #FEE2E2; color: #991B1B; }
|
||||
.player-label.blue { background: #DBEAFE; color: #1E40AF; }
|
||||
.player-label.green { background: #D1FAE5; color: #065F46; }
|
||||
.player-label.yellow { background: #FEF3C7; color: #92400E; }
|
||||
|
||||
.player-setup input[type="text"] {
|
||||
width: 100%; padding: 10px; border: 2px solid #E5E7EB; border-radius: 8px;
|
||||
font-family: inherit; font-size: 14px;
|
||||
}
|
||||
.player-setup input.name-red { border-color: #EF4444; }
|
||||
.player-setup input.name-blue { border-color: #3B82F6; }
|
||||
.player-setup input.name-green { border-color: #10B981; }
|
||||
.player-setup input.name-yellow { border-color: #F59E0B; }
|
||||
|
||||
.checkbox-wrapper { display: flex; align-items: center; gap: 8px; margin-top: 5px; font-size: 13px; }
|
||||
.checkbox-wrapper input { width: 18px; height: 18px; }
|
||||
|
||||
.rules-check {
|
||||
background: #F3F4F6; padding: 12px; border-radius: 8px; margin: 15px 0;
|
||||
}
|
||||
.rules-check label { display: flex; align-items: center; gap: 8px; font-size: 14px; cursor: pointer; }
|
||||
|
||||
.btn {
|
||||
background: #10B981; color: white; border: none; border-radius: 10px;
|
||||
padding: 12px 30px; font-size: 16px; cursor: pointer; font-family: inherit; font-weight: bold;
|
||||
width: 100%; margin-top: 10px;
|
||||
}
|
||||
.btn:hover { background: #059669; }
|
||||
.btn-back { background: #EF4444; text-decoration: none; display: inline-block; text-align: center; }
|
||||
|
||||
/* Spielbrett */
|
||||
.game-container { display: none; flex-direction: column; align-items: center; }
|
||||
|
||||
.board {
|
||||
display: grid; grid-template-columns: repeat(11, 32px); gap: 1px;
|
||||
background: #D1D5DB; padding: 8px; border-radius: 10px;
|
||||
box-shadow: 0 10px 30px rgba(0,0,0,0.3);
|
||||
}
|
||||
|
||||
.cell {
|
||||
width: 32px; height: 32px; background: white; border-radius: 50%;
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
position: relative; font-size: 10px;
|
||||
}
|
||||
|
||||
/* Home-Bereiche (Ecken) */
|
||||
.home-red { background: #FEE2E2; }
|
||||
.home-blue { background: #DBEAFE; }
|
||||
.home-green { background: #D1FAE5; }
|
||||
.home-yellow { background: #FEF3C7; }
|
||||
|
||||
/* Ziel-Bereiche */
|
||||
.goal-red { background: #FECACA; }
|
||||
.goal-blue { background: #BFDBFE; }
|
||||
.goal-green { background: #A7F3D0; }
|
||||
.goal-yellow { background: #FDE68A; }
|
||||
|
||||
/* Startfelder */
|
||||
.start-red { background: #EF4444; }
|
||||
.start-blue { background: #3B82F6; }
|
||||
.start-green { background: #10B981; }
|
||||
.start-yellow { background: #F59E0B; }
|
||||
|
||||
/* Figuren */
|
||||
.piece {
|
||||
width: 26px; height: 26px; border-radius: 50%; position: absolute;
|
||||
border: 2px solid white; box-shadow: 2px 2px 4px rgba(0,0,0,0.4);
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
font-size: 11px; font-weight: bold; color: white; cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
.piece:hover { transform: scale(1.2); }
|
||||
.piece.red { background: #DC2626; }
|
||||
.piece.blue { background: #2563EB; }
|
||||
.piece.green { background: #059669; }
|
||||
.piece.yellow { background: #D97706; color: white; }
|
||||
|
||||
.piece.selected { box-shadow: 0 0 0 3px #FFD700, 0 0 15px #FFD700; }
|
||||
.piece.movable { animation: pulse 1s infinite; }
|
||||
@keyframes pulse {
|
||||
0%, 100% { transform: scale(1); }
|
||||
50% { transform: scale(1.1); }
|
||||
}
|
||||
|
||||
/* Würfel */
|
||||
.dice-area { margin: 15px 0; }
|
||||
.dice {
|
||||
width: 70px; height: 70px; background: white; border-radius: 12px;
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
font-size: 40px; cursor: pointer; border: 3px solid #374151;
|
||||
box-shadow: 0 5px 15px rgba(0,0,0,0.3);
|
||||
}
|
||||
.dice.rolling { animation: shake 0.5s ease-in-out; }
|
||||
@keyframes shake {
|
||||
0%, 100% { transform: rotate(0deg); }
|
||||
25% { transform: rotate(-10deg); }
|
||||
75% { transform: rotate(10deg); }
|
||||
}
|
||||
|
||||
.status-bar {
|
||||
background: white; padding: 12px 20px; border-radius: 25px;
|
||||
margin: 10px 0; font-size: 15px; text-align: center;
|
||||
box-shadow: 0 3px 10px rgba(0,0,0,0.1); max-width: 350px;
|
||||
}
|
||||
.current-player { font-weight: bold; font-size: 17px; }
|
||||
|
||||
.throw-indicator {
|
||||
color: #059669; font-weight: bold; margin-top: 5px;
|
||||
}
|
||||
|
||||
.controls { display: flex; gap: 10px; margin-top: 15px; flex-wrap: wrap; justify-content: center; }
|
||||
.game-btn {
|
||||
padding: 10px 20px; border: none; border-radius: 8px;
|
||||
font-size: 14px; cursor: pointer; font-family: inherit; font-weight: bold;
|
||||
}
|
||||
.btn-roll { background: #10B981; color: white; }
|
||||
.btn-skip { background: #6B7280; color: white; }
|
||||
|
||||
.game-over {
|
||||
position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%);
|
||||
background: white; padding: 30px; border-radius: 20px; text-align: center;
|
||||
display: none; z-index: 100; box-shadow: 0 10px 50px rgba(0,0,0,0.5);
|
||||
}
|
||||
.game-over h2 { margin-bottom: 15px; color: #333; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>🎲 Mensch ärgere dich nicht</h1>
|
||||
|
||||
<!-- Setup -->
|
||||
<div class="setup-screen" id="setupScreen">
|
||||
<h2>👥 Spieler einrichten</h2>
|
||||
|
||||
<div class="player-setup">
|
||||
<div class="player-label red">🔴 Spieler 1 (Rot)</div>
|
||||
<input type="text" id="name1" class="name-red" placeholder="Name..." value="Peter">
|
||||
</div>
|
||||
|
||||
<div class="player-setup">
|
||||
<div class="player-label blue">🔵 Spieler 2 (Blau)</div>
|
||||
<input type="text" id="name2" class="name-blue" placeholder="Name..." value="Anna">
|
||||
<div class="checkbox-wrapper">
|
||||
<input type="checkbox" id="bot2" onchange="toggleBot(2)">
|
||||
<label for="bot2">🤖 Computer</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="player-setup">
|
||||
<div class="player-label green">🟢 Spieler 3 (Grün)</div>
|
||||
<input type="text" id="name3" class="name-green" placeholder="Name...">
|
||||
<div class="checkbox-wrapper">
|
||||
<input type="checkbox" id="bot3" onchange="toggleBot(3)">
|
||||
<label for="bot3">🤖 Computer</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="player-setup">
|
||||
<div class="player-label yellow">🟡 Spieler 4 (Gelb)</div>
|
||||
<input type="text" id="name4" class="name-yellow" placeholder="Name...">
|
||||
<div class="checkbox-wrapper">
|
||||
<input type="checkbox" id="bot4" onchange="toggleBot(4)">
|
||||
<label for="bot4">🤖 Computer</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="rules-check">
|
||||
<label>
|
||||
<input type="checkbox" id="forceKick" checked>
|
||||
<span>🎯 Schmeißen ist Pflicht</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<button class="btn" onclick="startGame()">🎮 Spiel starten</button>
|
||||
<a href="../index.html" class="btn btn-back" style="margin-top:10px;display:block">⬅️ Zurück</a>
|
||||
</div>
|
||||
|
||||
<!-- Spiel -->
|
||||
<div class="game-container" id="gameScreen">
|
||||
<div class="status-bar" id="statusBar">
|
||||
<div class="current-player" id="currentPlayerName">Peter ist dran!</div>
|
||||
<div id="gameStatus">Würfle eine 6 zum Starten!</div>
|
||||
<div class="throw-indicator" id="throwIndicator"></div>
|
||||
</div>
|
||||
|
||||
<div class="board" id="board"></div>
|
||||
|
||||
<div class="dice-area">
|
||||
<div class="dice" id="dice" onclick="roll()">🎲</div>
|
||||
</div>
|
||||
|
||||
<div class="controls">
|
||||
<button class="game-btn btn-roll" onclick="roll()">🎲 Würfeln</button>
|
||||
<button class="game-btn btn-skip" onclick="skipTurn()">⏭️ Zug beenden</button>
|
||||
<button class="game-btn" onclick="resetGame()">🔄 Neustart</button>
|
||||
<a href="../index.html" class="game-btn btn-back">⬅️ Menü</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="game-over" id="gameOver">
|
||||
<h2 id="winnerText">🎉 Gewinner!</h2>
|
||||
<button class="btn" onclick="resetGame()" style="width:auto">🔄 Nochmal</button>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// Spielbrett-Layout (11x11 Grid)
|
||||
// Positionen: -4 bis -1 = Home, 0-39 = Weg, 40-43 = Ziel
|
||||
const PLAYERS = [
|
||||
{ color: 'red', name: 'Rot', emoji: '🔴', startField: 0 },
|
||||
{ color: 'blue', name: 'Blau', emoji: '🔵', startField: 10 },
|
||||
{ color: 'green', name: 'Grün', emoji: '🟢', startField: 20 },
|
||||
{ color: 'yellow', name: 'Gelb', emoji: '🟡', startField: 30 }
|
||||
];
|
||||
|
||||
let players = []; // { name, color, isBot, pieces: [pos, pos, pos, pos], finished }
|
||||
let currentPlayer = 0;
|
||||
let currentRoll = 0;
|
||||
let throwsLeft = 0; // 3 Würfe wenn alle im Start
|
||||
let selectedPiece = null;
|
||||
let gameRunning = false;
|
||||
let forceKickRule = true;
|
||||
let hasRolled = false;
|
||||
|
||||
function toggleBot(num) {
|
||||
const checkbox = document.getElementById('bot' + num);
|
||||
const input = document.getElementById('name' + num);
|
||||
if (checkbox.checked) {
|
||||
input.value = '🤖 Computer ' + (num-1);
|
||||
input.disabled = true;
|
||||
} else {
|
||||
input.value = '';
|
||||
input.disabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
function startGame() {
|
||||
forceKickRule = document.getElementById('forceKick').checked;
|
||||
|
||||
players = [];
|
||||
for (let i = 0; i < 4; i++) {
|
||||
const name = document.getElementById('name' + (i+1)).value.trim();
|
||||
if (name) {
|
||||
players.push({
|
||||
id: i,
|
||||
name: name,
|
||||
color: PLAYERS[i].color,
|
||||
isBot: document.getElementById('bot' + (i+1))?.checked || false,
|
||||
pieces: [-1, -1, -1, -1], // -1 = Home, 0-39 = Weg, 40-43 = Ziel
|
||||
finished: 0
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (players.length < 2) {
|
||||
alert('Mindestens 2 Spieler!');
|
||||
return;
|
||||
}
|
||||
|
||||
document.getElementById('setupScreen').style.display = 'none';
|
||||
document.getElementById('gameScreen').style.display = 'flex';
|
||||
|
||||
initBoard();
|
||||
currentPlayer = 0;
|
||||
throwsLeft = calculateThrows();
|
||||
updateStatus();
|
||||
gameRunning = true;
|
||||
|
||||
if (players[0].isBot) setTimeout(botTurn, 1000);
|
||||
}
|
||||
|
||||
function calculateThrows() {
|
||||
const p = players[currentPlayer];
|
||||
const inStart = p.pieces.filter(pos => pos === -1).length;
|
||||
return (inStart === 4) ? 3 : 1;
|
||||
}
|
||||
|
||||
function initBoard() {
|
||||
const board = document.getElementById('board');
|
||||
board.innerHTML = '';
|
||||
|
||||
// 11x11 Grid erstellen
|
||||
for (let row = 0; row < 11; row++) {
|
||||
for (let col = 0; col < 11; col++) {
|
||||
const cell = document.createElement('div');
|
||||
cell.className = 'cell';
|
||||
cell.dataset.row = row;
|
||||
cell.dataset.col = col;
|
||||
|
||||
// Home-Bereiche (Ecken)
|
||||
if (row < 4 && col < 4) {
|
||||
cell.classList.add('home-red');
|
||||
cell.dataset.home = '0';
|
||||
} else if (row < 4 && col > 6) {
|
||||
cell.classList.add('home-blue');
|
||||
cell.dataset.home = '1';
|
||||
} else if (row > 6 && col < 4) {
|
||||
cell.classList.add('home-green');
|
||||
cell.dataset.home = '2';
|
||||
} else if (row > 6 && col > 6) {
|
||||
cell.classList.add('home-yellow');
|
||||
cell.dataset.home = '3';
|
||||
}
|
||||
// Ziel-Bereiche
|
||||
else if (row === 5 && col === 5) {
|
||||
cell.style.background = '#FEF3C7'; // Mitte
|
||||
}
|
||||
else if (row === 5 && col >= 1 && col <= 4) {
|
||||
cell.classList.add('goal-red');
|
||||
}
|
||||
else if (col === 5 && row >= 1 && row <= 4) {
|
||||
cell.classList.add('goal-blue');
|
||||
}
|
||||
else if (row === 5 && col >= 6 && col <= 9) {
|
||||
cell.classList.add('goal-green');
|
||||
}
|
||||
else if (col === 5 && row >= 6 && row <= 9) {
|
||||
cell.classList.add('goal-yellow');
|
||||
}
|
||||
// Weg mit Startfeldern
|
||||
else if (isPath(row, col)) {
|
||||
const pathIdx = getPathIndex(row, col);
|
||||
if (pathIdx !== null) {
|
||||
// Startfelder markieren
|
||||
if (pathIdx === 0) cell.classList.add('start-red');
|
||||
else if (pathIdx === 10) cell.classList.add('start-blue');
|
||||
else if (pathIdx === 20) cell.classList.add('start-green');
|
||||
else if (pathIdx === 30) cell.classList.add('start-yellow');
|
||||
cell.dataset.path = pathIdx;
|
||||
}
|
||||
}
|
||||
|
||||
board.appendChild(cell);
|
||||
}
|
||||
}
|
||||
|
||||
updatePieces();
|
||||
}
|
||||
|
||||
function isPath(row, col) {
|
||||
// Äußerer Ring + Verbindungen
|
||||
return (row === 0 || row === 10 || col === 0 || col === 10 ||
|
||||
(row === 4 || row === 6) && col >= 4 && col <= 6 ||
|
||||
(col === 4 || col === 6) && row >= 4 && row <= 6);
|
||||
}
|
||||
|
||||
function getPathIndex(row, col) {
|
||||
// Vereinfachte Pfad-Berechnung
|
||||
const paths = [
|
||||
[4,0], [4,1], [4,2], [4,3], [4,4], // Rot Start
|
||||
[3,4], [2,4], [1,4], [0,4], [0,5], [0,6], // Oben
|
||||
[1,6], [2,6], [3,6], [4,6], // Blau Start
|
||||
[4,7], [4,8], [4,9], [4,10], [5,10], [6,10], // Rechts
|
||||
[6,9], [6,8], [6,7], [6,6], // Grün Start
|
||||
[7,6], [8,6], [9,6], [10,6], [10,5], [10,4], // Unten
|
||||
[9,4], [8,4], [7,4], [6,4], // Gelb Start
|
||||
[6,3], [6,2], [6,1], [6,0], [5,0], // Links
|
||||
[5,1], [5,2], [5,3] // Ziel rot
|
||||
];
|
||||
|
||||
for (let i = 0; i < paths.length; i++) {
|
||||
if (paths[i][0] === row && paths[i][1] === col) return i;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function updatePieces() {
|
||||
document.querySelectorAll('.piece').forEach(p => p.remove());
|
||||
|
||||
players.forEach((player, pIdx) => {
|
||||
player.pieces.forEach((pos, pieceIdx) => {
|
||||
let cell;
|
||||
|
||||
if (pos === -1) {
|
||||
// Home - finde freie Position
|
||||
const homeCells = document.querySelectorAll(`[data-home="${pIdx}"]`);
|
||||
cell = homeCells[pieceIdx] || homeCells[0];
|
||||
} else if (pos >= 0 && pos < 40) {
|
||||
// Auf dem Weg
|
||||
const pathCells = document.querySelectorAll('[data-path]');
|
||||
// Position relativ zum Startfeld
|
||||
const playerStart = PLAYERS[pIdx].startField;
|
||||
const adjustedPos = (pos + playerStart) % 40;
|
||||
pathCells.forEach(pc => {
|
||||
if (parseInt(pc.dataset.path) === adjustedPos) cell = pc;
|
||||
});
|
||||
} else if (pos >= 40) {
|
||||
// Im Ziel
|
||||
const goalPos = pos - 40;
|
||||
const goalCells = document.querySelectorAll(`[class*="goal-${player.color}"]`);
|
||||
cell = goalCells[goalPos];
|
||||
}
|
||||
|
||||
if (cell) {
|
||||
const piece = document.createElement('div');
|
||||
piece.className = `piece ${player.color}`;
|
||||
piece.textContent = pieceIdx + 1;
|
||||
piece.onclick = (e) => {
|
||||
e.stopPropagation();
|
||||
selectPiece(pIdx, pieceIdx);
|
||||
};
|
||||
|
||||
// Markieren wenn bewegbar
|
||||
if (pIdx === currentPlayer && hasRolled && canMovePiece(pIdx, pieceIdx)) {
|
||||
piece.classList.add('movable');
|
||||
}
|
||||
|
||||
cell.appendChild(piece);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function roll() {
|
||||
if (!gameRunning || hasRolled) return;
|
||||
|
||||
const dice = document.getElementById('dice');
|
||||
dice.classList.add('rolling');
|
||||
|
||||
setTimeout(() => {
|
||||
dice.classList.remove('rolling');
|
||||
currentRoll = Math.floor(Math.random() * 6) + 1;
|
||||
dice.textContent = ['⚀','⚁','⚂','⚃','⚄','⚅'][currentRoll-1];
|
||||
|
||||
hasRolled = true;
|
||||
handleRoll(currentRoll);
|
||||
}, 500);
|
||||
}
|
||||
|
||||
function handleRoll(roll) {
|
||||
const player = players[currentPlayer];
|
||||
const inStart = player.pieces.filter(p => p === -1).length;
|
||||
|
||||
document.getElementById('gameStatus').textContent =
|
||||
`${player.name} würfelt ${roll}!`;
|
||||
|
||||
throwsLeft--;
|
||||
|
||||
// Prüfen ob Zug möglich
|
||||
const movable = player.pieces.map((pos, idx) => ({ pos, idx }))
|
||||
.filter(({ pos, idx }) => canMove(player, idx, roll));
|
||||
|
||||
if (movable.length === 0) {
|
||||
if (throwsLeft > 0) {
|
||||
document.getElementById('gameStatus').textContent +=
|
||||
` Kein Zug möglich. Noch ${throwsLeft} Versuch(e).`;
|
||||
hasRolled = false;
|
||||
} else {
|
||||
document.getElementById('gameStatus').textContent += ' Kein Zug möglich.';
|
||||
setTimeout(nextPlayer, 1500);
|
||||
}
|
||||
} else {
|
||||
document.getElementById('gameStatus').textContent +=
|
||||
` Wähle eine Figur!`;
|
||||
updatePieces(); // Markiere bewegliche
|
||||
|
||||
if (player.isBot) {
|
||||
setTimeout(() => botSelectPiece(movable), 1000);
|
||||
}
|
||||
}
|
||||
|
||||
updateThrowIndicator();
|
||||
}
|
||||
|
||||
function canMove(player, pieceIdx, roll) {
|
||||
const pos = player.pieces[pieceIdx];
|
||||
|
||||
if (pos === -1) {
|
||||
// Starten nur mit 6
|
||||
return roll === 6;
|
||||
} else if (pos >= 0 && pos < 40) {
|
||||
const newPos = pos + roll;
|
||||
// Kann ins Ziel oder weiter
|
||||
if (newPos <= 43) return true;
|
||||
// Prüfen ob exakt ins Ziel
|
||||
const goalEntry = 40 + (player.id * 4); // vereinfacht
|
||||
return newPos <= goalEntry + 3;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function selectPiece(playerIdx, pieceIdx) {
|
||||
if (playerIdx !== currentPlayer || !hasRolled) return;
|
||||
|
||||
const player = players[currentPlayer];
|
||||
if (!canMove(player, pieceIdx, currentRoll)) {
|
||||
speak('Diese Figur kann nicht bewegt werden!');
|
||||
return;
|
||||
}
|
||||
|
||||
movePiece(pieceIdx);
|
||||
}
|
||||
|
||||
function movePiece(pieceIdx) {
|
||||
const player = players[currentPlayer];
|
||||
const oldPos = player.pieces[pieceIdx];
|
||||
let newPos;
|
||||
|
||||
if (oldPos === -1) {
|
||||
// Starten
|
||||
newPos = 0;
|
||||
} else {
|
||||
newPos = oldPos + currentRoll;
|
||||
}
|
||||
|
||||
player.pieces[pieceIdx] = newPos;
|
||||
|
||||
// Schmeißen?
|
||||
if (forceKickRule) {
|
||||
checkKick(player, newPos, pieceIdx);
|
||||
}
|
||||
|
||||
// Gewonnen?
|
||||
const inGoal = player.pieces.filter(p => p >= 40).length;
|
||||
if (inGoal === 4) {
|
||||
endGame(player);
|
||||
return;
|
||||
}
|
||||
|
||||
updatePieces();
|
||||
|
||||
if (currentRoll === 6) {
|
||||
throwsLeft = calculateThrows();
|
||||
hasRolled = false;
|
||||
document.getElementById('gameStatus').textContent = 'Nochmal würfeln!';
|
||||
} else {
|
||||
setTimeout(nextPlayer, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
function checkKick(player, pos, pieceIdx) {
|
||||
if (pos >= 40) return; // Im Ziel nicht schmeißen
|
||||
|
||||
players.forEach((other, idx) => {
|
||||
if (idx === currentPlayer) return;
|
||||
|
||||
other.pieces.forEach((otherPos, otherIdx) => {
|
||||
if (otherPos === pos && otherPos >= 0 && otherPos < 40) {
|
||||
other.pieces[otherIdx] = -1;
|
||||
speak(`${player.name} schmeißt ${other.name} raus!`);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function botSelectPiece(movable) {
|
||||
// Priorität: Kann schmeißen > ins Ziel > vorne
|
||||
let best = movable[0];
|
||||
|
||||
movable.forEach(({ pos, idx }) => {
|
||||
const newPos = pos === -1 ? 0 : pos + currentRoll;
|
||||
|
||||
// Kann schmeißen?
|
||||
players.forEach((other, oIdx) => {
|
||||
if (oIdx === currentPlayer) return;
|
||||
if (other.pieces.includes(newPos)) {
|
||||
best = { pos, idx };
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
movePiece(best.idx);
|
||||
}
|
||||
|
||||
function skipTurn() {
|
||||
if (!gameRunning) return;
|
||||
nextPlayer();
|
||||
}
|
||||
|
||||
function nextPlayer() {
|
||||
currentPlayer = (currentPlayer + 1) % players.length;
|
||||
currentRoll = 0;
|
||||
hasRolled = false;
|
||||
throwsLeft = calculateThrows();
|
||||
selectedPiece = null;
|
||||
|
||||
updateStatus();
|
||||
updatePieces();
|
||||
|
||||
if (players[currentPlayer].isBot) {
|
||||
setTimeout(botTurn, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
function botTurn() {
|
||||
if (!gameRunning) return;
|
||||
roll();
|
||||
}
|
||||
|
||||
function updateStatus() {
|
||||
const p = players[currentPlayer];
|
||||
document.getElementById('currentPlayerName').textContent =
|
||||
`${p.emoji} ${p.name} ist dran!`;
|
||||
document.getElementById('currentPlayerName').style.color =
|
||||
p.color === 'red' ? '#DC2626' :
|
||||
p.color === 'blue' ? '#2563EB' :
|
||||
p.color === 'green' ? '#059669' : '#D97706';
|
||||
|
||||
throwsLeft = calculateThrows();
|
||||
updateThrowIndicator();
|
||||
}
|
||||
|
||||
function updateThrowIndicator() {
|
||||
const indicator = document.getElementById('throwIndicator');
|
||||
if (throwsLeft > 1) {
|
||||
indicator.textContent = `🎲 ${throwsLeft} Würfe verbleibend`;
|
||||
} else if (throwsLeft === 1) {
|
||||
indicator.textContent = `🎲 Letzter Wurf`;
|
||||
} else {
|
||||
indicator.textContent = '';
|
||||
}
|
||||
}
|
||||
|
||||
function endGame(winner) {
|
||||
gameRunning = false;
|
||||
document.getElementById('winnerText').innerHTML =
|
||||
`🎉 ${winner.emoji} ${winner.name} hat gewonnen!`;
|
||||
document.getElementById('gameOver').style.display = 'block';
|
||||
}
|
||||
|
||||
function resetGame() {
|
||||
document.getElementById('gameScreen').style.display = 'none';
|
||||
document.getElementById('setupScreen').style.display = 'block';
|
||||
document.getElementById('gameOver').style.display = 'none';
|
||||
gameRunning = false;
|
||||
}
|
||||
|
||||
function speak(text) {
|
||||
if ('speechSynthesis' in window) {
|
||||
const u = new SpeechSynthesisUtterance(text);
|
||||
u.lang = 'de-DE';
|
||||
speechSynthesis.speak(u);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user