// Generuje vsechny mozne tahy: private List <Tah> GenerujTahy(Deska deska, Hrac hracNaTahu) { List <Tah> vygenerovaneTahy = new List <Tah>(); List <Pozice> kamenyHrace = hracNaTahu.VratKameny(); List <Tah> vygenerovaneTahySPreskokem = new List <Tah>(); foreach (Pozice odkud in kamenyHrace) { foreach (Pozice kam in VratPoziceKamJdeSkocit(deska, odkud, false)) { List <Pozice> poziceProTah = new List <Pozice>(); poziceProTah.Add(odkud); poziceProTah.Add(kam); if (deska.JePosunPreskokemKameneProtihrace(odkud, kam)) { List <Tah> seznamVygenerovanychTahu = new List <Tah>(); deska.ProvedPosunKamene(odkud, kam, null); GenerujTahyPreskoku(kam, deska, poziceProTah, seznamVygenerovanychTahu); // tady se mi stradaji tahy, ktere jsou preskokem: vygenerovaneTahySPreskokem.AddRange(seznamVygenerovanychTahu); deska.VratZpetPosunKamene(kam, odkud, deska.VratPoziciMeziPosunem(kam, odkud)); continue; } vygenerovaneTahy.Add(MainWindow.VytvorTah(poziceProTah)); } } // Zamicham vypocitane tahy bez preskoku Zamichej(vygenerovaneTahy); // A pro ucinnejsi orezavani v alfa-beta alg. pridam na zacatek seznamu nejsilnejsi tahy, zrychluje to vypocet pomerne hodne vygenerovaneTahy.InsertRange(0, vygenerovaneTahySPreskokem); return(vygenerovaneTahy); }
// Ohodnoceni pozice private int OhodnotPozici(Deska deska, Hrac hracNaTahu) { int pocetKamenuHraceNaTahu = deska.VratPocetPozic(hracNaTahu.VratTypKameneHrace()); int pocetKamenuProtihrace = deska.VratPocetPozic(dispecerHry.VratProtihrace(hracNaTahu).VratTypKameneHrace()); return(pocetKamenuHraceNaTahu - pocetKamenuProtihrace); }
public void PridejDoHistorie(Tah tah, bool kopie) { ObservableCollection <string> tahy = new ObservableCollection <string>(); ObservableCollection <string> stavajiciTahy = new ObservableCollection <string>(); dispecer2 = MainWindow.GetDispecerHry(); // Vypis preskocenych kamenu: string preskoceneKameny = ""; foreach (Pozice pozice in tah.GetPreskoceneKameny) { preskoceneKameny += pozice.VratJakoText(); } // muj oficialni seznam tahu v Historii tahu tvoreny ciste tridami Tah cistySeznamOdehranychTahu.Add(tah); SetPocetTahuCelkem = cistySeznamOdehranychTahu.Count(); // tady v historii budu ukladat pocet tahu bez preskoku: int pocetBP = dispecer2.GetHra.GetPocetTahuBezPreskoku; int aktualniIndexTahu = cistySeznamOdehranychTahu.Count(); string jmenoHrace; Hrac kdoJeNaTahu = dispecer2.GetHracNaTahu; Hrac protiHrac = dispecer2.VratProtihrace(kdoJeNaTahu); if (kopie == true) { jmenoHrace = protiHrac.GetJmeno; } else { jmenoHrace = kdoJeNaTahu.GetJmeno; } string jedenTah = aktualniIndexTahu + ".tah " + jmenoHrace + " " + tah.ToString(); if (preskoceneKameny != "") { int pulka = preskoceneKameny.Length / 2; if (dispecer2.GetHracNaTahu.GetJePocitacovyHrac) { preskoceneKameny = preskoceneKameny.Substring(0, pulka); } jedenTah += " odstraněno " + preskoceneKameny.ToUpper(); } tahy = GetTahyVypsaneDetailne; tahy.Add(jedenTah); SetTahyVypsaneDetilane = tahy; VyvolejZmenu("TahyDoH"); VyvolejZmenu("GetTahyVypsaneDetailne"); }
// Podminky kdy neni kam dal tahnout: private bool NeniKamTahnout(Hrac hrac) { Deska deska = dispecerHry.GetDeska; List <Pozice> kamenyHrace = new List <Pozice>(deska.VratPoziceProTypKamene(hrac.VratTypKameneHrace())); foreach (Pozice p in kamenyHrace) { if (dispecerHry.GetGenerator.VratPoziceKamJdeSkocit(deska, p, false).Count() == 0) { continue; } return(false); } return(true); }
// Vrat hodnotu - protihrace: public Hrac VratProtihrace(Hrac hrac) { if (hrac.Equals(hrac1)) { return(hrac2); } if (hrac.Equals(hrac2)) { return(hrac1); } else { throw new Exception("Hrac neni hracem hry"); } }
// algoritmus alfa-beta private int Alfabeta(Deska deska, int hloubka, Hrac hracKteryHral, int alfa, int beta) { List <Tah> tahy = new List <Tah>(); Hrac hracNaTahu = dispecerHry.VratProtihrace(hracKteryHral); // zakladni podminky: if (dispecerHry.GetHra.HracProhral(hracNaTahu)) { return(-MAX); } if (dispecerHry.GetHra.HracVyhral(hracNaTahu)) { return(MAX); } if (dispecerHry.GetHra.JeRemiza()) { return(0); } if (hloubka == 0) { return(OhodnotPozici(deska, hracNaTahu)); } tahy = GenerujTahy(deska, hracNaTahu); for (int i = 0; i < tahy.Count(); ++i) { deska.ZahrajTah(tahy[i]); int cena = -Alfabeta(deska, hloubka - 1, hracNaTahu, Dal(-beta), Dal(-alfa)); cena = Bliz(cena); deska.vratTahZpet(tahy[i]); if (cena > alfa) { alfa = cena; if (cena >= beta) { return(beta); } } } return(alfa); }
// Zjisteni nejlepsiho tahu - sem vznasim dotaz z CodeBehind hlavniho okna public Tah GenerujNejlepsiTah(Deska deska, int hloubka, Hrac hracNaTahu) { // musim si nastavit instanci bw2 na instanci bw hlavniho okna, jen kvuli progress baru if (!MainWindow.GetDispecerHry().GetHracNaTahu.GetJePocitacovyHrac) { bw2 = MainWindow.bwNapoveda; } else { bw2 = MainWindow.bw; } List <Tah> tahy = new List <Tah>(); int indexNejlepsiho = 0; tahy = GenerujTahy(deska, hracNaTahu); int alfa = -MAX; jednoProcento = tahy.Count() / 100.0; // pro komunikaci s hlavnim oknem - mujProgressBar for (int i = 0; i < tahy.Count(); ++i) { pocetProcentTahu = i / jednoProcento; // doplneno k pocitani procent if (MainWindow.GetDispecerHry().GetZpomaleni) { switch (hloubka) // zpomaleni vypoctu tahu { case 1: System.Threading.Thread.Sleep(30); break; case 2: System.Threading.Thread.Sleep(27); break; case 3: System.Threading.Thread.Sleep(18); break; case 4: System.Threading.Thread.Sleep(18); break; default: break; } } // Tady vystupuju z cyklu, kdyz jsem stisknul Stop tlacitko: if (MainWindow.GetZrusVypocet) { MainWindow.bw.CancelAsync(); MainWindow.bwNapoveda.CancelAsync(); break; } bw2.ReportProgress((int)pocetProcentTahu); // komunikace s ovladacim prvkem mujProgressBar deska.ZahrajTah(tahy[i]); int cena = -Alfabeta(deska, hloubka - 1, hracNaTahu, -MAX, Dal(-alfa)); cena = Bliz(cena); deska.vratTahZpet(tahy[i]); if (cena > alfa) { alfa = cena; indexNejlepsiho = i; } } return(tahy[indexNejlepsiho]); }
// Vyhra je prohra druheho: public bool HracVyhral(Hrac hrac) { return(HracProhral(dispecerHry.VratProtihrace(hrac))); }
// Podminky Prohry: public bool HracProhral(Hrac hrac) { bool maloKamenu = hrac.VratPocetKamenu() < 2; return(maloKamenu || NeniKamTahnout(hrac)); }