215 lines
6.4 KiB
TypeScript
215 lines
6.4 KiB
TypeScript
import { ChangeDetectionStrategy, Component, inject, signal } from '@angular/core';
|
|
import { CommonModule } from '@angular/common';
|
|
import { Router } from '@angular/router';
|
|
import { PlayingCardComponent } from './components/playing-card/playing-card.component';
|
|
import { DealerHandComponent } from './components/dealer-hand/dealer-hand.component';
|
|
import { PlayerHandComponent } from './components/player-hand/player-hand.component';
|
|
import { GameControlsComponent } from './components/game-controls/game-controls.component';
|
|
import { GameInfoComponent } from './components/game-info/game-info.component';
|
|
import { Card, BlackjackGame } from './models/blackjack.model';
|
|
import { BlackjackService } from './services/blackjack.service';
|
|
import { HttpErrorResponse } from '@angular/common/http';
|
|
import { GameResultComponent } from './components/game-result/game-result.component';
|
|
import { GameState } from './enum/gameState';
|
|
import { NavbarComponent } from '../../../shared/components/navbar/navbar.component';
|
|
import { UserService } from '../../../service/user.service';
|
|
|
|
@Component({
|
|
selector: 'app-blackjack',
|
|
standalone: true,
|
|
imports: [
|
|
CommonModule,
|
|
NavbarComponent,
|
|
PlayingCardComponent,
|
|
DealerHandComponent,
|
|
PlayerHandComponent,
|
|
GameControlsComponent,
|
|
GameInfoComponent,
|
|
GameResultComponent,
|
|
],
|
|
templateUrl: './blackjack.component.html',
|
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
})
|
|
export default class BlackjackComponent {
|
|
private router = inject(Router);
|
|
private userService = inject(UserService);
|
|
private blackjackService = inject(BlackjackService);
|
|
|
|
dealerCards = signal<Card[]>([]);
|
|
playerCards = signal<Card[]>([]);
|
|
currentBet = signal(0);
|
|
balance = signal(0);
|
|
currentGameId = signal<number | undefined>(undefined);
|
|
gameInProgress = signal(false);
|
|
gameState = signal<GameState>(GameState.IN_PROGRESS);
|
|
showGameResult = signal(false);
|
|
|
|
isActionInProgress = signal(false);
|
|
currentAction = signal<string>('');
|
|
|
|
constructor() {
|
|
this.refreshUserBalance();
|
|
}
|
|
|
|
private refreshUserBalance(): void {
|
|
this.userService.getCurrentUser().subscribe((user) => {
|
|
this.balance.set(user?.balance ?? 0);
|
|
});
|
|
}
|
|
|
|
private updateGameState(game: BlackjackGame) {
|
|
console.log('Game state update:', game);
|
|
this.currentGameId.set(game.id);
|
|
this.currentBet.set(game.bet);
|
|
this.gameInProgress.set(game.state === GameState.IN_PROGRESS);
|
|
this.gameState.set(game.state as GameState);
|
|
|
|
const isGameOver = game.state !== GameState.IN_PROGRESS;
|
|
|
|
this.dealerCards.set(
|
|
game.dealerCards.map((card, index) => ({
|
|
...card,
|
|
hidden: !isGameOver && index === 1 && game.state === GameState.IN_PROGRESS,
|
|
}))
|
|
);
|
|
|
|
this.playerCards.set(
|
|
game.playerCards.map((card) => ({
|
|
...card,
|
|
hidden: false,
|
|
}))
|
|
);
|
|
|
|
if (isGameOver) {
|
|
console.log('Game is over, state:', game.state);
|
|
this.refreshUserBalance();
|
|
|
|
this.showGameResult.set(true);
|
|
console.log('Game result dialog should be shown now');
|
|
}
|
|
}
|
|
|
|
onNewGame(bet: number): void {
|
|
this.isActionInProgress.set(true);
|
|
this.currentAction.set('Spiel wird gestartet...');
|
|
|
|
this.blackjackService.startGame(bet).subscribe({
|
|
next: (game) => {
|
|
this.updateGameState(game);
|
|
this.refreshUserBalance();
|
|
this.isActionInProgress.set(false);
|
|
},
|
|
error: (error) => {
|
|
console.error('Failed to start game:', error);
|
|
this.isActionInProgress.set(false);
|
|
},
|
|
});
|
|
}
|
|
|
|
onHit(): void {
|
|
if (!this.currentGameId() || this.isActionInProgress()) return;
|
|
|
|
this.isActionInProgress.set(true);
|
|
this.currentAction.set('Karte wird gezogen...');
|
|
|
|
this.blackjackService.hit(this.currentGameId()!).subscribe({
|
|
next: (game) => {
|
|
this.updateGameState(game);
|
|
this.isActionInProgress.set(false);
|
|
},
|
|
error: (error) => {
|
|
console.error('Failed to hit:', error);
|
|
this.handleGameError(error);
|
|
this.isActionInProgress.set(false);
|
|
},
|
|
});
|
|
}
|
|
|
|
onStand(): void {
|
|
if (!this.currentGameId() || this.isActionInProgress()) return;
|
|
|
|
if (this.gameState() !== GameState.IN_PROGRESS) {
|
|
console.log('Cannot stand: game is not in progress');
|
|
return;
|
|
}
|
|
|
|
this.isActionInProgress.set(true);
|
|
this.currentAction.set('Dealer zieht Karten...');
|
|
|
|
this.blackjackService.stand(this.currentGameId()!).subscribe({
|
|
next: (game) => {
|
|
this.updateGameState(game);
|
|
this.isActionInProgress.set(false);
|
|
},
|
|
error: (error) => {
|
|
console.error('Failed to stand:', error);
|
|
this.handleGameError(error);
|
|
this.isActionInProgress.set(false);
|
|
},
|
|
});
|
|
}
|
|
|
|
onDoubleDown(): void {
|
|
if (!this.currentGameId() || this.isActionInProgress()) return;
|
|
|
|
if (this.gameState() !== GameState.IN_PROGRESS || this.playerCards().length !== 2) {
|
|
console.log('Cannot double down: game is not in progress or more than 2 cards');
|
|
return;
|
|
}
|
|
|
|
this.isActionInProgress.set(true);
|
|
this.currentAction.set('Einsatz wird verdoppelt...');
|
|
|
|
this.blackjackService.doubleDown(this.currentGameId()!).subscribe({
|
|
next: (game) => {
|
|
this.updateGameState(game);
|
|
this.isActionInProgress.set(false);
|
|
},
|
|
error: (error) => {
|
|
console.error('Failed to double down:', error);
|
|
this.handleGameError(error);
|
|
this.isActionInProgress.set(false);
|
|
},
|
|
});
|
|
}
|
|
|
|
onCloseGameResult(): void {
|
|
console.log('Closing game result dialog');
|
|
this.showGameResult.set(false);
|
|
}
|
|
|
|
private handleGameError(error: HttpErrorResponse): void {
|
|
if (error instanceof HttpErrorResponse) {
|
|
if (error.status === 400 && error.error?.error === 'Invalid state') {
|
|
this.gameInProgress.set(false);
|
|
|
|
this.refreshUserBalance();
|
|
} else if (error.status === 500) {
|
|
console.log('Server error occurred. The game may have been updated in another session.');
|
|
|
|
this.gameInProgress.set(false);
|
|
|
|
this.refreshUserBalance();
|
|
|
|
if (this.currentGameId()) {
|
|
this.refreshGameState(this.currentGameId()!);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private refreshGameState(gameId: number): void {
|
|
this.blackjackService.getGame(gameId).subscribe({
|
|
next: (game) => {
|
|
this.updateGameState(game);
|
|
},
|
|
error: (err) => {
|
|
console.error('Failed to refresh game state:', err);
|
|
},
|
|
});
|
|
}
|
|
|
|
leaveGame(): void {
|
|
this.router.navigate(['/home']);
|
|
}
|
|
}
|