otpion "sans remise"
This commit is contained in:
parent
b35694c730
commit
c00a3ce3b1
2 changed files with 52 additions and 4 deletions
|
|
@ -28,6 +28,13 @@
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div style="margin-top:8px">
|
||||||
|
<label id="no-remise" style="display:none;align-items:center;gap:8px;">
|
||||||
|
<input type="checkbox" id="no-remiseToggle" />
|
||||||
|
Sans remise
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div style="margin-top:8px">
|
<div style="margin-top:8px">
|
||||||
<button id="startBtn" style="display:none" class="btn-cta">Commencer la partie</button>
|
<button id="startBtn" style="display:none" class="btn-cta">Commencer la partie</button>
|
||||||
<button id="copyInviteBtn" style="margin-left:8px" class="btn-ghost">Copier le lien d'invitation</button>
|
<button id="copyInviteBtn" style="margin-left:8px" class="btn-ghost">Copier le lien d'invitation</button>
|
||||||
|
|
@ -54,6 +61,8 @@
|
||||||
const youAreHostEl = document.getElementById('youAreHost');
|
const youAreHostEl = document.getElementById('youAreHost');
|
||||||
const autoDrawLabelEl = document.getElementById('autoDrawLabel');
|
const autoDrawLabelEl = document.getElementById('autoDrawLabel');
|
||||||
const autoDrawToggleEl = document.getElementById('autoDrawToggle');
|
const autoDrawToggleEl = document.getElementById('autoDrawToggle');
|
||||||
|
const noRemiseLabelEl = document.getElementById('no-remise');
|
||||||
|
const noRemiseToggleEl = document.getElementById('no-remiseToggle');
|
||||||
|
|
||||||
function log(...args){ console.log(...args); }
|
function log(...args){ console.log(...args); }
|
||||||
|
|
||||||
|
|
@ -114,6 +123,20 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}catch(_){ }
|
}catch(_){ }
|
||||||
|
// update no-remise UI if server provides it
|
||||||
|
try{
|
||||||
|
if(typeof data.noRemise !== 'undefined' && noRemiseLabelEl && noRemiseToggleEl){
|
||||||
|
// show the control only to the host
|
||||||
|
if(myPlayerId && roomHostId && myPlayerId === roomHostId){
|
||||||
|
noRemiseLabelEl.style.display = 'inline-flex';
|
||||||
|
noRemiseToggleEl.checked = !!data.noRemise;
|
||||||
|
noRemiseToggleEl.disabled = false;
|
||||||
|
} else {
|
||||||
|
// hide control for non-hosts
|
||||||
|
noRemiseLabelEl.style.display = 'none';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}catch(_){ }
|
||||||
});
|
});
|
||||||
|
|
||||||
// register game started handler early so we don't miss the broadcast
|
// register game started handler early so we don't miss the broadcast
|
||||||
|
|
@ -162,6 +185,16 @@
|
||||||
if(autoDrawLabelEl) autoDrawLabelEl.style.display = 'none';
|
if(autoDrawLabelEl) autoDrawLabelEl.style.display = 'none';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// set no-remise independently so host sees it even if autoDraw is undefined
|
||||||
|
try{
|
||||||
|
if(roomInfo && typeof roomInfo.noRemise !== 'undefined'){
|
||||||
|
if(myPlayerId && roomHostId && myPlayerId === roomHostId){
|
||||||
|
if(noRemiseLabelEl && noRemiseToggleEl){ noRemiseLabelEl.style.display = 'inline-flex'; noRemiseToggleEl.checked = !!roomInfo.noRemise; noRemiseToggleEl.disabled = false; }
|
||||||
|
} else {
|
||||||
|
if(noRemiseLabelEl) noRemiseLabelEl.style.display = 'none';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}catch(_){ }
|
||||||
}catch(_){ }
|
}catch(_){ }
|
||||||
if(roomInfo && roomInfo.status === 'playing'){
|
if(roomInfo && roomInfo.status === 'playing'){
|
||||||
// server already marked room as playing; redirect immediately
|
// server already marked room as playing; redirect immediately
|
||||||
|
|
|
||||||
23
server.js
23
server.js
|
|
@ -38,6 +38,7 @@ function sendRoomUpdate(room){
|
||||||
size: (room.boardState && room.boardState.width) || room.size,
|
size: (room.boardState && room.boardState.width) || room.size,
|
||||||
cards: Object.keys(room.cards || {}),
|
cards: Object.keys(room.cards || {}),
|
||||||
autoDraw: !!room.autoDraw,
|
autoDraw: !!room.autoDraw,
|
||||||
|
noRemise: !!room.noRemise,
|
||||||
deckCount: (room.deck && room.deck.length) || 0,
|
deckCount: (room.deck && room.deck.length) || 0,
|
||||||
discardCount: (room.discard && room.discard.length) || 0
|
discardCount: (room.discard && room.discard.length) || 0
|
||||||
};
|
};
|
||||||
|
|
@ -296,8 +297,8 @@ function drawCardForPlayer(room, playerId){
|
||||||
}
|
}
|
||||||
if(hand.length >= 5) return null; // hand full
|
if(hand.length >= 5) return null; // hand full
|
||||||
if(room.deck.length === 0){
|
if(room.deck.length === 0){
|
||||||
// if deck empty, try to refill from discard and shuffle
|
// if deck empty, try to refill from discard and shuffle — unless 'noRemise' is enabled
|
||||||
if(room.discard && room.discard.length > 0){
|
if(!room.noRemise && room.discard && room.discard.length > 0){
|
||||||
// move all discard into deck
|
// move all discard into deck
|
||||||
room.deck = room.discard.splice(0).concat(room.deck || []);
|
room.deck = room.discard.splice(0).concat(room.deck || []);
|
||||||
// simple Fisher-Yates shuffle
|
// simple Fisher-Yates shuffle
|
||||||
|
|
@ -717,7 +718,7 @@ app.post('/rooms', (req, res) => {
|
||||||
// hostId will be set when the first player joins
|
// hostId will be set when the first player joins
|
||||||
// initialize a deck for this room
|
// initialize a deck for this room
|
||||||
const deck = buildDefaultDeck();
|
const deck = buildDefaultDeck();
|
||||||
rooms.set(id, { id, boardState, players: [], status: 'waiting', hostId: null, size, cards: {}, playedCards: [], removalTimers: new Map(), deck, hands: {}, autoDraw: false });
|
rooms.set(id, { id, boardState, players: [], status: 'waiting', hostId: null, size, cards: {}, playedCards: [], removalTimers: new Map(), deck, hands: {}, autoDraw: false, noRemise: false });
|
||||||
res.json({ roomId: id, size });
|
res.json({ roomId: id, size });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -726,7 +727,7 @@ app.get('/rooms/:id', (req, res) => {
|
||||||
if (!room) return res.status(404).json({ error: 'room not found' });
|
if (!room) return res.status(404).json({ error: 'room not found' });
|
||||||
const boardState = room.boardState || null;
|
const boardState = room.boardState || null;
|
||||||
const size = (room.boardState && room.boardState.width) || room.size;
|
const size = (room.boardState && room.boardState.width) || room.size;
|
||||||
res.json({ id: room.id, boardState, size: size, players: room.players.map(p => ({ id: p.id, color: p.color })), status: room.status, hostId: room.hostId, cards: Object.keys(room.cards || {}), autoDraw: !!room.autoDraw });
|
res.json({ id: room.id, boardState, size: size, players: room.players.map(p => ({ id: p.id, color: p.color })), status: room.status, hostId: room.hostId, cards: Object.keys(room.cards || {}), autoDraw: !!room.autoDraw, noRemise: !!room.noRemise });
|
||||||
});
|
});
|
||||||
|
|
||||||
io.on('connection', (socket) => {
|
io.on('connection', (socket) => {
|
||||||
|
|
@ -824,6 +825,20 @@ io.on('connection', (socket) => {
|
||||||
return cb && cb({ ok: true, autoDraw: room.autoDraw });
|
return cb && cb({ ok: true, autoDraw: room.autoDraw });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Host can toggle the 'no remise' flag (prevent reshuffling discard into deck). Only the host may change this setting.
|
||||||
|
socket.on('room:no_remise:set', ({ roomId, enabled }, cb) => {
|
||||||
|
const room = rooms.get(roomId);
|
||||||
|
if(!room) return cb && cb({ error: 'room not found' });
|
||||||
|
const sender = socket.data.playerId;
|
||||||
|
if(!sender) return cb && cb({ error: 'not joined' });
|
||||||
|
if(room.hostId !== sender) return cb && cb({ error: 'only the host can change no-remise' });
|
||||||
|
room.noRemise = !!enabled;
|
||||||
|
// Broadcast updated room state to all participants
|
||||||
|
try{ sendRoomUpdate(room); }catch(_){ }
|
||||||
|
try{ io.to(room.id).emit('room:no_remise:changed', { roomId: room.id, enabled: room.noRemise }); }catch(_){ }
|
||||||
|
return cb && cb({ ok: true, noRemise: room.noRemise });
|
||||||
|
});
|
||||||
|
|
||||||
socket.on('game:move', ({ roomId, from, to, promotion }, cb) => {
|
socket.on('game:move', ({ roomId, from, to, promotion }, cb) => {
|
||||||
const room = rooms.get(roomId);
|
const room = rooms.get(roomId);
|
||||||
if (!room) return cb && cb({ error: 'room not found' });
|
if (!room) return cb && cb({ error: 'room not found' });
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue