99 lines
3.0 KiB
JavaScript
99 lines
3.0 KiB
JavaScript
/**
|
||
* Lara Kiesewetter – Live Schachturnier
|
||
* Stockfish evaluation
|
||
*/
|
||
|
||
/* global Chess */
|
||
|
||
function syncEvalBarHeight() {
|
||
const boardEl = document.getElementById('board');
|
||
const evalContainer = document.getElementById('eval-bar-container');
|
||
if (boardEl && evalContainer) {
|
||
const h = boardEl.offsetHeight;
|
||
if (h > 100) evalContainer.style.minHeight = h + 'px';
|
||
}
|
||
}
|
||
|
||
async function updateEvaluation() {
|
||
if (!chess) return;
|
||
const fen = chess.fen();
|
||
|
||
if (lastEvalFen === fen && evalAbortController) return;
|
||
lastEvalFen = fen;
|
||
|
||
if (evalAbortController) {
|
||
evalAbortController.abort();
|
||
}
|
||
evalAbortController = new AbortController();
|
||
|
||
try {
|
||
const res = await fetch('/evaluate', {
|
||
method: 'POST',
|
||
headers: { 'Content-Type': 'application/json' },
|
||
body: JSON.stringify({ fen }),
|
||
signal: evalAbortController.signal,
|
||
});
|
||
if (!res.ok) throw new Error('Eval fehlgeschlagen');
|
||
|
||
const reader = res.body.getReader();
|
||
const decoder = new TextDecoder();
|
||
let buffer = '';
|
||
|
||
while (true) {
|
||
const { done, value } = await reader.read();
|
||
if (done) break;
|
||
|
||
buffer += decoder.decode(value, { stream: true });
|
||
const lines = buffer.split('\n');
|
||
buffer = lines.pop();
|
||
|
||
for (const line of lines) {
|
||
if (!line.trim()) continue;
|
||
try {
|
||
displayEval(JSON.parse(line));
|
||
} catch {}
|
||
}
|
||
}
|
||
|
||
if (buffer.trim()) {
|
||
try { displayEval(JSON.parse(buffer)); } catch {}
|
||
}
|
||
} catch (e) {
|
||
if (e.name === 'AbortError') return;
|
||
const el = document.getElementById('eval-score');
|
||
if (el) el.textContent = '?';
|
||
}
|
||
}
|
||
|
||
function displayEval(data) {
|
||
const evalScore = document.getElementById('eval-score');
|
||
const barFill = document.getElementById('eval-bar-fill');
|
||
const barMarker = document.getElementById('eval-bar-marker');
|
||
|
||
let scoreText = '0.00';
|
||
let fillPercent = 50;
|
||
|
||
if (data.scoreMate !== null && data.scoreMate !== undefined && data.scoreMate !== 0) {
|
||
const mate = parseInt(data.scoreMate);
|
||
const whiteMate = chess && chess.turn() === 'w' ? mate : -mate;
|
||
if (whiteMate > 0) {
|
||
scoreText = '#' + whiteMate;
|
||
fillPercent = 100;
|
||
} else {
|
||
scoreText = '#' + Math.abs(whiteMate);
|
||
fillPercent = 0;
|
||
}
|
||
} else if (data.scoreCp !== null && data.scoreCp !== undefined) {
|
||
const cp = parseInt(data.scoreCp);
|
||
const whiteCp = chess && chess.turn() === 'w' ? cp : -cp;
|
||
const pawns = (whiteCp / 100).toFixed(2);
|
||
scoreText = (whiteCp > 0 ? '+' : '') + pawns;
|
||
fillPercent = 50 + whiteCp / 14;
|
||
fillPercent = Math.max(0, Math.min(100, fillPercent));
|
||
}
|
||
|
||
evalScore.textContent = scoreText;
|
||
|
||
if (barFill) barFill.style.height = fillPercent + '%';
|
||
if (barMarker) barMarker.style.top = (100 - fillPercent) + '%';
|
||
} |