improvements
This commit is contained in:
@@ -25,6 +25,11 @@ public class GameEngine
|
||||
State.Players = players;
|
||||
State.Rules = rules;
|
||||
State.IsGameOver = false;
|
||||
State.IsMatchOver = false;
|
||||
State.IsRoundOver = false;
|
||||
State.MatchWinner = null;
|
||||
State.RoundLoser = null;
|
||||
State.RoundNumber = 1;
|
||||
State.LastFinishedPlayer = null;
|
||||
State.TurnCount = 1;
|
||||
State.PendingDrawCount = 0;
|
||||
@@ -35,6 +40,7 @@ public class GameEngine
|
||||
|
||||
foreach (var player in State.Players)
|
||||
{
|
||||
player.OlympicCardsCount = State.Rules.InitialCardCount;
|
||||
player.Reset();
|
||||
}
|
||||
|
||||
@@ -42,10 +48,10 @@ public class GameEngine
|
||||
State.DrawDeck = _deckManager.CreateShuffledDeck();
|
||||
State.DiscardPile.Clear();
|
||||
|
||||
// Rozdanie kariet každému hráčovi
|
||||
for (int i = 0; i < State.Rules.InitialCardCount; i++)
|
||||
// Rozdanie kariet každému aktívnemu hráčovi podľa jeho OlympicCardsCount
|
||||
foreach (var player in State.ActiveTournamentPlayers)
|
||||
{
|
||||
foreach (var player in State.Players)
|
||||
for (int i = 0; i < player.OlympicCardsCount; i++)
|
||||
{
|
||||
if (State.DrawDeck.Count > 0)
|
||||
{
|
||||
@@ -57,7 +63,6 @@ public class GameEngine
|
||||
}
|
||||
|
||||
// Otočenie prvej karty na odhadzovaciu kôpku
|
||||
// Ak je prvá karta sedma, eso alebo horník, v základnej hre ju berieme ako štartovaciu bez okamžitého trestu
|
||||
var startCard = State.DrawDeck[0];
|
||||
State.DrawDeck.RemoveAt(0);
|
||||
State.DiscardPile.Add(startCard);
|
||||
@@ -551,27 +556,131 @@ public class GameEngine
|
||||
int remaining = State.ActivePlayersCount;
|
||||
if (remaining <= 1)
|
||||
{
|
||||
State.IsGameOver = true;
|
||||
State.TurnState = TurnState.GameOver;
|
||||
|
||||
// Zostávajúcemu hráčovi priradíme posledné miesto
|
||||
var lastPlayer = State.Players.FirstOrDefault(p => !p.HasFinished);
|
||||
// Zostávajúci hráč, ktorému ostali karty (porazený tohto kola)
|
||||
var lastPlayer = State.ActiveTournamentPlayers.FirstOrDefault(p => !p.HasFinished);
|
||||
if (lastPlayer != null)
|
||||
{
|
||||
lastPlayer.FinishedPosition = State.Players.Count;
|
||||
lastPlayer.FinishedPosition = State.ActiveTournamentPlayers.Count;
|
||||
State.RoundLoser = lastPlayer;
|
||||
}
|
||||
|
||||
EmitEvent(new GameEvent(
|
||||
GameEventType.GameOver,
|
||||
null,
|
||||
Message: "Koniec hry! Všetky pozície sú určené."
|
||||
));
|
||||
if (State.Rules.OlympicMode)
|
||||
{
|
||||
if (lastPlayer != null)
|
||||
{
|
||||
lastPlayer.OlympicCardsCount--;
|
||||
if (lastPlayer.IsEliminated)
|
||||
{
|
||||
EmitEvent(new GameEvent(
|
||||
GameEventType.PlayerEliminated,
|
||||
lastPlayer,
|
||||
Message: $"☠️ {lastPlayer.Name} stratil všetky karty a vypadáva z Olympijského turnaja!"
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
var remainingTournamentPlayers = State.ActiveTournamentPlayers;
|
||||
if (remainingTournamentPlayers.Count <= 1)
|
||||
{
|
||||
// Koniec turnaja! Zostal iba 1 víťaz
|
||||
State.IsGameOver = true;
|
||||
State.IsMatchOver = true;
|
||||
State.MatchWinner = remainingTournamentPlayers.FirstOrDefault() ?? lastPlayer;
|
||||
State.TurnState = TurnState.GameOver;
|
||||
|
||||
EmitEvent(new GameEvent(
|
||||
GameEventType.MatchWon,
|
||||
State.MatchWinner,
|
||||
Message: $"🥇 {State.MatchWinner?.Name} sa stal celkovým OLYMPIJSKÝM ŠAMPIÓNOM!"
|
||||
));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Koniec jedného kola, nasleduje ďalšie
|
||||
State.IsRoundOver = true;
|
||||
State.TurnState = TurnState.RoundOver;
|
||||
|
||||
EmitEvent(new GameEvent(
|
||||
GameEventType.RoundOver,
|
||||
lastPlayer,
|
||||
ExtraData: State.RoundNumber,
|
||||
Message: $"🏅 Kolo #{State.RoundNumber} sa skončilo! {lastPlayer?.Name} bude mať v ďalšom kole {lastPlayer?.OlympicCardsCount} kariet."
|
||||
));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Bežná jednoduchá hra
|
||||
State.IsGameOver = true;
|
||||
State.TurnState = TurnState.GameOver;
|
||||
|
||||
EmitEvent(new GameEvent(
|
||||
GameEventType.GameOver,
|
||||
null,
|
||||
Message: "Koniec hry! Všetky pozície sú určené."
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void StartNextRound()
|
||||
{
|
||||
if (!State.Rules.OlympicMode || State.IsMatchOver) return;
|
||||
|
||||
State.RoundNumber++;
|
||||
State.IsRoundOver = false;
|
||||
State.IsGameOver = false;
|
||||
State.RoundLoser = null;
|
||||
State.TurnState = TurnState.Playing;
|
||||
State.TurnCount = 1;
|
||||
State.PendingDrawCount = 0;
|
||||
State.PendingSkip = false;
|
||||
State.ActiveSuit = null;
|
||||
State.PendingHornikPlayer = null;
|
||||
|
||||
foreach (var p in State.Players)
|
||||
{
|
||||
p.Reset();
|
||||
}
|
||||
|
||||
// Vytvorenie a zamiešanie nového balíčka
|
||||
State.DrawDeck = _deckManager.CreateShuffledDeck();
|
||||
State.DiscardPile.Clear();
|
||||
|
||||
// Rozdanie kariet len aktívnym (nevyradeným) hráčom podľa ich OlympicCardsCount
|
||||
foreach (var player in State.ActiveTournamentPlayers)
|
||||
{
|
||||
for (int i = 0; i < player.OlympicCardsCount; i++)
|
||||
{
|
||||
if (State.DrawDeck.Count > 0)
|
||||
{
|
||||
var card = State.DrawDeck[0];
|
||||
State.DrawDeck.RemoveAt(0);
|
||||
player.Hand.Add(card);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Otočenie prvej karty na odhadzovaciu kôpku
|
||||
var startCard = State.DrawDeck[0];
|
||||
State.DrawDeck.RemoveAt(0);
|
||||
State.DiscardPile.Add(startCard);
|
||||
|
||||
// Nastavíme prvého hráča na prvého aktívneho
|
||||
var firstActiveIndex = State.Players.FindIndex(p => !p.IsEliminated);
|
||||
State.CurrentPlayerIndex = firstActiveIndex >= 0 ? firstActiveIndex : 0;
|
||||
|
||||
EmitEvent(new GameEvent(
|
||||
GameEventType.GameStarted,
|
||||
State.CurrentPlayer,
|
||||
Card: startCard,
|
||||
Message: $"🏅 Začalo sa Kolo #{State.RoundNumber} Olympijského Faraóna!"
|
||||
));
|
||||
}
|
||||
|
||||
private void AdvanceTurn()
|
||||
{
|
||||
if (State.IsGameOver) return;
|
||||
if (State.IsGameOver || State.IsRoundOver) return;
|
||||
|
||||
int attempts = 0;
|
||||
do
|
||||
@@ -579,12 +688,12 @@ public class GameEngine
|
||||
State.CurrentPlayerIndex = (State.CurrentPlayerIndex + 1) % State.Players.Count;
|
||||
attempts++;
|
||||
}
|
||||
while (State.CurrentPlayer.HasFinished && attempts <= State.Players.Count);
|
||||
while ((State.CurrentPlayer.HasFinished || State.CurrentPlayer.IsEliminated) && attempts <= State.Players.Count * 2);
|
||||
|
||||
State.TurnCount++;
|
||||
|
||||
// Ak hráme Pass & Play a nasledujúci hráč je človek a je zapnutá súkromná clona
|
||||
if (State.Rules.PassAndPlayPrivacyScreen && State.CurrentPlayer.Type == PlayerType.Human && State.Players.Count(p => p.Type == PlayerType.Human) > 1)
|
||||
if (State.Rules.PassAndPlayPrivacyScreen && State.CurrentPlayer.Type == PlayerType.Human && State.ActiveTournamentPlayers.Count(p => p.Type == PlayerType.Human) > 1)
|
||||
{
|
||||
State.TurnState = TurnState.PassScreen;
|
||||
}
|
||||
|
||||
@@ -13,7 +13,10 @@ public enum GameEventType
|
||||
PlayerRevived,
|
||||
PlayerFinished,
|
||||
GameOver,
|
||||
DeckReshuffled
|
||||
DeckReshuffled,
|
||||
RoundOver,
|
||||
PlayerEliminated,
|
||||
MatchWon
|
||||
}
|
||||
|
||||
public record GameEvent(
|
||||
|
||||
@@ -5,6 +5,7 @@ public enum TurnState
|
||||
Playing,
|
||||
SelectingSuit,
|
||||
PassScreen,
|
||||
RoundOver,
|
||||
GameOver
|
||||
}
|
||||
|
||||
@@ -25,7 +26,15 @@ public class GameState
|
||||
public Player? PendingHornikPlayer { get; set; }
|
||||
public Card? TopCard => DiscardPile.Count > 0 ? DiscardPile[^1] : null;
|
||||
|
||||
// Olympijský režim (Turnaj)
|
||||
public int RoundNumber { get; set; } = 1;
|
||||
public bool IsRoundOver { get; set; } = false;
|
||||
public Player? RoundLoser { get; set; }
|
||||
public Player? MatchWinner { get; set; }
|
||||
public bool IsMatchOver { get; set; } = false;
|
||||
|
||||
public Player CurrentPlayer => Players.Count > 0 ? Players[CurrentPlayerIndex % Players.Count] : new Player();
|
||||
|
||||
public int ActivePlayersCount => Players.Count(p => !p.HasFinished);
|
||||
public int ActivePlayersCount => Players.Where(p => !p.IsEliminated).Count(p => !p.HasFinished);
|
||||
public List<Player> ActiveTournamentPlayers => Players.Where(p => !p.IsEliminated).ToList();
|
||||
}
|
||||
|
||||
@@ -27,6 +27,16 @@ public class Player
|
||||
|
||||
public bool IsSkipped { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Počet kariet do ruky v Olympijskom režime (kto prehrá kolo, klesá o 1).
|
||||
/// </summary>
|
||||
public int OlympicCardsCount { get; set; } = 5;
|
||||
|
||||
/// <summary>
|
||||
/// Či je hráč vyradený z Olympijského turnaja.
|
||||
/// </summary>
|
||||
public bool IsEliminated => OlympicCardsCount <= 0;
|
||||
|
||||
public Player() { }
|
||||
|
||||
public Player(string name, PlayerType type, string avatar = "👤", AIDifficulty difficulty = AIDifficulty.Medium)
|
||||
|
||||
@@ -41,4 +41,10 @@ public class RuleOptions
|
||||
/// Zvolený vizuálny štýl balíčka ("original" alebo "spongebob").
|
||||
/// </summary>
|
||||
public string SelectedDeck { get; set; } = "original";
|
||||
|
||||
/// <summary>
|
||||
/// Olympijský režim: Vyraďovací turnaj. Kto prehrá kolo, má v ďalšom o 1 kartu menej.
|
||||
/// Hrá sa až kým nezostane iba jeden celkový víťaz.
|
||||
/// </summary>
|
||||
public bool OlympicMode { get; set; } = false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user