156 lines
4.7 KiB
C#
156 lines
4.7 KiB
C#
namespace Faraon.Core.Engine;
|
|
|
|
using Faraon.Core.Models;
|
|
|
|
public static class ActionValidator
|
|
{
|
|
public static bool CanPlayCard(
|
|
Card card,
|
|
Card? topCard,
|
|
Suit? activeSuit,
|
|
int pendingDrawCount,
|
|
bool pendingSkip,
|
|
RuleOptions rules)
|
|
{
|
|
// 1. Ak je na stole trest zo sedmy (napr. +3, +6, +9)
|
|
if (pendingDrawCount > 0)
|
|
{
|
|
// Zelený dolník ruší sedmičky
|
|
if (rules.GreenUnderKnaveCancelsSevens && card.IsGreenUnderKnave)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
// Ak je povolené prebíjanie sediem, musí zahrať sedmu
|
|
return rules.StackSevens && card.IsSeven;
|
|
}
|
|
|
|
// 2. Ak je na stole eso (státie)
|
|
if (pendingSkip)
|
|
{
|
|
// Ak je povolené prebíjanie esa esom, musí zahrať eso
|
|
return rules.CounterAceWithAce && card.IsAce;
|
|
}
|
|
|
|
// 3. Ak je kôpka prázdna (začiatok hry)
|
|
if (topCard == null)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
// 4. Horník (Menič) sa môže zahrať na čokoľvek (keď nie je aktívny trest/eso)
|
|
if (card.IsHornik)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
// 4b. Červená sedma v režime AnyCardOneRound sa môže zahrať na ľubovoľnú kartu
|
|
if (card.IsRedSeven && rules.RedSevenMode == RedSevenMode.AnyCardOneRound)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
// 4c. Zelený dolník v režime UniversalWildcard ide na čokoľvek a naňho ide čokoľvek
|
|
if (rules.GreenUnderKnaveMode == GreenUnderKnaveMode.UniversalWildcard)
|
|
{
|
|
if (card.IsGreenUnderKnave || topCard.IsGreenUnderKnave)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
// 5. Ak bola zmenená farba Horníkom
|
|
if (activeSuit.HasValue)
|
|
{
|
|
// Musí sedieť zvolená farba (alebo zahrať ďalšieho Horníka, čo rieši bod 4)
|
|
return card.Suit == activeSuit.Value;
|
|
}
|
|
|
|
// 6. Bežné pravidlo: rovnaká farba ALEBO rovnaká hodnota
|
|
return card.Suit == topCard.Suit || card.Rank == topCard.Rank;
|
|
}
|
|
|
|
public static bool CanPlayCards(
|
|
List<Card> cards,
|
|
Card? topCard,
|
|
Suit? activeSuit,
|
|
int pendingDrawCount,
|
|
bool pendingSkip,
|
|
RuleOptions rules)
|
|
{
|
|
if (cards == null || cards.Count == 0) return false;
|
|
|
|
// Všetky karty musia mať rovnakú hodnotu
|
|
var firstRank = cards[0].Rank;
|
|
if (!cards.All(c => c.Rank == firstRank)) return false;
|
|
|
|
// 1. Ak je na stole trest zo sedmy
|
|
if (pendingDrawCount > 0)
|
|
{
|
|
if (rules.GreenUnderKnaveCancelsSevens && cards.Any(c => c.IsGreenUnderKnave))
|
|
{
|
|
return true;
|
|
}
|
|
return rules.StackSevens && cards.All(c => c.IsSeven);
|
|
}
|
|
|
|
// 2. Ak je na stole eso
|
|
if (pendingSkip)
|
|
{
|
|
return rules.CounterAceWithAce && cards.All(c => c.IsAce);
|
|
}
|
|
|
|
// 3. Ak je kôpka prázdna
|
|
if (topCard == null)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
// 4. Horníci sa dajú vyložiť kedykoľvek
|
|
if (firstRank == Rank.OverKnave)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
// 4b. Combo so Srdcovou/Červenou sedmou v režime AnyCardOneRound sa dá vyložiť na čokoľvek
|
|
if (firstRank == Rank.Seven && cards.Any(c => c.IsRedSeven) && rules.RedSevenMode == RedSevenMode.AnyCardOneRound)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
// 4c. Zelený dolník v režime UniversalWildcard
|
|
if (rules.GreenUnderKnaveMode == GreenUnderKnaveMode.UniversalWildcard)
|
|
{
|
|
if (cards.Any(c => c.IsGreenUnderKnave) || topCard.IsGreenUnderKnave)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
// 5. Ak bola zmenená farba Horníkom
|
|
if (activeSuit.HasValue)
|
|
{
|
|
// Aspoň jedna karta musí mať požadovanú farbu (prvá vyložená)
|
|
return cards.Any(c => c.Suit == activeSuit.Value);
|
|
}
|
|
|
|
// 6. Bežné pravidlo: aspoň jedna karta musí sedieť farbou na topCard, ALEBO hodnota kariet sedí na topCard
|
|
return firstRank == topCard.Rank || cards.Any(c => c.Suit == topCard.Suit);
|
|
}
|
|
|
|
public static bool CanBurnCards(
|
|
List<Card> cards,
|
|
int pendingDrawCount,
|
|
bool pendingSkip,
|
|
RuleOptions rules)
|
|
{
|
|
if (!rules.FourOfAKindBurns) return false;
|
|
if (pendingDrawCount > 0 || pendingSkip) return false;
|
|
if (cards.Count != 4) return false;
|
|
|
|
// Všetky 4 karty musia mať rovnakú hodnotu
|
|
var firstRank = cards[0].Rank;
|
|
return cards.All(c => c.Rank == firstRank);
|
|
}
|
|
}
|