85 lines
1.9 KiB
TypeScript
85 lines
1.9 KiB
TypeScript
"use server";
|
|
|
|
import crypto from "crypto";
|
|
import {
|
|
createDeck,
|
|
shuffle,
|
|
calculateHand,
|
|
type Card,
|
|
} from "~/lib/blackjack/engine";
|
|
|
|
// In-memory storage (replace with DB/Redis in production)
|
|
const games = new Map<string, any>();
|
|
|
|
export async function startGame(bet: number) {
|
|
const deck = shuffle(createDeck());
|
|
|
|
const player: Card[] = [deck.pop()!, deck.pop()!];
|
|
const dealer: Card[] = [deck.pop()!, deck.pop()!];
|
|
|
|
const gameId = crypto.randomUUID();
|
|
|
|
games.set(gameId, { deck, player, dealer, bet, status: "playing" });
|
|
|
|
return {
|
|
gameId,
|
|
player,
|
|
dealerUpcard: [dealer[0]],
|
|
playerTotal: calculateHand(player),
|
|
status: "playing",
|
|
};
|
|
}
|
|
|
|
export async function hit(gameId: string) {
|
|
const game = games.get(gameId);
|
|
if (!game) throw new Error("Game not found");
|
|
|
|
const card = game.deck.pop();
|
|
game.player.push(card);
|
|
|
|
const playerTotal = calculateHand(game.player);
|
|
if (playerTotal > 21) game.status = "bust";
|
|
|
|
return {
|
|
player: game.player,
|
|
playerTotal,
|
|
status: game.status,
|
|
};
|
|
}
|
|
|
|
export async function stand(gameId: string) {
|
|
const game = games.get(gameId);
|
|
if (!game) throw new Error("Game not found");
|
|
|
|
while (calculateHand(game.dealer) < 17) {
|
|
game.dealer.push(game.deck.pop());
|
|
}
|
|
|
|
const playerTotal = calculateHand(game.player);
|
|
const dealerTotal = calculateHand(game.dealer);
|
|
|
|
let result: "win" | "lose" | "push" = "lose";
|
|
if (dealerTotal > 21 || playerTotal > dealerTotal) result = "win";
|
|
if (playerTotal === dealerTotal) result = "push";
|
|
|
|
// TODO: update user balance here
|
|
|
|
games.delete(gameId);
|
|
|
|
return {
|
|
dealer: game.dealer,
|
|
dealerTotal,
|
|
result,
|
|
};
|
|
}
|
|
|
|
export async function revealDealer(gameId: string) {
|
|
const game = games.get(gameId);
|
|
if (!game) throw new Error("Game not found");
|
|
|
|
return {
|
|
dealer: game.dealer,
|
|
dealerTotal: calculateHand(game.dealer),
|
|
};
|
|
}
|