Add turn timer functionality to Table class; update environment configuration
This commit is contained in:
@@ -20,3 +20,4 @@ MIN_BET=10
|
||||
MAX_BET=500
|
||||
ROUND_START_DELAY_MS=3000
|
||||
ROUND_RESET_DELAY_MS=5000
|
||||
TURN_TIME_MS=15000
|
||||
|
||||
@@ -5,6 +5,7 @@ const MIN_BET = Number(process.env.MIN_BET || 10);
|
||||
const MAX_BET = Number(process.env.MAX_BET || 100);
|
||||
const ROUND_START_DELAY_MS = Number(process.env.ROUND_START_DELAY_MS || 3000);
|
||||
const ROUND_RESET_DELAY_MS = Number(process.env.ROUND_RESET_DELAY_MS || 5000);
|
||||
const TURN_TIME_MS = Number(process.env.TURN_TIME_MS || 15000);
|
||||
|
||||
class Table {
|
||||
constructor(id, seatCount) {
|
||||
@@ -26,6 +27,9 @@ class Table {
|
||||
this.roundId = 0;
|
||||
this.roundTimeout = null;
|
||||
this.resetTimeout = null;
|
||||
this.turnTimeout = null;
|
||||
this.turnEndsAt = null;
|
||||
this.turnCounter = 0;
|
||||
this.clients = new Set();
|
||||
}
|
||||
|
||||
@@ -55,6 +59,7 @@ class Table {
|
||||
minBet: MIN_BET,
|
||||
maxBet: MAX_BET,
|
||||
roundId: this.roundId,
|
||||
turnEndsAt: this.turnEndsAt,
|
||||
dealerHand,
|
||||
currentSeatIndex: this.currentSeatIndex,
|
||||
seats: this.seats.map((seat, index) => ({
|
||||
@@ -103,6 +108,36 @@ class Table {
|
||||
}
|
||||
}
|
||||
|
||||
clearTurnTimer() {
|
||||
if (this.turnTimeout) {
|
||||
clearTimeout(this.turnTimeout);
|
||||
}
|
||||
this.turnTimeout = null;
|
||||
this.turnEndsAt = null;
|
||||
}
|
||||
|
||||
startTurnTimer() {
|
||||
this.clearTurnTimer();
|
||||
if (this.currentSeatIndex === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.turnEndsAt = Date.now() + TURN_TIME_MS;
|
||||
const turnToken = ++this.turnCounter;
|
||||
|
||||
this.turnTimeout = setTimeout(() => {
|
||||
if (this.turnCounter !== turnToken) {
|
||||
return;
|
||||
}
|
||||
const seat = this.seats[this.currentSeatIndex];
|
||||
if (!seat || seat.status !== 'playing') {
|
||||
return;
|
||||
}
|
||||
seat.status = 'stood';
|
||||
void this.advanceTurn();
|
||||
}, TURN_TIME_MS);
|
||||
}
|
||||
|
||||
findSeatIndexByUser(userId) {
|
||||
return this.seats.findIndex((seat) => seat.userId === userId);
|
||||
}
|
||||
@@ -251,6 +286,7 @@ class Table {
|
||||
return;
|
||||
}
|
||||
|
||||
this.clearTurnTimer();
|
||||
this.phase = 'playing';
|
||||
this.roundId += 1;
|
||||
this.deck = shuffle(createDeck());
|
||||
@@ -272,6 +308,7 @@ class Table {
|
||||
return;
|
||||
}
|
||||
|
||||
this.startTurnTimer();
|
||||
this.broadcastState();
|
||||
}
|
||||
|
||||
@@ -310,6 +347,8 @@ class Table {
|
||||
} else if (value === 21) {
|
||||
seat.status = 'stood';
|
||||
await this.advanceTurn();
|
||||
} else {
|
||||
this.startTurnTimer();
|
||||
}
|
||||
} else if (action === 'stand') {
|
||||
seat.status = 'stood';
|
||||
@@ -343,15 +382,18 @@ class Table {
|
||||
async advanceTurn() {
|
||||
const nextIndex = this.nextPlayableSeatIndex(this.currentSeatIndex ?? -1);
|
||||
if (nextIndex === null) {
|
||||
this.clearTurnTimer();
|
||||
await this.dealerTurn();
|
||||
return;
|
||||
}
|
||||
|
||||
this.currentSeatIndex = nextIndex;
|
||||
this.startTurnTimer();
|
||||
this.broadcastState();
|
||||
}
|
||||
|
||||
async dealerTurn() {
|
||||
this.clearTurnTimer();
|
||||
this.phase = 'dealer';
|
||||
this.currentSeatIndex = null;
|
||||
|
||||
@@ -423,6 +465,7 @@ class Table {
|
||||
}
|
||||
|
||||
resetRound() {
|
||||
this.clearTurnTimer();
|
||||
for (const seat of this.seats) {
|
||||
if (!seat.userId) {
|
||||
continue;
|
||||
|
||||
Reference in New Issue
Block a user