Guessing eingebaut
This commit is contained in:
parent
7428faa138
commit
5cc62433bd
|
|
@ -6,6 +6,20 @@
|
|||
</div>
|
||||
|
||||
@if (gameStarted) {
|
||||
<div class="tip-phase">
|
||||
<div>
|
||||
<label>Dein Tipp:</label>
|
||||
<input type="number" [(ngModel)]="roundPredictions[currentRound - 1].playerPrediction" [class.active]="currentTipPlayerIndex === 0" [disabled]="currentTipPlayerIndex !== 0" />
|
||||
</div>
|
||||
|
||||
<div *ngFor="let opponent of opponents; let i = index">
|
||||
<label>Gegner {{ i + 1 }} Tipp:</label>
|
||||
<input type="number" [(ngModel)]="roundPredictions[currentRound - 1].opponentPredictions[i]" disabled />
|
||||
</div>
|
||||
|
||||
<button *ngIf="currentTipPlayerIndex === 0" (click)="submitPlayerTip()">Tipp abgeben</button>
|
||||
</div>
|
||||
|
||||
<div class="opponents-area">
|
||||
@for (opponent of opponents; track opponent; let i = $index) {
|
||||
<div class="opponent-hand">
|
||||
|
|
@ -30,7 +44,7 @@
|
|||
}
|
||||
</div>
|
||||
<div class="game-info">
|
||||
<div class="score">Spieler: {{ player.score }} @for (opponent of opponents; track opponent; let i = $index) { | Gegner {{ i + 1 }}: {{ opponent.score }} } | Runde: {{ currentRound }}/10</div>
|
||||
<!-- <div class="score">Spieler: {{ player.score }} @for (opponent of opponents; track opponent; let i = $index) { | Gegner {{ i + 1 }}: {{ opponent.score }} } | Runde: {{ currentRound }}/10</div> -->
|
||||
<button (click)="startNewRound()" [disabled]="player.hand.length > 0 || currentRound > 10">Nächste Runde</button>
|
||||
<!-- Tabelle für die Stiche pro Runde -->
|
||||
<table class="round-stats">
|
||||
|
|
@ -42,10 +56,18 @@
|
|||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr *ngFor="let stat of roundStats">
|
||||
<td>{{ stat.round }}</td>
|
||||
<td>{{ stat.playerStitches }}</td>
|
||||
<td *ngFor="let stitches of stat.opponentStitches">{{ stitches }}</td>
|
||||
<tr *ngFor="let stat of roundStats; let i = index">
|
||||
<td class="round-value">{{ stat.round }}</td>
|
||||
<td [ngClass]="{ alreadyTipped: tipAlreadySet(roundPredictions[stat.round - 1]?.playerPrediction) }">
|
||||
<span class="tip-value">{{ roundPredictions[stat.round - 1]?.playerPrediction === null ? '-' : roundPredictions[stat.round - 1]?.playerPrediction }}/{{ stat.playerStitches }}</span>
|
||||
<span class="stitch-value">{{ player.score }}</span>
|
||||
</td>
|
||||
@for(opponentTip of roundPredictions[stat.round - 1]?.opponentPredictions; track opponentTip; let j = $index){
|
||||
<td [ngClass]="{ alreadyTipped: tipAlreadySet(opponentTip) }">
|
||||
<span class="tip-value">{{ opponentTip === null ? '-' : opponentTip }}/{{ stat.opponentStitches[j] }}</span>
|
||||
<span class="stitch-value">{{ opponents[j].score }}</span>
|
||||
</td>
|
||||
}
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
|
|||
|
|
@ -15,13 +15,14 @@
|
|||
}
|
||||
.opponents-area {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
justify-content: center;
|
||||
min-height: 320px;
|
||||
}
|
||||
.opponent-hand {
|
||||
position: relative;
|
||||
width: 200px;
|
||||
height: 280px;
|
||||
margin-right: 150px;
|
||||
}
|
||||
.stacked-card {
|
||||
position: absolute;
|
||||
|
|
@ -83,12 +84,14 @@
|
|||
font-size: 14px;
|
||||
z-index: 100;
|
||||
text-align: center;
|
||||
border-collapse: collapse;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.round-stats th,
|
||||
.round-stats td {
|
||||
padding: 8px;
|
||||
border-bottom: 1px solid #ddd;
|
||||
padding: 5px;
|
||||
border: 1px solid #ddd;
|
||||
}
|
||||
|
||||
.round-stats thead {
|
||||
|
|
@ -99,3 +102,51 @@
|
|||
.round-stats tbody tr:last-child td {
|
||||
border-bottom: none;
|
||||
}
|
||||
.tip-value {
|
||||
font-size: 12px;
|
||||
vertical-align: top;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.stitch-value {
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
display: block;
|
||||
}
|
||||
.round-value {
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
}
|
||||
.tip-phase {
|
||||
position: fixed;
|
||||
top: 20px;
|
||||
left: 20px;
|
||||
background-color: #f9f9f9;
|
||||
border: 1px solid #ccc;
|
||||
padding: 10px;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
.tip-phase input {
|
||||
width: 60px;
|
||||
height: 30px;
|
||||
border: 2px solid #ccc;
|
||||
border-radius: 5px;
|
||||
text-align: center;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.tip-phase input.active {
|
||||
border-color: red;
|
||||
box-shadow: 0 0 10px red;
|
||||
}
|
||||
td.alreadyTipped {
|
||||
border-color: blue;
|
||||
box-shadow: 0 0 10px blue;
|
||||
}
|
||||
.tip-phase label {
|
||||
margin-right: 10px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { CardFrontComponent } from './card-front.component';
|
||||
import { CardBackComponent } from './card-back.component';
|
||||
import { CardService, Card } from './card.service';
|
||||
import { CardFrontComponent } from './card-front.component';
|
||||
import { Card, CardService } from './card.service';
|
||||
import { GameRuleEngine } from './game-rule-engine';
|
||||
|
||||
export interface Player {
|
||||
|
|
@ -17,12 +17,16 @@ interface RoundStats {
|
|||
playerStitches: number;
|
||||
opponentStitches: number[];
|
||||
}
|
||||
interface RoundPrediction {
|
||||
playerPrediction: number | null;
|
||||
opponentPredictions: Array<number | null>;
|
||||
}
|
||||
@Component({
|
||||
selector: 'app-game',
|
||||
standalone: true,
|
||||
imports: [CommonModule, FormsModule, CardFrontComponent, CardBackComponent],
|
||||
templateUrl: './game.component.html',
|
||||
styleUrls: ['./game.component.scss']
|
||||
styleUrls: ['./game.component.scss'],
|
||||
})
|
||||
export class GameComponent implements OnInit {
|
||||
player: Player = { id: 0, hand: [], playedCard: null, score: 0 };
|
||||
|
|
@ -36,17 +40,24 @@ export class GameComponent implements OnInit {
|
|||
roundStats: RoundStats[] = [];
|
||||
private ruleEngine: GameRuleEngine;
|
||||
|
||||
roundPredictions: RoundPrediction[] = [];
|
||||
currentTipPlayerIndex: number = 0;
|
||||
isTipPhase: boolean = true;
|
||||
numberTips = 0;
|
||||
constructor(private cardService: CardService) {
|
||||
this.ruleEngine = new GameRuleEngine(cardService);
|
||||
}
|
||||
|
||||
ngOnInit() {}
|
||||
ngOnInit() {
|
||||
this.startGame();
|
||||
}
|
||||
|
||||
startGame() {
|
||||
if (this.numberOfOpponents < 1 || this.numberOfOpponents > 3) {
|
||||
alert("Bitte wählen Sie 1 bis 3 Gegner.");
|
||||
return;
|
||||
}
|
||||
// if (this.numberOfOpponents < 1 || this.numberOfOpponents > 3) {
|
||||
// alert('Bitte wählen Sie 1 bis 3 Gegner.');
|
||||
// return;
|
||||
// }
|
||||
this.numberOfOpponents = 2;
|
||||
this.gameStarted = true;
|
||||
this.initializePlayers();
|
||||
this.startNewRound();
|
||||
|
|
@ -75,8 +86,74 @@ export class GameComponent implements OnInit {
|
|||
});
|
||||
|
||||
this.resetPlayedCards();
|
||||
this.currentPlayerIndex = this.ruleEngine.determineStartingPlayer(this.currentRound, this.opponents.length + 1);
|
||||
this.playTrick();
|
||||
|
||||
// Runde für roundStats initialisieren
|
||||
if (!this.roundStats[this.currentRound - 1]) {
|
||||
this.roundStats[this.currentRound - 1] = {
|
||||
round: this.currentRound,
|
||||
playerStitches: 0,
|
||||
opponentStitches: new Array(this.opponents.length).fill(0),
|
||||
};
|
||||
}
|
||||
|
||||
// Tipp-Phase initialisieren
|
||||
this.isTipPhase = true;
|
||||
this.currentTipPlayerIndex = (this.currentRound - 1) % (this.opponents.length + 1);
|
||||
this.initializeTipPhase();
|
||||
}
|
||||
initializeTipPhase() {
|
||||
// Initialisiere die Vorhersagen für die Runde
|
||||
this.roundPredictions[this.currentRound - 1] = {
|
||||
playerPrediction: null,
|
||||
opponentPredictions: new Array(this.opponents.length).fill(null),
|
||||
};
|
||||
|
||||
// Starte das Tippen beim richtigen Spieler basierend auf der Runde
|
||||
this.currentTipPlayerIndex = (this.currentRound - 1) % (this.opponents.length + 1);
|
||||
this.numberTips = 0;
|
||||
// Wenn der aktuelle Spieler kein menschlicher Spieler ist, den ersten Gegner automatisch tippen lassen
|
||||
if (this.currentTipPlayerIndex > 0) {
|
||||
this.submitOpponentTip(this.currentTipPlayerIndex - 1);
|
||||
}
|
||||
}
|
||||
|
||||
submitOpponentTip(index: number) {
|
||||
const randomTip = Math.floor(Math.random() * this.getCardsForRound(this.currentRound));
|
||||
this.roundPredictions[this.currentRound - 1].opponentPredictions[index] = randomTip;
|
||||
|
||||
this.numberTips++;
|
||||
if (this.numberTips === this.opponents.length + 1) {
|
||||
// Alle haben getippt, beende die Tippphase
|
||||
this.isTipPhase = false;
|
||||
this.playTrick();
|
||||
} else if ((this.currentTipPlayerIndex + 1) % 3 === 0) {
|
||||
// Spieler ist jetzt dran
|
||||
this.currentTipPlayerIndex = 0;
|
||||
return;
|
||||
} else {
|
||||
// Nächster Gegner ist dran
|
||||
this.currentTipPlayerIndex++;
|
||||
setTimeout(() => this.submitOpponentTip(this.currentTipPlayerIndex - 1), 1000);
|
||||
}
|
||||
}
|
||||
|
||||
submitPlayerTip() {
|
||||
const playerPrediction = this.roundPredictions[this.currentRound - 1]?.playerPrediction;
|
||||
if (playerPrediction === null || playerPrediction < 0 || playerPrediction > this.getCardsForRound(this.currentRound)) {
|
||||
return; // Ungültiger Tipp oder noch nicht gesetzt
|
||||
}
|
||||
|
||||
// Spieler hat getippt, wechsle zum nächsten Spieler
|
||||
this.currentTipPlayerIndex++;
|
||||
this.numberTips++;
|
||||
if (this.numberTips === this.opponents.length + 1) {
|
||||
// Alle haben getippt, beende die Tippphase
|
||||
this.isTipPhase = false;
|
||||
this.playTrick();
|
||||
} else {
|
||||
// Der nächste Gegner ist an der Reihe
|
||||
setTimeout(() => this.submitOpponentTip(0), 1000);
|
||||
}
|
||||
}
|
||||
|
||||
playTrick() {
|
||||
|
|
@ -136,7 +213,7 @@ export class GameComponent implements OnInit {
|
|||
const winner = this.ruleEngine.determineWinner(this.playedCards, allPlayers);
|
||||
winner.score++;
|
||||
|
||||
// Neue Logik, um Stiche zu speichern
|
||||
// Stiche in den roundStats aktualisieren
|
||||
if (!this.roundStats[this.currentRound - 1]) {
|
||||
this.roundStats[this.currentRound - 1] = {
|
||||
round: this.currentRound,
|
||||
|
|
@ -152,7 +229,21 @@ export class GameComponent implements OnInit {
|
|||
this.roundStats[this.currentRound - 1].opponentStitches[opponentIndex]++;
|
||||
}
|
||||
|
||||
// Überprüfe, ob die Runde vorbei ist
|
||||
if (this.player.hand.length === 0) {
|
||||
// Tipp-Prüfung und Extrapunkte
|
||||
const predictions = this.roundPredictions[this.currentRound - 1];
|
||||
if (predictions.playerPrediction === this.roundStats[this.currentRound - 1].playerStitches) {
|
||||
this.player.score += 10; // Extrapunkte für richtigen Tipp
|
||||
}
|
||||
|
||||
this.opponents.forEach((opponent, index) => {
|
||||
if (predictions.opponentPredictions[index] === this.roundStats[this.currentRound - 1].opponentStitches[index]) {
|
||||
opponent.score += 10; // Extrapunkte für richtigen Tipp
|
||||
}
|
||||
});
|
||||
|
||||
// Neue Runde starten oder Spiel beenden
|
||||
if (this.currentRound < 10) {
|
||||
setTimeout(() => this.startNewRound(), 500);
|
||||
} else {
|
||||
|
|
@ -169,7 +260,7 @@ export class GameComponent implements OnInit {
|
|||
this.playedCards = [];
|
||||
this.leadCard = null;
|
||||
this.player.playedCard = null;
|
||||
this.opponents.forEach(opponent => opponent.playedCard = null);
|
||||
this.opponents.forEach(opponent => (opponent.playedCard = null));
|
||||
}
|
||||
|
||||
getCardsForRound(round: number): number {
|
||||
|
|
@ -182,12 +273,10 @@ export class GameComponent implements OnInit {
|
|||
const maxScore = Math.max(...allPlayers.map(p => p.score));
|
||||
const winners = allPlayers.filter(p => p.score === maxScore);
|
||||
|
||||
let result = winners.length > 1 ? "Unentschieden!" :
|
||||
winners[0] === this.player ? "Sie haben gewonnen!" :
|
||||
`Gegner ${winners[0].id} hat gewonnen!`;
|
||||
let result = winners.length > 1 ? 'Unentschieden!' : winners[0] === this.player ? 'Sie haben gewonnen!' : `Gegner ${winners[0].id} hat gewonnen!`;
|
||||
|
||||
let scoreMessage = `Endstand - Spieler: ${this.player.score}`;
|
||||
this.opponents.forEach((opponent) => {
|
||||
this.opponents.forEach(opponent => {
|
||||
scoreMessage += `, Gegner ${opponent.id}: ${opponent.score}`;
|
||||
});
|
||||
|
||||
|
|
@ -196,4 +285,7 @@ export class GameComponent implements OnInit {
|
|||
this.currentRound = 0;
|
||||
this.player.score = 0;
|
||||
}
|
||||
tipAlreadySet(value: number | null | undefined) {
|
||||
return value !== null;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue