feat: add double down feature to blackjack game
This commit is contained in:
parent
d90fcdcf1e
commit
d2b22b561d
7 changed files with 190 additions and 61 deletions
|
@ -11,6 +11,7 @@
|
|||
[gameState]="gameState()"
|
||||
(hit)="onHit()"
|
||||
(stand)="onStand()"
|
||||
(doubleDown)="onDoubleDown()"
|
||||
(leave)="leaveGame()"
|
||||
></app-game-controls>
|
||||
}
|
||||
|
@ -32,4 +33,5 @@
|
|||
[gameState]="gameState()"
|
||||
[amount]="currentBet()"
|
||||
[show]="showGameResult()"
|
||||
(close)="onCloseGameResult()"
|
||||
></app-game-result>
|
||||
|
|
|
@ -60,10 +60,13 @@ export default class BlackjackComponent {
|
|||
this.gameInProgress.set(game.state === 'IN_PROGRESS');
|
||||
this.gameState.set(game.state);
|
||||
|
||||
// When game ends, make sure all dealer cards are visible
|
||||
const isGameOver = game.state !== 'IN_PROGRESS';
|
||||
|
||||
this.dealerCards.set(
|
||||
game.dealerCards.map((card, index) => ({
|
||||
...card,
|
||||
hidden: index === 1 && game.state === 'IN_PROGRESS',
|
||||
hidden: !isGameOver && index === 1 && game.state === 'IN_PROGRESS',
|
||||
}))
|
||||
);
|
||||
|
||||
|
@ -74,11 +77,14 @@ export default class BlackjackComponent {
|
|||
}))
|
||||
);
|
||||
|
||||
if (game.state !== 'IN_PROGRESS') {
|
||||
// Only refresh and show game result if the game has ended
|
||||
if (isGameOver) {
|
||||
console.log('Game is over, state:', game.state);
|
||||
this.refreshUserBalance();
|
||||
setTimeout(() => {
|
||||
this.showGameResult.set(true);
|
||||
}, 1000);
|
||||
|
||||
// Show result immediately without resetting first
|
||||
this.showGameResult.set(true);
|
||||
console.log('Game result dialog should be shown now');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -127,7 +133,26 @@ export default class BlackjackComponent {
|
|||
});
|
||||
}
|
||||
|
||||
onDoubleDown(): void {
|
||||
if (!this.currentGameId()) return;
|
||||
|
||||
if (this.gameState() !== 'IN_PROGRESS' || this.playerCards().length !== 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.blackjackService.doubleDown(this.currentGameId()!).subscribe({
|
||||
next: (game) => {
|
||||
this.updateGameState(game);
|
||||
},
|
||||
error: (error) => {
|
||||
console.error('Failed to double down:', error);
|
||||
this.handleGameError(error);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
onCloseGameResult(): void {
|
||||
console.log('Closing game result dialog');
|
||||
this.showGameResult.set(false);
|
||||
}
|
||||
|
||||
|
|
|
@ -31,6 +31,13 @@ import { Card } from '../../models/blackjack.model';
|
|||
>
|
||||
Halten
|
||||
</button>
|
||||
<button
|
||||
(click)="doubleDown.emit()"
|
||||
class="button-primary px-8 py-4 text-lg font-medium min-w-[120px]"
|
||||
[disabled]="gameState !== 'IN_PROGRESS' || playerCards.length !== 2"
|
||||
>
|
||||
Verdoppeln
|
||||
</button>
|
||||
<button
|
||||
(click)="leave.emit()"
|
||||
class="bg-accent-red hover:bg-accent-red/80 px-8 py-4 rounded text-lg font-medium min-w-[120px] transition-all duration-300"
|
||||
|
@ -48,6 +55,7 @@ export class GameControlsComponent {
|
|||
|
||||
@Output() hit = new EventEmitter<void>();
|
||||
@Output() stand = new EventEmitter<void>();
|
||||
@Output() doubleDown = new EventEmitter<void>();
|
||||
@Output() leave = new EventEmitter<void>();
|
||||
|
||||
calculateHandValue(cards: Card[]): number {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
|
||||
import { ChangeDetectionStrategy, Component, Input, Output, EventEmitter } from '@angular/core';
|
||||
import { CommonModule, CurrencyPipe } from '@angular/common';
|
||||
import { animate, style, transition, trigger } from '@angular/animations';
|
||||
|
||||
|
@ -11,6 +11,7 @@ import { animate, style, transition, trigger } from '@angular/animations';
|
|||
*ngIf="visible"
|
||||
[@fadeInOut]
|
||||
class="modal-bg"
|
||||
style="z-index: 1000; position: fixed;"
|
||||
>
|
||||
<div
|
||||
class="modal-card"
|
||||
|
@ -52,7 +53,7 @@ import { animate, style, transition, trigger } from '@angular/animations';
|
|||
|
||||
<button
|
||||
type="button"
|
||||
(click)="visible = false"
|
||||
(click)="closeDialog()"
|
||||
class="button-primary w-full py-2"
|
||||
>
|
||||
Verstanden
|
||||
|
@ -66,16 +67,16 @@ import { animate, style, transition, trigger } from '@angular/animations';
|
|||
trigger('fadeInOut', [
|
||||
transition(':enter', [
|
||||
style({ opacity: 0 }),
|
||||
animate('300ms ease-out', style({ opacity: 1 }))
|
||||
animate('150ms ease-out', style({ opacity: 1 }))
|
||||
]),
|
||||
transition(':leave', [
|
||||
animate('200ms ease-in', style({ opacity: 0 }))
|
||||
animate('150ms ease-in', style({ opacity: 0 }))
|
||||
])
|
||||
]),
|
||||
trigger('cardAnimation', [
|
||||
transition(':enter', [
|
||||
style({ opacity: 0, transform: 'scale(0.8)' }),
|
||||
animate('350ms ease-out', style({ opacity: 1, transform: 'scale(1)' }))
|
||||
style({ opacity: 0, transform: 'scale(0.95)' }),
|
||||
animate('200ms ease-out', style({ opacity: 1, transform: 'scale(1)' }))
|
||||
])
|
||||
])
|
||||
]
|
||||
|
@ -84,9 +85,12 @@ export class GameResultComponent {
|
|||
@Input() gameState: string = '';
|
||||
@Input() amount: number = 0;
|
||||
@Input() set show(value: boolean) {
|
||||
console.log('GameResultComponent show input changed:', value, 'gameState:', this.gameState);
|
||||
this.visible = value;
|
||||
}
|
||||
|
||||
@Output() close = new EventEmitter<void>();
|
||||
|
||||
visible = false;
|
||||
|
||||
get isWin(): boolean {
|
||||
|
@ -121,4 +125,10 @@ export class GameResultComponent {
|
|||
if (this.isDraw) return 'text-yellow-400';
|
||||
return '';
|
||||
}
|
||||
|
||||
closeDialog(): void {
|
||||
this.visible = false;
|
||||
this.close.emit();
|
||||
console.log('Dialog closed by user');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,6 +42,17 @@ export class BlackjackService {
|
|||
);
|
||||
}
|
||||
|
||||
doubleDown(gameId: number): Observable<BlackjackGame> {
|
||||
return this.http
|
||||
.post<BlackjackGame>(`/backend/blackjack/${gameId}/doubleDown`, {}, { responseType: 'json' })
|
||||
.pipe(
|
||||
catchError((error) => {
|
||||
console.error('Double Down error:', error);
|
||||
throw error;
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
getGame(gameId: number): Observable<BlackjackGame> {
|
||||
return this.http
|
||||
.get<BlackjackGame>(`/backend/blackjack/${gameId}`, { responseType: 'json' })
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue