public AI_MiniMax FindNextMove(int depth) //metoda wywoływana zewnętrznie, uruchamia wyszkianie następnego ruchu { AI_MiniMax ret = null; MiniMax(depth, m_TurnForPlayerX, int.MinValue + 1, int.MaxValue - 1, out ret); return(ret); }
public void ComputerMakeMove() //metoda wywoływana zewnętrznie nakazująca maszynie grającej znalezienie następnego ruchu { AI_MiniMax Current = new AI_MiniMax(app.controller.board.Board, false); //budowanie stanu maszyny na podstawie aktualnego stanu planszy AI_MiniMax next = Current.FindNextMove(depth); //szukanie najlepszego ruchu if (next != null) { ComputerClick(next.Moves); //wywołanie imitacji kliknięcia } }
public IEnumerable <AI_MiniMax> GetChildren() //pobieranie plansz dostępnych przy następnym ruchu { FindAvailableBoards(board, m_TurnForPlayerX ? 1 : 2); for (int i = 0; i < available.boards.Count; i++) { int[][] newValues = (int[][])available.boards[i].Clone(); AI_MiniMax retChild = new AI_MiniMax(newValues, !m_TurnForPlayerX); retChild.Moves = new List <int[]> (available.moves [i]); yield return(retChild); } }
//http://www.ocf.berkeley.edu/~yosenl/extras/alphabeta/alphabeta.html //metoda implementująca strategię MiniMax z AlfaBeta cięciami public int MiniMax(int depth, bool needMax, int alpha, int beta, out AI_MiniMax childWithMax) { childWithMax = null; if (depth == 0 || IsTerminalNode()) //zwrocenie wyniku przy odpowiedniej glebokosci lub w przypadku konca gry { RecursiveScore = m_Score; return(m_Score); } foreach (AI_MiniMax cur in GetChildren()) { AI_MiniMax dummy; int score = cur.MiniMax(depth - 1, !needMax, alpha, beta, out dummy); if (!needMax) { if (beta > score) { beta = score; childWithMax = cur; if (alpha >= beta) { break; } } } else { if (alpha < score) { alpha = score; childWithMax = cur; if (alpha >= beta) { break; } } } } RecursiveScore = needMax ? alpha : beta; return(RecursiveScore); }