diff --git a/src/common/game/game-play.ts b/src/common/game/game-play.ts index d87e598..b9e019f 100644 --- a/src/common/game/game-play.ts +++ b/src/common/game/game-play.ts @@ -23,6 +23,7 @@ export class GamePlay implements GamePlayType { public isGameOver: boolean = false; public isStarted: boolean = false; public isOpen: boolean = false; + public timer?: number; get dealerIndex(): number { return this.players.findIndex((player) => player.dealer === true); @@ -105,16 +106,24 @@ export class GamePlay implements GamePlayType { case "check": break; case "call": - player.subtractBet(this.currentBet); - this.currentPot += this.currentBet - (parseFloat(player.bet) || 0); - player.bet = this.currentBet.toFixed(2); + const bet = + this.currentBet > player.stackAmount + ? player.stackAmount + : this.currentBet; + player.subtractBet(bet); + this.currentPot += bet - (parseFloat(player.bet) || 0); + player.bet = bet.toFixed(2); break; case "bet": case "raise": this.currentBet = data; player.subtractBet(this.currentBet); + this.currentPot += this.currentBet - (parseFloat(player.bet) || 0); player.bet = data.toFixed(2); + + this.clearLastAggresor(); + player.isLastAggressor = true; break; case "rebuy": player.stackAmount += data || 0; @@ -158,13 +167,19 @@ export class GamePlay implements GamePlayType { this.board.push(this.deck!.pop()!); break; default: - this.solveHands(); - return; + this.isGameOver = true; + break; } updatePots(this); } + public updatePlayerStacks(): void { + this.activePlayers.map( + (activePlayer, i) => (activePlayer.stackAmount += activePlayer.result) + ); + } + private nextTurn(): void { if (this.activePlayers.length === 1) { this.activePlayers.map((player) => { @@ -298,4 +313,8 @@ export class GamePlay implements GamePlayType { ) .map((player) => (player.isSittingOut = false)); } + + private clearLastAggresor(): void { + this.players.map((player) => (player.isLastAggressor = false)); + } } diff --git a/src/common/game/game.ts b/src/common/game/game.ts index 2454222..d8e9ffd 100644 --- a/src/common/game/game.ts +++ b/src/common/game/game.ts @@ -15,10 +15,9 @@ export class Game extends GamePlay { return { board: this.board, gameID: this.gameID, - players: - this.isGameOver || this.isOpen - ? this.players - : this.getGameStatePlayers(currentPlayerID), + players: this.isOpen + ? this.players + : this.getGameStatePlayers(currentPlayerID), pot: this.pot, round: this.round, bigBlind: this.bigBlind, @@ -33,6 +32,7 @@ export class Game extends GamePlay { isStarted: this.isStarted, isOpen: this.isOpen, sittingInPlayers: this.sittingInPlayers, + timer: this.timer, }; } @@ -45,7 +45,9 @@ export class Game extends GamePlay { player.playerID !== currentPlayerID && player.cards.length > 0 ) .map((player) => { - player.cards = [this.cardBack, this.cardBack]; + player.cards = player.showCards + ? player.cards + : [this.cardBack, this.cardBack]; }); return copyPlayers; @@ -81,6 +83,9 @@ export class Game extends GamePlay { callback(); if (this.isGameOver) { + this.solveHands(); + this.updatePlayerStacks(); + setTimeout(() => { this.start(); callback(); @@ -90,4 +95,86 @@ export class Game extends GamePlay { setTimeout(() => this.OpenGame(callback), 3000); } + + public showdown(callback: () => void): void { + this.solveHands(); + + const winnerFound: boolean = false; + const lastAggressorIndex = this.activePlayers.findIndex( + (player) => player.isLastAggressor === true + ); + const resultTemp: number[] = []; + this.activePlayers.map((activePlayer) => + resultTemp.push(activePlayer.result) + ); + + setTimeout( + () => + this.showdownHelper(lastAggressorIndex, winnerFound, resultTemp, () => + callback() + ), + 1500 + ); + } + + private showdownHelper( + lastAggressorIndex: number, + winnerFound: boolean, + resultTemp: number[], + callback: () => void + ): void { + if ( + this.activePlayers.filter((activePlayer) => activePlayer.result > 0) + .length === 0 + ) { + this.activePlayers.map( + (activePlayer, i) => (activePlayer.result = resultTemp[i]) + ); + + this.updatePlayerStacks(); + callback(); + + setTimeout(() => { + this.start(); + callback(); + }, 5000); + + return; + } + + const player = this.activePlayers[lastAggressorIndex]; + + if (!player) { + lastAggressorIndex = 0; + + this.showdownHelper(lastAggressorIndex, winnerFound, resultTemp, () => + callback() + ); + return; + } + + lastAggressorIndex++; + + if (winnerFound && player.result === 0) { + this.showdownHelper(lastAggressorIndex, winnerFound, resultTemp, () => + callback() + ); + return; + } + + if (player.result > 0) { + winnerFound = true; + player.result = 0; + } + + player.showCards = true; + callback(); + setTimeout( + () => + this.showdownHelper(lastAggressorIndex, winnerFound, resultTemp, () => + callback() + ), + 1500 + ); + } } diff --git a/src/common/game/solve-hands.ts b/src/common/game/solve-hands.ts index 7f7b469..6c81371 100644 --- a/src/common/game/solve-hands.ts +++ b/src/common/game/solve-hands.ts @@ -84,10 +84,4 @@ export function solveHands(game: GamePlayType): void { winners = []; boardWinner = true; } - - game.players - .filter((player) => player.result > 0) - .map((player) => (player.stackAmount += player.result)); - - game.isGameOver = true; } diff --git a/src/common/player/player.ts b/src/common/player/player.ts index 5363e2a..6a80db4 100644 --- a/src/common/player/player.ts +++ b/src/common/player/player.ts @@ -16,6 +16,8 @@ export class Player implements PlayerType { public result: number = 0; public pendingSitOut: boolean = false; public isSittingOut: boolean = false; + public isLastAggressor: boolean = false; + public showCards: boolean = false; get isActive(): boolean { return this.cards.length === 2 && this.status !== "fold"; @@ -62,6 +64,8 @@ export class Player implements PlayerType { this.isTurn = false; this.isBigBlind = false; this.isLittleBlind = false; + this.isLastAggressor = false; + this.showCards = false; this.invested = 0; this.result = 0; } diff --git a/src/common/types.ts b/src/common/types.ts index 093bacc..524522f 100644 --- a/src/common/types.ts +++ b/src/common/types.ts @@ -14,6 +14,8 @@ export interface PlayerState { solvedHand?: Hand; isSittingOut: boolean; pendingSitOut: boolean; + isLastAggressor: boolean; + showCards: boolean; readonly isActive: boolean; readonly isCheck: boolean; readonly numBet: number; @@ -43,6 +45,7 @@ export interface GameState { isStarted: boolean; isGameOver: boolean; isOpen: boolean; + timer?: number; readonly sittingInPlayers: PlayerType[]; } diff --git a/src/components/action.ts b/src/components/action.ts index ad329fc..cbfde8b 100644 --- a/src/components/action.ts +++ b/src/components/action.ts @@ -10,7 +10,12 @@ import { import { classMap } from "lit-html/directives/class-map"; import { GameState, PlayerState } from "../common/types"; import { roundToPrecision } from "../common/round-to-precision"; -import { sendPlayerAction, startGame, leaveGame } from "../data/connection"; +import { + sendPlayerAction, + startGame, + leaveGame, + callClock, +} from "../data/connection"; interface BetTarget extends EventTarget { multiplier: number; @@ -45,8 +50,8 @@ export class Action extends LitElement { if (this.player.bet === "" && this.player.isTurn && !this.game.isGameOver) { this.player.bet = (this.game.currentBet !== 0 - ? this.game.currentBet - : this.game.bigBlind + ? this.game.currentBet + this.game.bigBlind + : this.game.bigBlind + this.game.littleBlind ).toFixed(2); } @@ -124,35 +129,38 @@ export class Action extends LitElement { type="number" /> -