inial impl

This commit is contained in:
Michal Vrba
2026-08-28 13:59:36 +02:00
parent efec4e62c5
commit 6abf0f91a0
180 changed files with 64651 additions and 0 deletions
+129
View File
@@ -0,0 +1,129 @@
namespace Faraon.Core.Models;
public enum Suit
{
Hearts = 0, // Červeň / Srdce ❤️
Leaves = 1, // Zeleň / List 🍃
Acorns = 2, // Žaluď 🌰
Bells = 3 // Guľa 🔔
}
public enum Rank
{
Seven = 7,
Eight = 8,
Nine = 9,
Ten = 10,
UnderKnave = 11, // Dolník / Spodok
OverKnave = 12, // Horník / Filak / Menič
King = 13, // Kráľ
Ace = 14 // Eso
}
public record Card(Suit Suit, Rank Rank)
{
public string Id => $"{Suit}_{Rank}";
public string Name => $"{RankName} ({SuitName})";
public string ShortName => Rank switch
{
Rank.Seven => "VII",
Rank.Eight => "VIII",
Rank.Nine => "IX",
Rank.Ten => "X",
Rank.UnderKnave => "D",
Rank.OverKnave => "H",
Rank.King => "K",
Rank.Ace => "E",
_ => Rank.ToString()
};
public string NumericShortName => Rank switch
{
Rank.Seven => "7",
Rank.Eight => "8",
Rank.Nine => "9",
Rank.Ten => "10",
Rank.UnderKnave => "D",
Rank.OverKnave => "H",
Rank.King => "K",
Rank.Ace => "E",
_ => Rank.ToString()
};
public string RankName => Rank switch
{
Rank.Seven => "Sedma",
Rank.Eight => "Osma",
Rank.Nine => "Deviatka",
Rank.Ten => "Desiatka",
Rank.UnderKnave => "Dolník",
Rank.OverKnave => "Horník",
Rank.King => "Kráľ",
Rank.Ace => "Eso",
_ => Rank.ToString()
};
public string SuitName => Suit switch
{
Suit.Hearts => "Červeň",
Suit.Leaves => "Zeleň",
Suit.Acorns => "Žaluď",
Suit.Bells => "Guľa",
_ => Suit.ToString()
};
public string SuitSymbol => Suit switch
{
Suit.Hearts => "♥",
Suit.Leaves => "🍃",
Suit.Acorns => "🌰",
Suit.Bells => "🔔",
_ => "?"
};
public string SuitColor => Suit switch
{
Suit.Hearts => "#d62828", // Tradičná sýta červeň
Suit.Leaves => "#2d6a4f", // Tradičná lesná zeleň
Suit.Acorns => "#8b5a2b", // Hnedo-zlatý žaluď
Suit.Bells => "#d48b1a", // Zlatistá rolničková guľa
_ => "#ffffff"
};
public string SeasonName => (Rank == Rank.Ace) ? Suit switch
{
Suit.Hearts => "Jar",
Suit.Leaves => "Leto",
Suit.Acorns => "Jeseň",
Suit.Bells => "Zima",
_ => ""
} : "";
public string CharacterName => Rank switch
{
Rank.OverKnave => Suit switch
{
Suit.Hearts => "Wilhelm Tell",
Suit.Leaves => "Walter Fürst",
Suit.Acorns => "Ulrich Rudenz",
Suit.Bells => "Stauffacher",
_ => "Horník"
},
Rank.UnderKnave => Suit switch
{
Suit.Hearts => "Kuoni",
Suit.Leaves => "Itel Reding",
Suit.Acorns => "Stüssi",
Suit.Bells => "Harrass",
_ => "Dolník"
},
_ => ""
};
public bool IsSeven => Rank == Rank.Seven;
public bool IsAce => Rank == Rank.Ace;
public bool IsHornik => Rank == Rank.OverKnave;
public bool IsRedSeven => Rank == Rank.Seven && Suit == Suit.Hearts;
}
+42
View File
@@ -0,0 +1,42 @@
namespace Faraon.Core.Models;
public class Deck
{
private readonly Random _random;
public Deck(int? seed = null)
{
_random = seed.HasValue ? new Random(seed.Value) : new Random();
}
public static List<Card> CreateStandardDeck()
{
var cards = new List<Card>(32);
foreach (Suit suit in Enum.GetValues<Suit>())
{
foreach (Rank rank in Enum.GetValues<Rank>())
{
cards.Add(new Card(suit, rank));
}
}
return cards;
}
public List<Card> CreateShuffledDeck()
{
var deck = CreateStandardDeck();
Shuffle(deck);
return deck;
}
public void Shuffle<T>(List<T> list)
{
int n = list.Count;
while (n > 1)
{
n--;
int k = _random.Next(n + 1);
(list[k], list[n]) = (list[n], list[k]);
}
}
}
+28
View File
@@ -0,0 +1,28 @@
namespace Faraon.Core.Models;
public enum GameEventType
{
GameStarted,
CardPlayed,
CardsBurned,
CardDrawn,
SevenStacked,
AceSkipped,
AceCountered,
SuitChanged,
PlayerRevived,
PlayerFinished,
GameOver,
DeckReshuffled
}
public record GameEvent(
GameEventType Type,
Player? SourcePlayer,
Player? TargetPlayer = null,
Card? Card = null,
List<Card>? Cards = null,
Suit? ChosenSuit = null,
int ExtraData = 0,
string Message = ""
);
+31
View File
@@ -0,0 +1,31 @@
namespace Faraon.Core.Models;
public enum TurnState
{
Playing,
SelectingSuit,
PassScreen,
GameOver
}
public class GameState
{
public List<Player> Players { get; set; } = new();
public int CurrentPlayerIndex { get; set; } = 0;
public List<Card> DrawDeck { get; set; } = new();
public List<Card> DiscardPile { get; set; } = new();
public Suit? ActiveSuit { get; set; }
public int PendingDrawCount { get; set; } = 0;
public bool PendingSkip { get; set; } = false;
public RuleOptions Rules { get; set; } = new();
public bool IsGameOver { get; set; } = false;
public Player? LastFinishedPlayer { get; set; }
public int TurnCount { get; set; } = 0;
public TurnState TurnState { get; set; } = TurnState.Playing;
public Player? PendingHornikPlayer { get; set; }
public Card? TopCard => DiscardPile.Count > 0 ? DiscardPile[^1] : null;
public Player CurrentPlayer => Players.Count > 0 ? Players[CurrentPlayerIndex % Players.Count] : new Player();
public int ActivePlayersCount => Players.Count(p => !p.HasFinished);
}
+46
View File
@@ -0,0 +1,46 @@
namespace Faraon.Core.Models;
public enum PlayerType
{
Human = 0,
AI = 1
}
public enum AIDifficulty
{
Easy = 0,
Medium = 1,
Hard = 2
}
public class Player
{
public string Id { get; init; } = Guid.NewGuid().ToString("N");
public string Name { get; set; } = "Hráč";
public PlayerType Type { get; set; } = PlayerType.Human;
public AIDifficulty Difficulty { get; set; } = AIDifficulty.Medium;
public string Avatar { get; set; } = "👑";
public List<Card> Hand { get; } = new();
public int? FinishedPosition { get; set; }
public bool HasFinished => FinishedPosition.HasValue;
public bool IsSkipped { get; set; }
public Player() { }
public Player(string name, PlayerType type, string avatar = "👤", AIDifficulty difficulty = AIDifficulty.Medium)
{
Name = name;
Type = type;
Avatar = avatar;
Difficulty = difficulty;
}
public void Reset()
{
Hand.Clear();
FinishedPosition = null;
IsSkipped = false;
}
}
+44
View File
@@ -0,0 +1,44 @@
namespace Faraon.Core.Models;
public class RuleOptions
{
/// <summary>
/// Počet kariet rozdaných každému hráčovi na začiatku (zvyčajne 4 alebo 5).
/// </summary>
public int InitialCardCount { get; set; } = 5;
/// <summary>
/// Ak je zapnuté, sedma na sedmu pridáva ďalšie +2 karty (kumulácia trestu).
/// </summary>
public bool StackSevens { get; set; } = true;
/// <summary>
/// Ak je zapnuté, eso možno prebiť vlastným esom a preniesť státie na ďalšieho hráča.
/// </summary>
public bool CounterAceWithAce { get; set; } = true;
/// <summary>
/// Červená sedma vracia do hry hráča, ktorý sa už zbavil všetkých kariet (posledného víťaza).
/// </summary>
public bool RedSevenRevives { get; set; } = true;
/// <summary>
/// Zahranie 4 rovnakých kariet naraz ("Spálenie"). Spáli kôpku a hráč hrá znova.
/// </summary>
public bool FourOfAKindBurns { get; set; } = true;
/// <summary>
/// Režim Pass & Play so súkromnou clonou medzi ťahmi viacerých živých hráčov.
/// </summary>
public bool PassAndPlayPrivacyScreen { get; set; } = false;
/// <summary>
/// Rýchlosť AI ťahov v milisekundách (pre plynulé sledovanie animácií).
/// </summary>
public int AIDelayMs { get; set; } = 900;
/// <summary>
/// Zvolený vizuálny štýl balíčka ("original" alebo "spongebob").
/// </summary>
public string SelectedDeck { get; set; } = "original";
}