Win on stuck sheep
This commit is contained in:
@@ -408,18 +408,13 @@
|
|||||||
|
|
||||||
function updateHistory(newState, forceJump = false) {
|
function updateHistory(newState, forceJump = false) {
|
||||||
const isAtEnd = historyIndex === history.length - 1;
|
const isAtEnd = historyIndex === history.length - 1;
|
||||||
|
|
||||||
if (newState.moveCount === 0) {
|
if (newState.moveCount === 0) {
|
||||||
history = [JSON.parse(JSON.stringify(newState))];
|
history = [JSON.parse(JSON.stringify(newState))];
|
||||||
} else if (!state || newState.moveCount > state.moveCount) {
|
} else if (!state || newState.moveCount > state.moveCount) {
|
||||||
history.push(JSON.parse(JSON.stringify(newState)));
|
history.push(JSON.parse(JSON.stringify(newState)));
|
||||||
}
|
}
|
||||||
|
|
||||||
state = newState;
|
state = newState;
|
||||||
// Only jump the view to the latest state if the player was already at the end or if forced (like on restart)
|
if (isAtEnd || forceJump) historyIndex = history.length - 1;
|
||||||
if (isAtEnd || forceJump) {
|
|
||||||
historyIndex = history.length - 1;
|
|
||||||
}
|
|
||||||
render();
|
render();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -427,7 +422,6 @@
|
|||||||
if (isLocal) return initLocalState();
|
if (isLocal) return initLocalState();
|
||||||
const protocol = location.protocol === "https:" ? "wss" : "ws";
|
const protocol = location.protocol === "https:" ? "wss" : "ws";
|
||||||
ws = new WebSocket(`${protocol}://${location.host}?room=${roomId}&sessionId=${sessionId}`);
|
ws = new WebSocket(`${protocol}://${location.host}?room=${roomId}&sessionId=${sessionId}`);
|
||||||
|
|
||||||
ws.onopen = () => document.getElementById("dot").classList.add("conn-online");
|
ws.onopen = () => document.getElementById("dot").classList.add("conn-online");
|
||||||
ws.onmessage = e => {
|
ws.onmessage = e => {
|
||||||
const msg = JSON.parse(e.data);
|
const msg = JSON.parse(e.data);
|
||||||
@@ -447,27 +441,16 @@
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keyboard controls for Navigation
|
|
||||||
window.addEventListener("keydown", (e) => {
|
window.addEventListener("keydown", (e) => {
|
||||||
if (history.length === 0) return;
|
if (history.length === 0) return;
|
||||||
|
|
||||||
switch (e.key) {
|
switch (e.key) {
|
||||||
case "ArrowLeft":
|
case "ArrowLeft": if (historyIndex > 0) historyIndex--; break;
|
||||||
if (historyIndex > 0) historyIndex--;
|
case "ArrowRight": if (historyIndex < history.length - 1) historyIndex++; break;
|
||||||
break;
|
case "ArrowUp": historyIndex = history.length - 1; break;
|
||||||
case "ArrowRight":
|
case "ArrowDown": historyIndex = 0; break;
|
||||||
if (historyIndex < history.length - 1) historyIndex++;
|
default: return;
|
||||||
break;
|
|
||||||
case "ArrowUp": // Jump to Present
|
|
||||||
historyIndex = history.length - 1;
|
|
||||||
break;
|
|
||||||
case "ArrowDown": // Jump to Start
|
|
||||||
historyIndex = 0;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return; // Exit if other key
|
|
||||||
}
|
}
|
||||||
selected = null; // Clear selection when moving through time
|
selected = null;
|
||||||
render();
|
render();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -482,24 +465,33 @@
|
|||||||
|
|
||||||
nextState.moveCount++;
|
nextState.moveCount++;
|
||||||
nextState.winner = checkWinConditions(nextState);
|
nextState.winner = checkWinConditions(nextState);
|
||||||
|
|
||||||
// Branch history
|
|
||||||
history = history.slice(0, historyIndex + 1);
|
history = history.slice(0, historyIndex + 1);
|
||||||
updateHistory(nextState, true);
|
updateHistory(nextState, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkWinConditions(g) {
|
function checkWinConditions(g) {
|
||||||
|
// 1. Wolf reaches sheep starting line (Row 0)
|
||||||
if (g.wolf === 0) return "wolf";
|
if (g.wolf === 0) return "wolf";
|
||||||
|
|
||||||
|
// 2. Max moves reached
|
||||||
if (g.moveCount >= 40) return "wolf";
|
if (g.moveCount >= 40) return "wolf";
|
||||||
|
|
||||||
|
// 3. Wolf is trapped
|
||||||
const canWolfMove = bWolf[g.wolf].some(to => !g.sheep.includes(to));
|
const canWolfMove = bWolf[g.wolf].some(to => !g.sheep.includes(to));
|
||||||
if (!canWolfMove) return "sheep";
|
if (!canWolfMove) return "sheep";
|
||||||
|
|
||||||
|
// 4. Sheep are trapped (Wolf wins)
|
||||||
|
const canAnySheepMove = g.sheep.some(sPos => {
|
||||||
|
return bSheep[sPos].some(to => to !== g.wolf && !g.sheep.includes(to));
|
||||||
|
});
|
||||||
|
if (!canAnySheepMove) return "wolf";
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function render() {
|
function render() {
|
||||||
const viewState = history[historyIndex];
|
const viewState = history[historyIndex];
|
||||||
if (!viewState) return;
|
if (!viewState) return;
|
||||||
|
|
||||||
const isViewingHistory = historyIndex < history.length - 1;
|
const isViewingHistory = historyIndex < history.length - 1;
|
||||||
const svg = document.querySelector("svg");
|
const svg = document.querySelector("svg");
|
||||||
svg.innerHTML = "";
|
svg.innerHTML = "";
|
||||||
@@ -541,7 +533,6 @@
|
|||||||
const isSheep = viewState.sheep.includes(i);
|
const isSheep = viewState.sheep.includes(i);
|
||||||
const type = isWolf ? "wolf" : (isSheep ? "sheep" : "empty");
|
const type = isWolf ? "wolf" : (isSheep ? "sheep" : "empty");
|
||||||
const isWinnerPiece = (viewState.winner === "wolf" && isWolf) || (viewState.winner === "sheep" && isSheep);
|
const isWinnerPiece = (viewState.winner === "wolf" && isWolf) || (viewState.winner === "sheep" && isSheep);
|
||||||
|
|
||||||
const canInteract = isLocal || (!isViewingHistory && state.turn === myRole);
|
const canInteract = isLocal || (!isViewingHistory && state.turn === myRole);
|
||||||
const isPossible = canInteract && selected !== null && (viewState.turn === "wolf" ? bWolf[selected] : bSheep[selected]).includes(i) && !isWolf && !isSheep;
|
const isPossible = canInteract && selected !== null && (viewState.turn === "wolf" ? bWolf[selected] : bSheep[selected]).includes(i) && !isWolf && !isSheep;
|
||||||
|
|
||||||
@@ -549,7 +540,6 @@
|
|||||||
g.onclick = () => {
|
g.onclick = () => {
|
||||||
if (viewState.winner || (!isLocal && isViewingHistory)) return;
|
if (viewState.winner || (!isLocal && isViewingHistory)) return;
|
||||||
if (!isLocal && state.turn !== myRole) return;
|
if (!isLocal && state.turn !== myRole) return;
|
||||||
|
|
||||||
const isMine = (viewState.turn === "wolf" && isWolf) || (viewState.turn === "sheep" && isSheep);
|
const isMine = (viewState.turn === "wolf" && isWolf) || (viewState.turn === "sheep" && isSheep);
|
||||||
if (isMine) selected = i;
|
if (isMine) selected = i;
|
||||||
else if (isPossible) {
|
else if (isPossible) {
|
||||||
|
|||||||
Reference in New Issue
Block a user