ChessNut/public/game.html
2025-11-08 18:05:15 +01:00

115 lines
4.2 KiB
HTML

<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>ChessNut - Partie</title>
<link rel="stylesheet" href="/styles/style.css">
</head>
<body>
<h2>ChessNut — Partie</h2>
<div>Room: <strong id="roomId">-</strong>
<div class="layout-row">
<div>
<div id="board"></div>
</div>
</div>
<script src="https://cdn.socket.io/4.7.2/socket.io.min.js"></script>
<script>
function qs(name){ const url = new URL(window.location.href); return url.searchParams.get(name); }
const roomId = qs('roomId');
const playerId = qs('playerId') || undefined;
document.getElementById('roomId').textContent = roomId || '-';
document.getElementById('playerId').textContent = playerId || '-';
const logEl = document.getElementById('log');
const fenEl = document.getElementById('fen');
const playersEl = document.getElementById('players');
const boardEl = document.getElementById('board');
let socket = null;
function log(...args){ logEl.textContent += '\n' + args.map(a=>typeof a==='object'?JSON.stringify(a):a).join(' '); logEl.scrollTop = logEl.scrollHeight; }
if(!roomId){ alert('roomId manquant dans l\'URL'); }
function connectAndJoin(){
socket = io();
socket.on('connect', ()=>{ log('socket connecté', socket.id); });
socket.on('room:update', (data)=>{
log('room:update', data);
fenEl.textContent = data.fen || '-';
playersEl.innerHTML = '';
(data.players||[]).forEach(p=>{
const li = document.createElement('li');
li.textContent = p.id + ' (' + p.color + ')';
playersEl.appendChild(li);
});
if(data.fen) renderFen(data.fen);
});
socket.on('move:moved', (data)=>{ log('move:moved', data); fenEl.textContent = data.fen; renderFen(data.fen); });
socket.on('game:over', (data)=>{ log('game:over', data); fenEl.textContent = data.fen; renderFen(data.fen); });
socket.on('game:started', (data)=>{ log('game:started', data); fenEl.textContent = data.fen || '-'; renderFen(data.fen || ''); });
socket.emit('room:join', { roomId, playerId }, (resp)=>{
if(resp && resp.error){ log('join error', resp); alert(resp.error); return; }
log('Rejoint room', resp);
});
}
connectAndJoin();
document.getElementById('move').addEventListener('click', ()=>{
if(!socket){ alert('non connecté'); return; }
const from = document.getElementById('from').value.trim();
const to = document.getElementById('to').value.trim();
const promotion = document.getElementById('promo').value.trim() || undefined;
socket.emit('game:move', { roomId, from, to, promotion }, (resp)=>{
if(resp && resp.error) { log('move error', resp); alert(resp.error); return; }
log('move accepted', resp);
});
});
// Board rendering using provided SVG assets. Accepts FEN.
const pieceSetPath = '/assets/chess-pieces/chess_1Kbyte_gambit';
// board visual defaults are handled by CSS (background, size, border, position)
function renderFen(fen){
if(!fen) return;
const parts = fen.split(' ');
const rows = parts[0].split('/');
boardEl.innerHTML = '';
for(let r=0;r<8;r++){
const row = rows[r];
let file = 0;
for(let i=0;i<row.length;i++){
const ch = row[i];
if(/[1-8]/.test(ch)){
const empties = parseInt(ch,10);
for(let e=0;e<empties;e++){
const sq = document.createElement('div');
sq.className = 'square';
boardEl.appendChild(sq);
file++;
}
} else {
const sq = document.createElement('div');
sq.className = 'square';
// determine filename from piece char
const isWhite = (ch === ch.toUpperCase());
const letter = ch.toUpperCase();
const filename = (isWhite ? 'w' + letter : 'b' + letter) + '.svg';
const img = document.createElement('img');
img.src = `${pieceSetPath}/${filename}`;
img.className = 'piece';
sq.appendChild(img);
boardEl.appendChild(sq);
file++;
}
}
}
}
</script>
</body>
</html>