removed moves
This commit is contained in:
parent
edc864a2ad
commit
580775e6b1
3 changed files with 121 additions and 59 deletions
141
public/game.html
141
public/game.html
|
|
@ -17,10 +17,7 @@
|
|||
<section class="card" style="margin-top:12px">
|
||||
<div><strong>Outils / Logs</strong></div>
|
||||
<div style="margin-top:8px">
|
||||
<input id="from" placeholder="from (e2)" style="width:90px" />
|
||||
<input id="to" placeholder="to (e4)" style="width:90px" />
|
||||
<input id="promo" placeholder="promo (q,r)" style="width:80px" />
|
||||
<button id="move">Envoyer</button>
|
||||
<!-- movement controls removed as requested -->
|
||||
</div>
|
||||
<pre id="log" style="margin-top:8px;height:160px;overflow:auto">logs...</pre>
|
||||
</section>
|
||||
|
|
@ -44,6 +41,12 @@
|
|||
const myColorEl = document.getElementById('myColor');
|
||||
let socket = null;
|
||||
let myColor = null;
|
||||
// selection state for this client
|
||||
let selectedSquare = null; // algebraic name like 'e2'
|
||||
let selectedSquareEl = null;
|
||||
let myPlayerId = playerId || null;
|
||||
// track remote selections: { playerId: square }
|
||||
const remoteSelections = {};
|
||||
|
||||
// safe logger: prefer on-page log if present, otherwise console
|
||||
function log(...args){
|
||||
|
|
@ -84,15 +87,31 @@
|
|||
}
|
||||
if(data.boardState) renderBoardFromState(data.boardState);
|
||||
});
|
||||
socket.on('move:moved', (data)=>{ log('move:moved', data); if(data.boardState) renderBoardFromState(data.boardState); });
|
||||
socket.on('game:over', (data)=>{ log('game:over', data); if(data.boardState) renderBoardFromState(data.boardState); });
|
||||
socket.on('game:started', (data)=>{ log('game:started', data); if(data.boardState) renderBoardFromState(data.boardState); });
|
||||
// selection events broadcasted by other clients
|
||||
socket.on('game:select', (data) => {
|
||||
try{
|
||||
const pid = data && data.playerId;
|
||||
const square = data && data.square;
|
||||
// ignore our own (some transports might echo)
|
||||
if(pid === myPlayerId) return;
|
||||
if(!pid) return;
|
||||
if(!square){
|
||||
// clear remote selection for that player
|
||||
clearRemoteSelection(pid);
|
||||
return;
|
||||
}
|
||||
setRemoteSelection(pid, square);
|
||||
}catch(e){ console.warn('game:select handler error', e); }
|
||||
});
|
||||
|
||||
socket.emit('room:join', { roomId, playerId }, (resp)=>{
|
||||
if(resp && resp.error){ log('join error', resp); alert(resp.error); return; }
|
||||
log('Rejoint room', resp);
|
||||
// remember assigned id/color from server
|
||||
if(resp.playerId){
|
||||
myPlayerId = resp.playerId;
|
||||
if(playerIdEl) playerIdEl.textContent = resp.playerId;
|
||||
}
|
||||
if(resp.color){
|
||||
|
|
@ -109,26 +128,59 @@
|
|||
|
||||
connectAndJoin();
|
||||
|
||||
// show markers for legal moves when clicking any square (any piece color)
|
||||
function clearLegalMarkers(){
|
||||
const prev = boardEl.querySelectorAll('.move-marker');
|
||||
prev.forEach(p=>p.remove());
|
||||
// movement UI removed: legalMoves and move markers are disabled
|
||||
|
||||
// selection helpers (client-side)
|
||||
function clearSelection(emit = true){
|
||||
if(selectedSquareEl){
|
||||
selectedSquareEl.classList.remove('selected');
|
||||
}
|
||||
selectedSquare = null;
|
||||
selectedSquareEl = null;
|
||||
const fromEl = document.getElementById('from');
|
||||
if(fromEl) fromEl.value = '';
|
||||
// notify others that we cleared selection
|
||||
if(emit && socket && myPlayerId){
|
||||
socket.emit('game:select', { roomId, square: null }, ()=>{});
|
||||
}
|
||||
}
|
||||
|
||||
function showLegalMoves(moves){
|
||||
clearLegalMarkers();
|
||||
(moves||[]).forEach(m => {
|
||||
const to = m.to || (m.move && m.move.to);
|
||||
if(!to) return;
|
||||
const target = boardEl.querySelector(`.square[data-square="${to}"]`);
|
||||
if(!target) return;
|
||||
const marker = document.createElement('div');
|
||||
marker.className = 'move-marker';
|
||||
// store metadata if needed later
|
||||
marker.dataset.from = m.from || '';
|
||||
marker.dataset.to = to;
|
||||
target.appendChild(marker);
|
||||
});
|
||||
function setSelection(squareName, emit = true){
|
||||
if(!squareName) return clearSelection(emit);
|
||||
if(selectedSquareEl) selectedSquareEl.classList.remove('selected');
|
||||
const sqEl = boardEl.querySelector(`.square[data-square="${squareName}"]`);
|
||||
if(!sqEl){ selectedSquare = null; selectedSquareEl = null; return; }
|
||||
selectedSquare = squareName;
|
||||
selectedSquareEl = sqEl;
|
||||
sqEl.classList.add('selected');
|
||||
const fromEl = document.getElementById('from');
|
||||
if(fromEl) fromEl.value = squareName;
|
||||
// notify others of our selection
|
||||
if(emit && socket && myPlayerId){
|
||||
socket.emit('game:select', { roomId, square: squareName }, ()=>{});
|
||||
}
|
||||
}
|
||||
|
||||
// remote selection helpers: mark a square as selected by another player
|
||||
function setRemoteSelection(playerId, squareName){
|
||||
// clear previous for that player
|
||||
clearRemoteSelection(playerId);
|
||||
const sqEl = boardEl.querySelector(`.square[data-square="${squareName}"]`);
|
||||
if(!sqEl) return;
|
||||
remoteSelections[playerId] = squareName;
|
||||
sqEl.classList.add('selected-remote');
|
||||
sqEl.dataset.selectedBy = playerId;
|
||||
}
|
||||
|
||||
function clearRemoteSelection(playerId){
|
||||
const prev = remoteSelections[playerId];
|
||||
if(!prev) return;
|
||||
const prevEl = boardEl.querySelector(`.square[data-square="${prev}"]`);
|
||||
if(prevEl){
|
||||
prevEl.classList.remove('selected-remote');
|
||||
delete prevEl.dataset.selectedBy;
|
||||
}
|
||||
delete remoteSelections[playerId];
|
||||
}
|
||||
|
||||
if(boardEl){
|
||||
|
|
@ -137,32 +189,20 @@
|
|||
if(!sqEl) return;
|
||||
const square = sqEl.getAttribute('data-square');
|
||||
if(!square) return;
|
||||
if(socket){
|
||||
socket.emit('game:legalMoves', { roomId, square }, (resp)=>{
|
||||
if(resp && resp.error){ log('legalMoves error', resp); clearLegalMarkers(); return; }
|
||||
log('legalMoves for', square, resp.moves || resp);
|
||||
showLegalMoves(resp.moves || []);
|
||||
});
|
||||
|
||||
// clicked a piece -> select it (no legal moves requested)
|
||||
const pieceImg = ev.target.closest && ev.target.closest('img.piece');
|
||||
if(pieceImg){
|
||||
setSelection(square);
|
||||
return;
|
||||
}
|
||||
|
||||
// default: clicked empty square -> clear selection
|
||||
clearSelection();
|
||||
});
|
||||
}
|
||||
|
||||
const moveBtn = document.getElementById('move');
|
||||
if(moveBtn){
|
||||
moveBtn.addEventListener('click', ()=>{
|
||||
if(!socket){ alert('non connecté'); return; }
|
||||
const fromEl = document.getElementById('from');
|
||||
const toEl = document.getElementById('to');
|
||||
const promoEl = document.getElementById('promo');
|
||||
const from = fromEl ? fromEl.value.trim() : '';
|
||||
const to = toEl ? toEl.value.trim() : '';
|
||||
const promotion = promoEl ? promoEl.value.trim() || undefined : 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);
|
||||
});
|
||||
});
|
||||
}
|
||||
// move button removed
|
||||
|
||||
// Board rendering using provided SVG assets and `boardState` JSON.
|
||||
const pieceSetPath = '/assets/chess-pieces/chess_maestro_bw';
|
||||
|
|
@ -187,6 +227,17 @@
|
|||
img.className = 'piece';
|
||||
sqEl.appendChild(img);
|
||||
});
|
||||
|
||||
// re-apply selection if the previously selected square still exists
|
||||
if(selectedSquare){
|
||||
// re-apply local selection without re-emitting
|
||||
setSelection(selectedSquare, false);
|
||||
}
|
||||
// re-apply remote selections
|
||||
Object.entries(remoteSelections).forEach(([pid, sq]) => {
|
||||
const el = boardEl.querySelector(`.square[data-square="${sq}"]`);
|
||||
if(el) el.classList.add('selected-remote');
|
||||
});
|
||||
}
|
||||
|
||||
// build grid with independent square elements and data-square attributes
|
||||
|
|
|
|||
|
|
@ -49,12 +49,23 @@ a:hover{text-decoration:underline}
|
|||
|
||||
/* marker shown on target squares for legal moves */
|
||||
.square{position:relative}
|
||||
.square .move-marker{
|
||||
position:absolute;
|
||||
left:50%;top:50%;transform:translate(-50%,-50%);
|
||||
width:18%;height:18%;border-radius:50%;pointer-events:none;background:rgba(96,165,250,0.95);
|
||||
box-shadow:0 2px 6px rgba(2,6,23,0.6);z-index:3
|
||||
/* move markers removed */
|
||||
|
||||
/* highlighted/selected square when a player selects a piece */
|
||||
.square.selected{
|
||||
outline: 3px solid rgba(245,158,11,0.95); /* amber */
|
||||
box-shadow: inset 0 0 0 3px rgba(245,158,11,0.08), 0 8px 24px rgba(245,158,11,0.06);
|
||||
z-index: 4;
|
||||
}
|
||||
.square.selected .piece{transform: scale(1.06); transition: transform 140ms ease}
|
||||
|
||||
/* remote selection (other player's selection) */
|
||||
.square.selected-remote{
|
||||
outline: 3px solid rgba(59,130,246,0.95); /* blue */
|
||||
box-shadow: inset 0 0 0 3px rgba(59,130,246,0.06), 0 6px 16px rgba(59,130,246,0.04);
|
||||
z-index: 3;
|
||||
}
|
||||
.square.selected-remote .piece{transform: scale(1.02); transition: transform 140ms ease}
|
||||
|
||||
/* basic checkerboard coloring */
|
||||
.square.light{background: linear-gradient(180deg, rgba(255,255,255,0.02), rgba(255,255,255,0.01));}
|
||||
|
|
|
|||
18
server.js
18
server.js
|
|
@ -200,16 +200,16 @@ io.on('connection', (socket) => {
|
|||
});
|
||||
|
||||
// delegates to `computeLegalMoves` which is a stub you should implement.
|
||||
socket.on('game:legalMoves', ({ roomId, square }, cb) => {
|
||||
// legalMoves API removed (movement UI disabled)
|
||||
|
||||
// propagate selection made by one client to the other clients in the same room
|
||||
socket.on('game:select', ({ roomId, square }, cb) => {
|
||||
const room = rooms.get(roomId);
|
||||
if (!room) return cb && cb({ error: 'room not found' });
|
||||
try{
|
||||
const moves = computeLegalMoves(room, square) || [];
|
||||
return cb && cb({ ok: true, moves });
|
||||
}catch(e){
|
||||
console.error('game:legalMoves error', e);
|
||||
return cb && cb({ error: 'invalid square', moves: [] });
|
||||
}
|
||||
if(!room) return cb && cb({ error: 'room not found' });
|
||||
const playerId = socket.data.playerId || null;
|
||||
// broadcast to other sockets in the room (exclude sender)
|
||||
socket.to(roomId).emit('game:select', { playerId, square });
|
||||
cb && cb({ ok: true });
|
||||
});
|
||||
|
||||
// Simple cards API via sockets: list/play
|
||||
|
|
|
|||
Loading…
Reference in a new issue