v0.10.0 fix to engine game state mgmt, client and web ui updates to match
This commit is contained in:
@@ -120,9 +120,11 @@ function updateAuthIndicator(authenticated) {
|
||||
if (authenticated) {
|
||||
light.setAttribute('data-status', 'authenticated');
|
||||
indicator.setAttribute('data-status', gameState.username);
|
||||
indicator.setAttribute('data-tooltip', 'Account');
|
||||
} else {
|
||||
light.setAttribute('data-status', 'anonymous');
|
||||
indicator.setAttribute('data-status', 'anonymous');
|
||||
indicator.setAttribute('data-status', 'click to login');
|
||||
indicator.setAttribute('data-tooltip', 'Login');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -438,6 +440,9 @@ function updateTurnIndicator(state, turn) {
|
||||
status = 'unknown';
|
||||
tooltipText = 'Game Over';
|
||||
}
|
||||
} else if (state === 'stuck') {
|
||||
status = 'degraded';
|
||||
tooltipText = 'Engine Error';
|
||||
} else if (turn === 'w') {
|
||||
status = 'white';
|
||||
tooltipText = 'White';
|
||||
@@ -637,7 +642,10 @@ async function startNewGame() {
|
||||
initializeBoard();
|
||||
updateGameDisplay(game);
|
||||
document.getElementById('undo-btn').disabled = true;
|
||||
if (!gameState.isPlayerWhite) triggerComputerMove();
|
||||
const computerTurn = gameState.isPlayerWhite ? 'b' : 'w';
|
||||
if (isPlayable(game.state) && game.turn === computerTurn) {
|
||||
triggerComputerMove();
|
||||
}
|
||||
|
||||
setModalMessage('new-game-modal-message', `Game started - you play ${willBePlayerWhite ? 'White' : 'Black'}`, 'success');
|
||||
setTimeout(hideNewGameModal, MODAL_SUCCESS_DISPLAY_MS);
|
||||
@@ -711,7 +719,7 @@ function handleSquareClick(e) {
|
||||
if (gameState.isLocked) return;
|
||||
|
||||
// Block moves after game over
|
||||
if (isGameOver(gameState.state)) return;
|
||||
if (!isPlayable(gameState.state)) return;
|
||||
|
||||
const squareEl = e.currentTarget;
|
||||
const { square, pieceColor } = squareEl.dataset;
|
||||
@@ -776,7 +784,7 @@ async function handleHumanMove(from, to) {
|
||||
flashSquare(fromEl, true);
|
||||
flashSquare(toEl, true);
|
||||
updateGameDisplay(game);
|
||||
if (!isGameOver(game.state)) {
|
||||
if (isPlayable(game.state)) {
|
||||
triggerComputerMove();
|
||||
}
|
||||
} catch (error) {
|
||||
@@ -906,6 +914,9 @@ async function undoMoves() {
|
||||
const game = await response.json();
|
||||
gameState.state = game.state;
|
||||
updateGameDisplay(game);
|
||||
if (game.state === 'stuck') {
|
||||
flashErrorMessage('Engine error — Undo to recover or start a new game');
|
||||
}
|
||||
} catch (error) {
|
||||
if (error.message === 'Failed to fetch') {
|
||||
handleApiError('undo', error);
|
||||
@@ -1021,6 +1032,9 @@ function markMatedKing(game) {
|
||||
function isGameOver(state) {
|
||||
return ['white wins', 'black wins', 'stalemate', 'draw'].includes(state);
|
||||
}
|
||||
function isPlayable(state) {
|
||||
return !isGameOver(state) && state !== 'stuck';
|
||||
}
|
||||
|
||||
function handleApiError(action, error, response = null) {
|
||||
let serverStatus = 'degraded';
|
||||
|
||||
@@ -647,18 +647,26 @@ input[type="range"]::-webkit-slider-thumb {
|
||||
}
|
||||
|
||||
/* Auth Indicator */
|
||||
.auth-indicator {
|
||||
cursor: pointer;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 6px;
|
||||
transition: border-color .2s, background .2s;
|
||||
}
|
||||
|
||||
.auth-indicator:hover {
|
||||
border-color: var(--host-royal);
|
||||
background: rgba(95, 87, 245, 0.15);
|
||||
}
|
||||
|
||||
.auth-indicator .light[data-status="anonymous"] {
|
||||
color: var(--tokyo-border);
|
||||
color: var(--tokyo-yellow);
|
||||
}
|
||||
|
||||
.auth-indicator .light[data-status="authenticated"] {
|
||||
color: var(--tokyo-green);
|
||||
}
|
||||
|
||||
.auth-indicator {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* --- Modal status message (Issue 2) --- */
|
||||
.modal-message {
|
||||
display: none;
|
||||
@@ -871,41 +879,20 @@ input[type="range"]:disabled {
|
||||
}
|
||||
|
||||
@media (max-width: 530px) {
|
||||
body {
|
||||
overflow-y: auto;
|
||||
overflow-x: auto;
|
||||
min-width: clamp(440px, 100vw, 530px);
|
||||
body { min-width: 0; overflow-x: hidden; }
|
||||
.outer-container { width: 100%; min-width: 0; }
|
||||
.container { width: calc(100% - 16px); min-width: 0; }
|
||||
.board-container {
|
||||
width: min(92vw, 440px);
|
||||
height: min(92vw, 440px);
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
.outer-container {
|
||||
width: clamp(440px, 100vw, 530px);
|
||||
min-width: clamp(440px, 100vw, 530px);
|
||||
padding: 8px;
|
||||
min-height: 100vh;
|
||||
height: auto;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: flex-start;
|
||||
overflow: visible;
|
||||
.board-wrapper {
|
||||
width: calc(min(92vw, 440px) - 24px);
|
||||
height: calc(min(92vw, 440px) - 24px);
|
||||
}
|
||||
|
||||
.container {
|
||||
width: calc(100% - 16px);
|
||||
min-width: clamp(424px, calc(100vw - 16px), 514px);
|
||||
border-radius: 12px;
|
||||
min-height: calc(100vh - 16px);
|
||||
height: auto;
|
||||
padding: 1rem;
|
||||
margin: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.board-container,
|
||||
.info-panel {
|
||||
width: clamp(360px, 83vw, 440px);
|
||||
min-width: clamp(360px, 83vw, 440px);
|
||||
width: min(92vw, 440px);
|
||||
min-width: 0;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user