284 lines
12 KiB
C#
284 lines
12 KiB
C#
namespace Faraon.Core.AI;
|
||
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using Faraon.Core.Models;
|
||
|
||
public static class AIDialogueService
|
||
{
|
||
private static readonly Random _rng = new();
|
||
|
||
// --- EASY (Začiatočník - prezrádza taktiku a neistotu) ---
|
||
private static readonly string[] EasyThinking =
|
||
[
|
||
"Mám ešte jedno eso, len neviem či ho dať teraz...",
|
||
"Keby mi radšej prišla zeleň, to by bolo super.",
|
||
"Dúfam, že po mne nikto nehodí sedmu!",
|
||
"Mám len samé vysoké karty, čo s tým...",
|
||
"Asi ti zmením farbu, táto sa mi veľmi nepáči.",
|
||
"Ktorú kartu dať skôr? Táto vyzerá celkom pekne.",
|
||
"Nemám veľa možností, toto snáď vyjde.",
|
||
"Mám tu jedného horníka, ale bojím sa ho použiť.",
|
||
"Ešteže mám túto záchrannú kartu...",
|
||
"Snáď nikto nezbadá, že mi ostala už len jedna karta!",
|
||
"Hm... pravidlá hovoria, že toto môžem zahrať, nie?",
|
||
"Tento ťah snáď nebude úplná katastrofa.",
|
||
"Čo ak zahrám toto a súper ma zničí?",
|
||
"Uff, dúfam, že nemáš sedmu na ruke."
|
||
];
|
||
|
||
// --- MEDIUM (Taktik - realistické premýšľanie) ---
|
||
private static readonly string[] MediumThinking =
|
||
[
|
||
"Skúsim ti podržať farbu, nech nemôžeš vyložiť.",
|
||
"Túto sedmu si radšej pošetrím na neskôr.",
|
||
"Pozrime sa, čo s týmto urobíš.",
|
||
"Ak teraz zahrám túto kartu, ďalší ťah mám voľný.",
|
||
"Idem po istote, netreba zbytočne riskovať.",
|
||
"Vidím, že zbieraš túto farbu, tak ti ju zmením.",
|
||
"Rýchle combo by ťa teraz mohlo prekvapiť.",
|
||
"Mením taktiku na rýchle vyprázdnenie ruky.",
|
||
"Kľúčové bude neprepustiť ťah bez tlaku.",
|
||
"Opatrný ťah, ešte nie je čas na otvorené finále.",
|
||
"Počítam karty, toto by malo bezpečne prejsť.",
|
||
"Skúsim ťa prinútiť potiahnuť z balíčka."
|
||
];
|
||
|
||
// --- HARD (Veľmajster - psychologické blufovanie a prevaha) ---
|
||
private static readonly string[] HardThinking =
|
||
[
|
||
"Presne do tejto pasce som ťa potreboval dostať.",
|
||
"Mám v ruke presne to, čo ťa bude bolieť.",
|
||
"Matematicky ti zostávajú maximálne dva ťahy.",
|
||
"Risk je zisk. Priprav sa na prekvapenie.",
|
||
"Túto hru mám už prečítanú od prvého kola.",
|
||
"Si si naozaj istý, že toto bol tvoj najlepší ťah?",
|
||
"Môj ďalší krok rozhodne o celom zápase.",
|
||
"Viem presne, aké karty ti ostali v ruke.",
|
||
"Pripravujem šach-mat, sleduj pozorne.",
|
||
"Všetko ide presne podľa môjho majstrovského plánu.",
|
||
"Tvoj osud je spečatený, žiadna záchrana nepríde.",
|
||
"Geniálny ťah si žiada trochu trpezlivosti."
|
||
];
|
||
|
||
// --- POSLEDNÁ KARTA (1 karta) ---
|
||
private static readonly string[] LastCardThoughts =
|
||
[
|
||
"Už mi chýba len jedna jediná karta!",
|
||
"Cítim vôňu víťazstva... už len krok!",
|
||
"Dúfam, že ma nikto nezablokuje v poslednej chvíli...",
|
||
"Kto ma teraz nezastaví, ten prehral zápas!",
|
||
"Už len jeden ťah a titul je môj!"
|
||
];
|
||
|
||
// --- ČELENIE SEDME (Facing Seven) ---
|
||
private static readonly string[] FacingSevenThoughts =
|
||
[
|
||
"Sedma?! Pozrime sa, či mám odpoveď...",
|
||
"Dúfam, že mám na ruke ďalšiu sedmu!",
|
||
"Toto bude bolieť, ak nemám obranu...",
|
||
"Ak mám Zeleného dolníka, tak sa vám vysmejem!"
|
||
];
|
||
|
||
// --- ČELENIE ESU (Facing Ace) ---
|
||
private static readonly string[] FacingAceThoughts =
|
||
[
|
||
"Eso? Skúsim to prebiť vlastným esom!",
|
||
"Zamrznúť teraz by bola veľká škoda...",
|
||
"Hľadám v ruke eso na prebitie..."
|
||
];
|
||
|
||
// --- BEŽNÉ LÍZANIE (Musí ťahať z balíčka) ---
|
||
private static readonly string[] MustDrawThoughts =
|
||
[
|
||
"Nič mi nesedí, musím líznuť z balíčka...",
|
||
"Snáď mi príde niečo poriadne...",
|
||
"Balíček, nesklam ma v tejto chvíli!",
|
||
"Škoda, tento ťah musím potiahnuť kartu."
|
||
];
|
||
|
||
// --- REAKCIE NA UDALOSTI ---
|
||
private static readonly string[] FreezeReactions =
|
||
[
|
||
"Brrr, to je ale poriadna zima!",
|
||
"Zamrzol som na jedno celé kolo...",
|
||
"Kto tu pustil túto sibírsku fujavicu?!",
|
||
"Počkaj, hneď ako rozmrznem, ti to vrátim!",
|
||
"Stojím, ale môj čas ešte len príde.",
|
||
"Mráz mi nevadí, aspoň lepšie premyslím stratégiu."
|
||
];
|
||
|
||
private static readonly string[] AceCounterReactions =
|
||
[
|
||
"Žiadne státie! Moje eso okamžite rozpúšťa ľad!",
|
||
"Na mňa si s mrazom neprídeš!",
|
||
"Vraciam ti to aj s úrokmi, stojíš ty!"
|
||
];
|
||
|
||
private static readonly string[] SmallPenaltyDrawReactions =
|
||
[
|
||
"Ejha, +3 karty? To ešte hravo zvládnem.",
|
||
"No pekne, sedma ma neobišla...",
|
||
"Dobre, beriem 3, ale vrátim vám ich dvojnásobne!"
|
||
];
|
||
|
||
private static readonly string[] BigPenaltyDrawReactions =
|
||
[
|
||
"Ejha, toľko kariet mi do ruky ani nevojde!",
|
||
"To je nejaká organizovaná pomsta?!",
|
||
"Kde mám teraz zohnať miesto na ruke pre toľko kariet?!",
|
||
"No výborne, zachvíľu budem mať celý balíček...",
|
||
"Tento masívny trest vám v ďalšom kole nezabudnem!"
|
||
];
|
||
|
||
private static readonly string[] SevenCanceledReactions =
|
||
[
|
||
"Haha, Zelený dolník vás zachránil!",
|
||
"Štít aktivovaný, dnes žiadne ťahanie sediem!",
|
||
"Itel Reding hovorí jasné: Dnes nie!",
|
||
"Sedmy vymazané na nulu, ideme ďalej!"
|
||
];
|
||
|
||
private static readonly string[] RevivedTargetReactions =
|
||
[
|
||
"Znova žijem! Pozor na mňa!",
|
||
"Červená sedma robí zázraky! Som späť v hre!",
|
||
"Ešte sme neskončili, návrat šampióna!"
|
||
];
|
||
|
||
private static readonly string[] RevivedSourceReactions =
|
||
[
|
||
"Nikam neodchádzaš, ešte si s tebou zahrám!",
|
||
"Vraciam ťa späť do hry, zábava pokračuje!",
|
||
"Predčasná radosť, poď pekne naspäť k stolu!"
|
||
];
|
||
|
||
private static readonly string[] SuitChangeReactions =
|
||
[
|
||
"Prepínam hru na moju obľúbenú farbu!",
|
||
"Uvidíme, či máte na túto farbu odpoveď...",
|
||
"Trochu to tu zamiešame a zmeníme smer!"
|
||
];
|
||
|
||
private static readonly string[] BurnReactions =
|
||
[
|
||
"BUM! Všetko zhorelo na prach!",
|
||
"Spálené! A ťahám znova!",
|
||
"Dokonalé 4 karty, stôl je čistý!"
|
||
];
|
||
|
||
public static string GetThinkingDialogue(Player player, GameState state)
|
||
{
|
||
if (player.Hand.Count == 1)
|
||
{
|
||
return PickRandom(LastCardThoughts);
|
||
}
|
||
|
||
if (state.PendingDrawCount > 0)
|
||
{
|
||
return PickRandom(FacingSevenThoughts);
|
||
}
|
||
|
||
if (state.PendingSkip)
|
||
{
|
||
return PickRandom(FacingAceThoughts);
|
||
}
|
||
|
||
return player.Difficulty switch
|
||
{
|
||
AIDifficulty.Easy => PickRandom(EasyThinking),
|
||
AIDifficulty.Hard => PickRandom(HardThinking),
|
||
_ => PickRandom(MediumThinking)
|
||
};
|
||
}
|
||
|
||
public static string GetMustDrawDialogue(Player player)
|
||
{
|
||
return PickRandom(MustDrawThoughts);
|
||
}
|
||
|
||
public static string GetEventReaction(GameEvent e, Player player)
|
||
{
|
||
return e.Type switch
|
||
{
|
||
GameEventType.AceSkipped when e.SourcePlayer == player => PickRandom(FreezeReactions),
|
||
GameEventType.AceCountered when e.SourcePlayer == player => PickRandom(AceCounterReactions),
|
||
GameEventType.SevenStacked when e.TargetPlayer == player || (e.ExtraData > 0 && e.SourcePlayer != player) =>
|
||
e.ExtraData >= 6 ? PickRandom(BigPenaltyDrawReactions) : PickRandom(SmallPenaltyDrawReactions),
|
||
GameEventType.SevenCanceled when e.SourcePlayer == player => PickRandom(SevenCanceledReactions),
|
||
GameEventType.PlayerRevived when e.TargetPlayer == player => PickRandom(RevivedTargetReactions),
|
||
GameEventType.PlayerRevived when e.SourcePlayer == player => PickRandom(RevivedSourceReactions),
|
||
GameEventType.SuitChanged when e.SourcePlayer == player => PickRandom(SuitChangeReactions),
|
||
GameEventType.CardsBurned when e.SourcePlayer == player => PickRandom(BurnReactions),
|
||
_ => ""
|
||
};
|
||
}
|
||
|
||
public record CardJoke(string Icon, string Category, string Setup, string Punchline);
|
||
|
||
// --- VTIPY: MASÍVNY TREST (9 - 12+ kariet) ---
|
||
private static readonly CardJoke[] MultiDrawJokes =
|
||
[
|
||
new("🎒", "KAUZÁLNY BATOH", "Pýta sa Faraón hráča pri stole: 'Prečo si prišiel na zápas s turistickým ruksakom?'", "– 'Aby sa mi tam zmestili všetky tie sedmičky z balíčka!'"),
|
||
new("🏢", "VRCHOL OPTIMIZMU", "Viete, čo je vrchol hráčskeho optimizmu?", "– Keď po 12 potiahnutých kartách zahlásiš: 'Počkajte, ešte dve kolá a končím!'"),
|
||
new("🏗️", "STAVEBNÝ ZÁMER", "Rozprávajú sa dvaja architekti pri stole:", "– 'Z toľkých kariet v ruke sa už dá postaviť pekný trojizbový byt aj s terasou!'"),
|
||
new("🍕", "RODINNÁ PIZZA", "Aký je rozdiel medzi rodinnou pizzou a hráčom s 12 kartami na ruke?", "– Rodinná pizza aspoň niekoho pri stole naozaj poteší!"),
|
||
new("📜", "DAŇ Z NEHNUTEĽNOSTI", "Dôležitý oznam od správcu turnaja:", "– Hráč s viac ako 10 kartami začína platiť daň za zastavanú plochu stola!")
|
||
];
|
||
|
||
// --- VTIPY: SPÁLENIE (4 rovnaké karty) ---
|
||
private static readonly CardJoke[] BurnJokes =
|
||
[
|
||
new("🎩", "ILUZIONISTA", "Kúzelník na javisku: 'A teraz sledujte pozorne, nechám zmiznúť 4 karty!'", "– Hráč z rohu kričí: 'Nič nové, to robím v každom kole spálením!'"),
|
||
new("🚒", "POŽIARNY POPLACH", "Hasiči práve vyhlásili výjazd k nášmu hernému stolu!", "– Niekto tu práve odpálil 4 rovnaké karty a stôl ľahol popolom!"),
|
||
new("🧙", "LEGENDA V OHNI", "Stretnú sa 4 rovnaké karty v balíčku a jedna hovorí:", "– 'Dnes z nás bude buď slávna legenda, alebo čistý popol!'"),
|
||
new("🔥", "ČISTÁ POÉZIA", "Spáliť 4 karty naraz jedným ťahom nie je len obyčajné šťastie...", "– ...je to čisté vizuálne umenie a nočná mora pre súperov!")
|
||
];
|
||
|
||
// --- VTIPY: DLHÁ HRA (TurnCount >= 28) ---
|
||
private static readonly CardJoke[] LongGameJokes =
|
||
[
|
||
new("⏳", "RODINNÝ DÔCHODOK", "Manželka volá kartárovi: 'Kedy už prídeš domov z toho zápasu?'", "– 'Drahá, ešte jedno kolo a môžeme ísť rovno spolu do dôchodku!'"),
|
||
new("🏛️", "PAMIATKOVÝ ÚRAD", "Táto partia trvá už tak neskutočne dlho...", "– ...že si na ďalší ťah budeme musieť pýtať povolenie od pamiatkárov!"),
|
||
new("🧔", "ČAS NA HOLENIE", "Začiatok zápasu: hladko oholení mladíci plní síl.", "– Aktuálny stav: fúzatí veteráni čakajúci na záchrannú zeleň!"),
|
||
new("🕰️", "ŠPORTOVÝ VÝKON", "Lekár sa pýta pacienta: 'Koľko hodín denne venujete športu?'", "– 'Už šiestu hodinu bez prestávky sedím pri napínavom Faraónovi!'")
|
||
];
|
||
|
||
// --- VTIPY: OŽIVENIE (Červená sedma) ---
|
||
private static readonly CardJoke[] ReviveJokes =
|
||
[
|
||
new("🧟", "ZÁKAZ ODCHODU", "Lekár konštatuje: 'Hráč úspešne vyhral a odchádza domov.'", "– Červená sedma na to: 'Ešte nie, kamarát! Poď pekne naspäť k stolu!'"),
|
||
new("⚡", "VZKRIESENIE ŠAMPIÓNA", "Viete, čo je rýchlejšie ako ranný pondelkový budík?", "– Hráč vrátený do hry Červenou sedmou s chuťou po veľkej pomste!")
|
||
];
|
||
|
||
public static CardJoke? GetContextualJoke(GameEventType? type, int extraData, int turnCount)
|
||
{
|
||
if (type == GameEventType.SevenStacked && extraData >= 9)
|
||
{
|
||
return PickRandom(MultiDrawJokes);
|
||
}
|
||
|
||
if (type == GameEventType.CardsBurned)
|
||
{
|
||
return PickRandom(BurnJokes);
|
||
}
|
||
|
||
if (type == GameEventType.PlayerRevived)
|
||
{
|
||
return PickRandom(ReviveJokes);
|
||
}
|
||
|
||
if (turnCount >= 28 && turnCount % 16 == 0)
|
||
{
|
||
return PickRandom(LongGameJokes);
|
||
}
|
||
|
||
return null;
|
||
}
|
||
|
||
private static T PickRandom<T>(T[] options)
|
||
{
|
||
if (options == null || options.Length == 0) return default!;
|
||
return options[_rng.Next(options.Length)];
|
||
}
|
||
} |