/// <summary> /// Metoda pro vytvoření nejlepšího tahu /// </summary> /// <param name="hloubka"></param> /// <returns></returns> private List <int[]> GetBestMoves(int hloubka) { //vytvořime kopii seznamu všech tahů a pak ještě kolekci těch nejlepších tahů, které vrátíme List <int[]> nejlepsiTahy = new List <int[]>(); List <int[]> tahy = new List <int[]>(); //všechny tahy hráče na tahu, tj.bílého foreach (int[] tah in rules.GetMovesList()) { tahy.Add(tah.Clone() as int[]); } if (tahy.Count <= 1) //Pokud seznam obsahuje jen jeden, nebo žádný tah, tak se rovnou vrátí. Protože je povinost skákat. Tento tah je nejlepší, není potřeba nic prohledávat { return(tahy); } int hodnotaNejlepsihoTahu = -MAX; //Smyčka projede všechny tahy a provede je foreach (int[] tah in tahy) { board.Move(tah, false, false); //provedení rules.ChangePlayer(); //změna hráče rules.MovesGenerate(); //generování všech tahů pro hráče na tahu /*Tady bude první volání minimaxu, které nám vrátí nejvýhodnější hodnotu v daném směru. * Takže budeme vědět jak moc výhodný je pro nás tento směr. * Pokud je je lepší, než ty co už máme, tak je nahradíme. Pokud je stejný, tak ho k nim přidáme. * Pokud je horší, tak jdem na další z možných tahů... * Tyto Ify */ int hodnota = -MiniMax(hloubka - 1); if (hodnota >= hodnotaNejlepsihoTahu) //pokud hodnota vrácená hodnota z minimaxu je větší nebo rovna -99, tak true a uloží se do seznamu nejlepších tahů { if (hodnota > hodnotaNejlepsihoTahu) //pokud je pouze větší tj. 95 > -99 { nejlepsiTahy.Clear(); //seznam se vymaže hodnotaNejlepsihoTahu = hodnota; //a naše vrácená hodnota je nyní naše hodnotaNejlepsihoTahu } nejlepsiTahy.Add(tah.Clone() as int[]); } board.Move(tah, false, true); //tahy se provedou zpět rules.ChangePlayer(); // změní se hráč na tahu } rules.MovesGenerate(); //vygenerují se zase tahy pro hráče na tahu return(nejlepsiTahy); //náš nejlepšítah je vrácen }
/// <summary> /// Hlavní herní smyčka /// </summary> public void Game() { rules.InitBoard(); //inicializace desky ui.SelectPlayer(out player1, out player2); //výběr hráče na tahu rules.InitPlayer(); //inicializace hráče na tahu rules.MovesGenerate(); //vygenerování všech tahů pro aktuálního hráče tj. 1-bílý rules.TahuBezSkoku = 0; while (!rules.IsGameFinished()) //cyklus dokud platí že oba hráči mají figurky, jinak konec { Console.Clear(); ui.PocetKol(kolo); ui.PocetTahuBezSkoku(rules.TahuBezSkoku); ui.PrintBoard(); //Tahy počítače if (rules.PlayerOnMove() == 1 && player1 > 0) //pokud hráč na tahu je 1 a player1 > 0 tak true, provede tah a continue na dalšího hráče { ui.PcInfo(); int[] move = null; Thread pc1 = new Thread(() => move = brain.GetBestMove(player1)); pc1.IsBackground = true; pc1.Start(); ConsoleKey pressKey = ConsoleKey.A; while (pc1.IsAlive && pressKey != ConsoleKey.Escape && pressKey != ConsoleKey.Z) { if (Console.KeyAvailable) { pressKey = Console.ReadKey().Key; } } if (pressKey == ConsoleKey.Escape) { pc1.Abort(); } if (pressKey == ConsoleKey.Z) { ui.SelectPlayer(out player1, out player2); continue; } else { board.Move(move, true, false); } //pokud tah není skok tak se navýší počítadlo TahuBezSkoku if (move.Length == 8) { rules.TahuBezSkoku++; } else { rules.TahuBezSkoku = 0; } kolo++; //přičtení do počítadla kol rules.ChangePlayer(); rules.MovesGenerate(); //Thread.Sleep(1500); continue; } if (rules.PlayerOnMove() == -1 && player2 > 0) //pokud hráč na tahu je -1 a player2 > 0 tak true, provede tah a continue { ui.PcInfo(); int[] move = null; Thread pc2 = new Thread(() => move = brain.GetBestMove(player2)); pc2.IsBackground = true; pc2.Start(); ConsoleKey pressKey = ConsoleKey.A; while (pc2.IsAlive && pressKey != ConsoleKey.Escape) { if (Console.KeyAvailable) { pressKey = Console.ReadKey().Key; } } if (pressKey == ConsoleKey.Escape) { Console.Clear(); Start(); Game(); pc2.Abort(); } if (pressKey == ConsoleKey.Z) { ui.SelectPlayer(out player1, out player2); continue; } else { board.Move(move, true, false); } if (move.Length == 8) { rules.TahuBezSkoku++; } else { rules.TahuBezSkoku = 0; } rules.ChangePlayer(); rules.MovesGenerate(); //Thread.Sleep(1500); continue; } //Tahy Hráče int[] vstup = null; int[] plnyVstup = null; bool platnyVstup = false; while (!platnyVstup) //Dokud je vstup !playtnyVstup tak pokračuje { vstup = ui.InputUser(rules.PlayerOnMove()); //pokud -1 tak se podmínka neprovede protože -1 >= 0, pokud 0 tak se provede 0=0 a zkontroluje se platnost tahu //Výpis historie tahu if (vstup[0] == -4) { ui.PrintHelpMove(board.HistoryMove); } //Možnost tahu zpět if (vstup[0] == -3) { if (rules.PlayerOnMove() == -1 && board.HistoryMove.Count == 1) { Console.Clear(); ui.PocetKol(kolo); ui.PocetTahuBezSkoku(rules.TahuBezSkoku); ui.PrintBoard(); ui.Mistake(); continue; } int posledniHraceNaTahu = board.HistoryMove.Count - 2; int[] lastmove = board.HistoryMove[posledniHraceNaTahu]; board.Move(lastmove, false, true); rules.TahuBezSkoku--; rules.ChangePlayer(); ui.PrintBoard(); rules.MovesGenerate(); continue; } if (vstup[0] == -2) //Pokud hráč do konzole zadá HELP { if (vstup.Length > 1) //Pokud ještě zadá pro jakou figurku chce help { ui.PrintHelpMove(rules.GetMovesList(vstup[1], vstup[2])); //pro zadanou figurku } else //Vypíše všechny možné tahy hráče na tahu { ui.PrintHelpMove(rules.GetMovesList()); //všechny možné tahy hráče //ui.PrintHelpMove(board.HistoryMove); //všechny možné tahy hráče } } if (vstup[0] >= 0) //pokud je zadán správný pohyb tj A2-B3 { plnyVstup = rules.FullMove(vstup); //převedení na kompletní pohyb který se skládá ze 4 souřadnic X,Y, stav před, stav po platnyVstup = plnyVstup[0] != -1; //ověření zda je táhnuto dle pravidel, typ bool ve while cyklu if (!platnyVstup) //pokud není vypíše uživately chybu { ui.Mistake(); //chyba } } //Zpět do menu if (vstup[0] == -5) { Console.Clear(); Start(); Game(); } } board.Move(plnyVstup, true, false); //pokud je zadáno správně, metoda nastaví pohyb na desce //počítání kol if (player1 > 0) { kolo = 0; } kolo++; if (plnyVstup.Length == 8) { rules.TahuBezSkoku++; } else { rules.TahuBezSkoku = 0; } if (rules.ListMove.Count == 0) //pokud je ListMove prázdnej tak se změní hráč na tahu a vygenerují se pro něj nové možné tahy { rules.ChangePlayer(); rules.MovesGenerate(); } else //pokud v listu stále je možnost, tak pokračuje hráč, vícenásobné skoky { continue; } } ui.PrintBoard(); ui.Finished(); }