132 lines
5.3 KiB
HTML
132 lines
5.3 KiB
HTML
<!doctype html>
|
|
<html>
|
|
<head>
|
|
<meta charset="utf-8" />
|
|
<title>ChessNut - Partie</title>
|
|
<style>body{font-family:Arial;margin:20px} input,button{padding:6px;margin:4px} #log{white-space:pre-wrap; border:1px solid #ddd;padding:8px;height:300px;overflow:auto} #players{margin:6px 0;padding-left:18px}</style>
|
|
</head>
|
|
<body>
|
|
<h2>ChessNut — Partie</h2>
|
|
<div>Room: <strong id="roomId">-</strong> Player: <strong id="playerId">-</strong></div>
|
|
<div style="display:flex;gap:20px;align-items:flex-start">
|
|
<div>
|
|
<div>Fen: <span id="fen">-</span></div>
|
|
<div>Joueurs:
|
|
<ul id="players"></ul>
|
|
</div>
|
|
</div>
|
|
<div>
|
|
<div id="board" style="width:360px;height:360px;display:grid;grid-template-columns:repeat(8,1fr);border:1px solid #333"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<h3>Événements</h3>
|
|
<div id="log">Logs...</div>
|
|
<div style="margin-top:10px"><a href="/">Retour à la page principale</a></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';
|
|
// set board background image (if available)
|
|
boardEl.style.backgroundImage = "url('/assets/chess-pieces/boards/8x8_wood.svg')";
|
|
boardEl.style.backgroundSize = 'cover';
|
|
boardEl.style.position = 'relative';
|
|
|
|
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.style.width = '100%'; sq.style.height = '100%';
|
|
sq.style.display = 'flex'; sq.style.alignItems='center'; sq.style.justifyContent='center';
|
|
boardEl.appendChild(sq);
|
|
file++;
|
|
}
|
|
} else {
|
|
const sq = document.createElement('div');
|
|
sq.style.width = '100%'; sq.style.height = '100%';
|
|
sq.style.display = 'flex'; sq.style.alignItems='center'; sq.style.justifyContent='center';
|
|
// 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.style.maxWidth = '78%';
|
|
img.style.maxHeight = '78%';
|
|
img.style.userSelect = 'none';
|
|
sq.appendChild(img);
|
|
boardEl.appendChild(sq);
|
|
file++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
</body>
|
|
</html>
|