feat(game): add blackjack game component and routing
Some checks failed
CI / Get Changed Files (pull_request) Successful in 6s
CI / Checkstyle Main (pull_request) Has been skipped
CI / prettier (pull_request) Successful in 16s
CI / eslint (pull_request) Failing after 43s
CI / test-build (pull_request) Successful in 46s

This commit is contained in:
Jan-Marlon Leibl 2025-03-26 13:26:38 +01:00
commit eb153f4459
Signed by: jleibl
GPG key ID: 300B2F906DC6F1D5
12 changed files with 273 additions and 2 deletions

View file

@ -0,0 +1,29 @@
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
import { CommonModule } from '@angular/common';
import { PlayingCardComponent } from '../playing-card/playing-card.component';
import { Card } from '../../models/card.model';
@Component({
selector: 'app-dealer-hand',
standalone: true,
imports: [CommonModule, PlayingCardComponent],
template: `
<div class="space-y-4">
<h3 class="section-heading text-2xl mb-4">Croupier's Karten</h3>
<div class="card p-6 !bg-red-500">
<div class="flex justify-center gap-4 min-h-[160px] p-4 border-2 border-red-400 rounded-lg">
<app-playing-card
*ngFor="let card of cards"
[value]="card.value"
[suit]="card.suit"
[hidden]="card.hidden"
></app-playing-card>
</div>
</div>
</div>
`,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class DealerHandComponent {
@Input() cards: Card[] = [];
}

View file

@ -0,0 +1,36 @@
import { ChangeDetectionStrategy, Component, EventEmitter, Output } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-game-controls',
standalone: true,
imports: [CommonModule],
template: `
<div class="flex justify-center gap-4">
<button
(click)="onHit.emit()"
class="button-primary px-8 py-4 text-lg font-medium min-w-[120px]"
>
Ziehen
</button>
<button
(click)="onStand.emit()"
class="button-primary px-8 py-4 text-lg font-medium min-w-[120px]"
>
Halten
</button>
<button
(click)="onLeave.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"
>
Abbrechen
</button>
</div>
`,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class GameControlsComponent {
@Output() onHit = new EventEmitter<void>();
@Output() onStand = new EventEmitter<void>();
@Output() onLeave = new EventEmitter<void>();
}

View file

@ -0,0 +1,34 @@
import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core';
import { CommonModule, CurrencyPipe } from '@angular/common';
@Component({
selector: 'app-game-info',
standalone: true,
imports: [CommonModule, CurrencyPipe],
template: `
<div class="card p-4">
<h3 class="section-heading text-xl mb-4">Spiel Informationen</h3>
<div class="space-y-4">
<div class="flex justify-between items-center">
<span class="text-text-secondary">Guthaben:</span>
<span class="text-emerald">{{ balance | currency: 'EUR' }}</span>
</div>
<div class="flex justify-between items-center">
<span class="text-text-secondary">Aktuelle Wette:</span>
<span [class]="currentBet > 0 ? 'text-accent-red' : 'text-text-secondary'">
{{ currentBet | currency: 'EUR' }}
</span>
</div>
<button class="button-primary w-full py-2" (click)="onNewGameClick.emit()">
Neues Spiel
</button>
</div>
</div>
`,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class GameInfoComponent {
@Input() balance: number = 0;
@Input() currentBet: number = 0;
@Output() onNewGameClick = new EventEmitter<void>();
}

View file

@ -0,0 +1,31 @@
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
import { CommonModule } from '@angular/common';
import { PlayingCardComponent } from '../playing-card/playing-card.component';
import { Card } from '../../models/card.model';
@Component({
selector: 'app-player-hand',
standalone: true,
imports: [CommonModule, PlayingCardComponent],
template: `
<div class="space-y-4">
<h3 class="section-heading text-2xl mb-4">Deine Karten</h3>
<div class="card p-6 !bg-green-500">
<div
class="flex justify-center gap-4 min-h-[160px] p-4 border-2 border-green-400 rounded-lg"
>
<app-playing-card
*ngFor="let card of cards"
[value]="card.value"
[suit]="card.suit"
[hidden]="card.hidden"
></app-playing-card>
</div>
</div>
</div>
`,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class PlayerHandComponent {
@Input() cards: Card[] = [];
}

View file

@ -0,0 +1,30 @@
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-playing-card',
standalone: true,
imports: [CommonModule],
template: `
<div
class="w-24 h-36 rounded-lg p-2 relative flex flex-col justify-between shadow-lg"
[class]="hidden ? 'bg-red-800' : 'bg-white'"
>
<span *ngIf="!hidden" class="text-xl font-bold text-accent-red">{{ value }}</span>
<span
*ngIf="!hidden"
class="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 text-3xl text-accent-red"
>{{ suit }}</span
>
<span *ngIf="!hidden" class="text-xl font-bold text-accent-red self-end rotate-180">{{
value
}}</span>
</div>
`,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class PlayingCardComponent {
@Input({ required: true }) value!: string;
@Input({ required: true }) suit!: string;
@Input({ required: true }) hidden!: boolean;
}