fix: Correct PnL calculation by using betAmount in net profit computation
Some checks failed
Deploy to Production / test (push) Failing after 34s
Some checks failed
Deploy to Production / test (push) Failing after 34s
- Add betAmount field to BlackjackState to track the base bet - Fix finishPlayerTurns: multiply hand.bet by state.betAmount for actual money bets - Fix GameServer: roundPayouts are already gross payouts (not multipliers) - Update cumulative PnL calculation to correctly subtract actual bet amount - Add betAmount support to riggedState test helper
This commit is contained in:
@@ -95,10 +95,9 @@ export class GameServer {
|
||||
const gameName = gameRegistry.get(room.gameSlug)?.name ?? "Game";
|
||||
const payoutDetails: Record<string, { net: number }> = {};
|
||||
|
||||
for (const [playerId, multiplier] of Object.entries(roundPayouts)) {
|
||||
if (multiplier <= 0) continue;
|
||||
const grossPayout = Math.floor(betAmount * multiplier);
|
||||
const netProfit = grossPayout - betAmount; // Calculate net profit (gross payout minus original bet)
|
||||
for (const [playerId, grossPayout] of Object.entries(roundPayouts)) {
|
||||
// roundPayout is already the gross payout amount (not a multiplier)
|
||||
const netProfit = Math.floor(grossPayout) - betAmount; // Calculate net profit (gross payout minus original bet)
|
||||
try {
|
||||
await economyService.modifyUserBalance(
|
||||
playerId,
|
||||
|
||||
@@ -34,6 +34,7 @@ function riggedState(overrides: {
|
||||
activePlayerIndex?: number;
|
||||
phase?: "betting" | "player_turns" | "resolved";
|
||||
roundNumber?: number;
|
||||
betAmount?: number;
|
||||
}): BlackjackState {
|
||||
return {
|
||||
deck: overrides.deck ?? [makeCard("5"), makeCard("6"), makeCard("7"), makeCard("8"), makeCard("9"), makeCard("10")],
|
||||
@@ -43,6 +44,7 @@ function riggedState(overrides: {
|
||||
activePlayerIndex: overrides.activePlayerIndex ?? 0,
|
||||
phase: overrides.phase ?? "player_turns",
|
||||
roundNumber: overrides.roundNumber ?? 1,
|
||||
betAmount: overrides.betAmount ?? 0,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -196,10 +196,10 @@ function finishPlayerTurns(state: BlackjackState): BlackjackState {
|
||||
|
||||
// Then calculate PnL based on resolved hands
|
||||
const roundPayout = calculateRoundPayouts({ [id]: { ...seat, hands: resolvedHands } });
|
||||
const roundPnl = roundPayout[id] ?? 0;
|
||||
const roundPayoutMoney = roundPayout[id] ?? 0;
|
||||
// Subtract the total bet amount to get net profit/loss
|
||||
const roundBetTotal = seat.hands.reduce((sum, h) => sum + h.bet, 0);
|
||||
const roundNetPnl = roundPayout[id] ? roundPayout[id] - roundBetTotal : -roundBetTotal;
|
||||
const roundBetTotal = seat.hands.reduce((sum, h) => sum + (h.bet * state.betAmount), 0);
|
||||
const roundNetPnl = roundPayoutMoney ? roundPayoutMoney - roundBetTotal : -roundBetTotal;
|
||||
|
||||
resolvedSeats[id] = {
|
||||
...seat,
|
||||
@@ -361,7 +361,8 @@ export const blackjackPlugin: GamePlugin<BlackjackState, BlackjackAction> = {
|
||||
maxPlayers: 6,
|
||||
manualStart: true,
|
||||
|
||||
createInitialState(players: string[], _options?: Record<string, unknown>): BlackjackState {
|
||||
createInitialState(players: string[], options?: Record<string, unknown>): BlackjackState {
|
||||
const betAmount = typeof options?.betAmount === 'number' ? options.betAmount : 0;
|
||||
const seats: Record<string, PlayerSeat> = {};
|
||||
for (const pid of players) {
|
||||
seats[pid] = {
|
||||
@@ -380,6 +381,7 @@ export const blackjackPlugin: GamePlugin<BlackjackState, BlackjackAction> = {
|
||||
activePlayerIndex: -1,
|
||||
phase: "betting",
|
||||
roundNumber: 1,
|
||||
betAmount,
|
||||
};
|
||||
},
|
||||
|
||||
|
||||
@@ -41,6 +41,8 @@ export interface BlackjackState {
|
||||
activePlayerIndex: number;
|
||||
phase: "betting" | "player_turns" | "resolved";
|
||||
roundNumber: number;
|
||||
/** The base bet amount for this game (0 for free play). */
|
||||
betAmount: number;
|
||||
}
|
||||
|
||||
// ── Actions ──
|
||||
|
||||
Reference in New Issue
Block a user