/// <summary> /// Vrací všechny platné tahy pro zadanou pozici a pro zadaného hráče. /// </summary> public static List<Tah> VratPlatneTahy(Pozice pole, Manazer.StavPole hrac, HraciDeska hraciDeska) { if(hraciDeska.Hrac(pole) == hrac) return VratPlatneTahy(pole.Radek, pole.Sloupec, hrac, hraciDeska); return new List<Tah>(); }
/*public static Tah VratNejlepsiTah(HraciDeska hraciDeska, Manazer.StavPole hrac, int hloubka) { GenerujVsechnyTahy(hraciDeska, hrac, hloubka, true); return vyslednyTah; }*/ public static void NejlepsiTah(HraciDeska hraciDeska, Manazer.StavPole hrac, int hloubka) { vlakno = new Thread(() => { GenerujVsechnyTahy(hraciDeska, hrac, hloubka, true); AkcePoNalezeniTahu(vyslednyTah); }); vlakno.Start(); }
/// <summary> /// Zjistíme, jestli je daný tah validní. /// </summary> public static bool ValidniTah(int radekKam, int sloupecKam, int radekOdkud, int sloupecOdkud, Manazer.StavPole hrac, HraciDeska hraciDeska) { return DoBoku(radekKam, sloupecKam, radekOdkud, sloupecOdkud) || Dopredu(radekKam, sloupecKam, radekOdkud, sloupecOdkud, hrac) || Diagonalne(radekKam, sloupecKam, radekOdkud, sloupecOdkud, hrac) || Skok(radekKam, sloupecKam, radekOdkud, sloupecOdkud, hrac, hraciDeska); }
/// <summary> /// Ohodonotí danou pozici na hrací desce z pohledu útočníka. /// Tedy čím více bodů, tím lépe pro útočníka (a naopak pro obránce). /// </summary> /// <returns>Ohodnocení pozice vyjádřené v celých bodech (int).</returns> public static int Ohodnot(HraciDeska hraciDeska) { int stupen; Random rand = new Random(); // Za každého živého útočníku +100 bodů stupen = hraciDeska.PocetUtocniku() * 100; int PocetUtocnikuVPevnosti = 0; for(int i = 0; i < hraciDeska.rozmer; i++) { for(int j = 0; j < hraciDeska.rozmer; j++) { if(hraciDeska.Hrac(i, j) == Manazer.StavPole.utok) { if(HraciDeska.Pevnost(i, j)) { // Pokud jsou všichni útočníci v pevnosti, jistě je to nejlepší tah if (++PocetUtocnikuVPevnosti == 9) { return Int16.MaxValue; } // Za každého panáčka v horním řádku pevnosti +65 bodů if(i == 0) stupen += 65; // Za každého panáčka na levém či pravém boku pevnosti +55 bodů if((j == 2 || j == 4) && (i != 2)) stupen += 55; // Za každého panáčka v penosti +20 bodů stupen += 35; } // Za každý pohyb o pole dopředu +10 bodů stupen += ((7 - i) * 10); // Přidáme náhodné číslo od 0 do 9, aby počítač netáhl vždy stejně stupen += rand.Next(10); } else if(hraciDeska.Hrac(i, j) == Manazer.StavPole.obrana) { // Čím dál je obránce od pevnosti, tím lépe stupen += 25 * i; } } } return stupen; }
/// <summary> /// Zkopíruje hrací desku. /// </summary> /// <returns>Kopie desky.</returns> public HraciDeska Copy() { HraciDeska novaDeska = new HraciDeska(); for(int i = 0; i < rozmer; i++) for(int j = 0; j < rozmer; j++) novaDeska.deska[i, j] = deska[i, j]; novaDeska.aktualniTah = aktualniTah; return novaDeska; }
/// <summary> /// Vrací všechny platné tahy pro zadanou pozici a pro zadaného hráče. /// </summary> public static List<Tah> VratPlatneTahy(int radekOdkud, int sloupecOdkud, Manazer.StavPole hrac, HraciDeska hraciDeska) { List<Tah> platneTahy = new List<Tah>(); if(hraciDeska.Hrac(radekOdkud, sloupecOdkud) == hrac) { for(int i = 0; i < hraciDeska.rozmer; i++) { for(int j = 0; j < hraciDeska.rozmer; j++) { if(ValidniTah(i, j, radekOdkud, sloupecOdkud, hrac, hraciDeska) && hraciDeska.MuzemeTahnout(i, j)) { Tah tah = new Tah(new Pozice(radekOdkud, sloupecOdkud), new Pozice(i, j)); platneTahy.Add(tah); } } } } return platneTahy; }
/// <summary> /// Zjišťuje, zda již někdo nevyhrál. Vrací buď hráče, který vyhrál nebo vrací Hraci.mimo. /// </summary> public static Manazer.MoznostiVyher KdoVyhral(HraciDeska hraciDeska) { if (hraciDeska.PocetUtocniku() < 9) { return Manazer.MoznostiVyher.obrana; } if (hraciDeska.ObsazenaPevnost()) { return Manazer.MoznostiVyher.utok; } if(ZablokovanyHrac(Manazer.StavPole.obrana, hraciDeska)) { return Manazer.MoznostiVyher.utok; } if(ZablokovanyHrac(Manazer.StavPole.utok, hraciDeska)) { return Manazer.MoznostiVyher.obrana; } return Manazer.MoznostiVyher.nikdo; }
/// <summary> /// Vygeneruje všechny možné situace hry do zadané hloubky a následně do /// slotu "vyslednyTah" uloží nejlepší pozici. /// </summary> private static int GenerujVsechnyTahy(HraciDeska hraciDeska, Manazer.StavPole hrac, int hloubka, bool prvniFunkce) { if(hloubka == 0) return Ohodnoceni.Ohodnot(hraciDeska); List<List<Tah>> validniTahy = Rozhodci.VratVsechnyPlatneTahy(hrac, hraciDeska); List<int> ohodnoceni = new List<int>(); Manazer.StavPole dalsiHrac; if(hrac == Manazer.StavPole.obrana) dalsiHrac = Manazer.StavPole.utok; else dalsiHrac = Manazer.StavPole.obrana; for(int i = 0; i < validniTahy.Count; i++) { for(int j = 0; j < validniTahy[i].Count; j++) { HraciDeska novaDeska = hraciDeska.Copy(); // HraciDeska novaDeska = (HraciDeska) hraciDeska.Clone(); novaDeska.Tahni(validniTahy[i][j]); novaDeska.OdstranPreskoceneKameny(validniTahy[i][j]); ohodnoceni.Add(GenerujVsechnyTahy(novaDeska, dalsiHrac, hloubka - 1, false)); } } int pomoc; if(hrac == Manazer.StavPole.utok) { pomoc = Int32.MinValue; } else { pomoc = Int32.MaxValue; } foreach(int cislo in ohodnoceni) { if(hrac == Manazer.StavPole.utok) { if(cislo > pomoc) pomoc = cislo; } else { if(cislo < pomoc) pomoc = cislo; } } if(prvniFunkce) { int index = ohodnoceni.IndexOf(pomoc); int i, j, citac; citac = 0; for(i = 0; i < validniTahy.Count; i++) { for(j = 0; j < validniTahy[i].Count; j++) { if(citac++ == index) vyslednyTah = validniTahy[i][j]; } } return 0; } return pomoc; }
public Schranka(Manazer ManazerHry, HraciDeska AktualniHraciDeska) { this.AktualniHraciDeska = AktualniHraciDeska; this.ManazerHry = ManazerHry; }
/// <summary> /// Vrací všechny platné tahy daného hráče v tomto kole /// </summary> public static List<List<Tah>> VratVsechnyPlatneTahy(Manazer.StavPole hrac, HraciDeska hraciDeska) { List<List<Tah>> vsechnyPlatneTahy = new List<List<Tah>>(); for(int i = 0; i < hraciDeska.rozmer; i++) for(int j = 0; j < hraciDeska.rozmer; j++) { // Zjistíme všechny platné tahy z dané pozice... List<Tah> tahy = VratPlatneTahy(i, j, hrac, hraciDeska); // ...a pokud z této pozice můžeme alespoň někam táhnout, uložíme si tah if(tahy.Count > 0) vsechnyPlatneTahy.Add(tahy); } // Pokud obránce může skákat, zahodíme obyčejné tahy a zjistíme, // jestli nemůže obránce skákat ještě dál (vícenásobný skok). if(MuzeObranceSkakat(vsechnyPlatneTahy)) { List<Pozice> poziceObrancu = hraciDeska.VratPoziceObrancu(); vsechnyPlatneTahy = OdstranObycejneTahy(vsechnyPlatneTahy); // Skoky prvního obránce Skoky skoky = VsechnySkoky(poziceObrancu[0], hraciDeska); // Skoky druhého obránce Skoky skoky2 = VsechnySkoky(poziceObrancu[1], hraciDeska); vsechnyPlatneTahy.Clear(); // serializujeme skoky do listů List<Tah> platneTahy1 = Serializace(skoky); List<Tah> platneTahy2 = Serializace(skoky2); // Pokud může obránce alespoň jednou skočit, uložíme si skok if(platneTahy1.Count != 0) vsechnyPlatneTahy.Add(platneTahy1); if(platneTahy2.Count != 0) vsechnyPlatneTahy.Add(platneTahy2); } return vsechnyPlatneTahy; }
/// <summary> /// Zablokovali jsme obránce? /// </summary> private static bool ZablokovanyObrance(HraciDeska hraciDeska) { List<Pozice> obranci; // obranci = hraciDeska.VratPoziceObrancu(); obranci = hraciDeska.VratPoziceHrace(Manazer.StavPole.obrana); foreach(Pozice pole in obranci) if((VratPlatneTahy(pole, Manazer.StavPole.obrana, hraciDeska)).Count > 0) return false; return true; }
/// <summary> /// Zablokovali jsme na hrací desce daného hráče? /// </summary> private static bool ZablokovanyHrac(Manazer.StavPole barvaHrace, HraciDeska hraciDeska) { List<Pozice> hraci; hraci = hraciDeska.VratPoziceHrace(barvaHrace); foreach(Pozice pole in hraci) if((VratPlatneTahy(pole, barvaHrace, hraciDeska)).Count > 0) return false; return true; }
/// <summary> /// Vrací všechny (i násobné) skoky jednoho obránce. /// </summary> private static Skoky VsechnySkoky(Pozice souradniceObrance, HraciDeska hraciDeska) { List<Tah> obrancovySkoky; Skoky skok = new Skoky(); skok.odkud = souradniceObrance; skok.skoky = null; obrancovySkoky = KamMuzeObranceSkocit(souradniceObrance, hraciDeska); if(obrancovySkoky.Count != 0) { skok.skoky = new List<Skoky>(); foreach(Tah tah in obrancovySkoky) { HraciDeska novaHraciDeska; novaHraciDeska = hraciDeska.Copy(); // novaHraciDeska = (HraciDeska) hraciDeska.Clone(); novaHraciDeska.Tahni(tah); novaHraciDeska.OdstranPreskoceneKameny(tah); Skoky novySkok = new Skoky(tah.seznamTahu[1], null); novySkok.deska = novaHraciDeska; skok.skoky.Add(novySkok); } HelpSkoky(skok); } return skok; }
/// <summary> /// Skáče obránce horizontálně nebo vertikálně nebo diagonálně? /// </summary> private static bool Skok(int radekKam, int sloupecKam, int radekOdkud, int sloupecOdkud, Manazer.StavPole hrac, HraciDeska hraciDeska) { if(hrac == Manazer.StavPole.obrana) { Manazer.StavPole hracNaPozici; int rozdilRadku = Math.Abs(radekKam - radekOdkud); int rozdilSloupcu = Math.Abs(sloupecKam - sloupecOdkud); // Obecný skok if((sloupecKam == sloupecOdkud && rozdilRadku == 2) || (radekKam == radekOdkud && rozdilSloupcu == 2) || (rozdilRadku == rozdilSloupcu && rozdilSloupcu == 2)) { int preskokRadek = (radekOdkud + radekKam) / 2; int preskokSloupec = (sloupecKam + sloupecOdkud) / 2; // Skáče obránce přes roh hrací desky? if((rozdilRadku == rozdilSloupcu && rozdilSloupcu == 2) && (((preskokRadek == 2) && (preskokSloupec == 1 || preskokSloupec == 5)) || ((preskokRadek == 4) && (preskokSloupec == 1 || preskokSloupec == 5)) || ((preskokRadek == 1) && (preskokSloupec == 2 || preskokSloupec == 4)) || ((preskokRadek == 5) && (preskokSloupec == 2 || preskokSloupec == 4)))) return false; hracNaPozici = hraciDeska.Hrac(preskokRadek, preskokSloupec); if(hracNaPozici == Manazer.StavPole.utok) { return true; } } } return false; }
/// <summary> /// Vrací všechny skoky jedné úrovně jednoho obránce. /// </summary> private static List<Tah> KamMuzeObranceSkocit(Pozice souradniceObrance, HraciDeska hraciDeska) { List<Tah> tahy; tahy = VratPlatneTahy(souradniceObrance, Manazer.StavPole.obrana, hraciDeska); tahy = OdstranObycejneTahy(tahy); return tahy; }
/// <summary> /// Prostě restartuje hru. /// </summary> public void Restart() { Deska = new HraciDeska(); NastaveniObranci = false; hracNaTahu = Manazer.StavPole.obrana; Deska.Restart(); this.KonecHry = false; PocetTahu = 0; Vitez = MoznostiVyher.nikdo; TahyZpet = new Stack<Tah>(); TahyVpred = new Stack<Tah>(); if(Obrance.umelaInteligence) { NastavObrance(); } }