diff --git a/public/waiting.html b/public/waiting.html
index 998a2c7..272667f 100644
--- a/public/waiting.html
+++ b/public/waiting.html
@@ -28,6 +28,13 @@
+
+
+
+
@@ -54,6 +61,8 @@
const youAreHostEl = document.getElementById('youAreHost');
const autoDrawLabelEl = document.getElementById('autoDrawLabel');
const autoDrawToggleEl = document.getElementById('autoDrawToggle');
+ const noRemiseLabelEl = document.getElementById('no-remise');
+ const noRemiseToggleEl = document.getElementById('no-remiseToggle');
function log(...args){ console.log(...args); }
@@ -114,6 +123,20 @@
}
}
}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
@@ -162,6 +185,16 @@
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(_){ }
if(roomInfo && roomInfo.status === 'playing'){
// server already marked room as playing; redirect immediately
diff --git a/server.js b/server.js
index c0da89e..dca6f11 100644
--- a/server.js
+++ b/server.js
@@ -38,6 +38,7 @@ function sendRoomUpdate(room){
size: (room.boardState && room.boardState.width) || room.size,
cards: Object.keys(room.cards || {}),
autoDraw: !!room.autoDraw,
+ noRemise: !!room.noRemise,
deckCount: (room.deck && room.deck.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(room.deck.length === 0){
- // if deck empty, try to refill from discard and shuffle
- if(room.discard && room.discard.length > 0){
+ // if deck empty, try to refill from discard and shuffle — unless 'noRemise' is enabled
+ if(!room.noRemise && room.discard && room.discard.length > 0){
// move all discard into deck
room.deck = room.discard.splice(0).concat(room.deck || []);
// simple Fisher-Yates shuffle
@@ -717,7 +718,7 @@ app.post('/rooms', (req, res) => {
// hostId will be set when the first player joins
// initialize a deck for this room
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 });
});
@@ -726,7 +727,7 @@ app.get('/rooms/:id', (req, res) => {
if (!room) return res.status(404).json({ error: 'room not found' });
const boardState = room.boardState || null;
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) => {
@@ -824,6 +825,20 @@ io.on('connection', (socket) => {
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) => {
const room = rooms.get(roomId);
if (!room) return cb && cb({ error: 'room not found' });