public Move MiniMaxRoot(int depth, bool isMaximisingPlayer) { CellColor color = (CellColor)aiColor; if (!isMaximisingPlayer) { color = (CellColor)opponentColor; } List <Move> newGameMoves = grid.GetAvailableMoves(color); int bestMove = int.MinValue + 1; List <Move> bestMovesFound = new List <Move>(); // loop on all moves available on this board for (int i = 0; i < newGameMoves.Count; i++) { Move move = newGameMoves[i]; positionCount++; grid.DoMove(move); int value = -EvaluateGrid(evaluationData, depth); if (!IsGameEnded(value)) { // get loop on all moves available on board with this move value = MiniMax(depth - 1, int.MinValue + 1, int.MaxValue - 1, !isMaximisingPlayer); } grid.UndoMove(move); // is this move better if (value > bestMove) { bestMove = value; bestMovesFound.Clear(); bestMovesFound.Add(move); } else if (value == bestMove) { bestMovesFound.Add(move); } } return(bestMovesFound[Random.Range(0, bestMovesFound.Count - 1)]); }
public IEnumerator GetBestMove(OptimizedGrid optiGrid, System.Action <Move> toDo) { grid = optiGrid; positionCount = 0; timeSpent = 0; float actualTime = Time.realtimeSinceStartup; Move bestMove = new Move(); bool done = false; yield return(new WaitForEndOfFrame()); List <Vector2> canWinCells = new List <Vector2>(); // if AI has a 4-0 pattern if (grid.CanColorWin(aiColor, out canWinCells)) { // if AI can move to win if (grid.CanColorMoveToWin(aiColor, canWinCells, out bestMove)) { grid.DoMove(bestMove); if (IsScoreEnoughToWin(aiColor, canWinCells)) { done = true; } grid.UndoMove(bestMove); } } // if Player can win next turn if (grid.CanColorWin(opponentColor, out canWinCells) && IsScoreEnoughToWin(opponentColor, canWinCells) && !done) { // if player can move to win next turn if (grid.CanColorMoveToWin(opponentColor, canWinCells, out bestMove)) { grid.DoMove(bestMove); bool canPlayerWin = IsScoreEnoughToWin(opponentColor, canWinCells); grid.UndoMove(bestMove); // can AI def it ??? if (canPlayerWin && grid.CanColorMoveToWin(aiColor, canWinCells, out bestMove)) { grid.DoMove(bestMove); if (IsScoreEnoughToWin(aiColor, canWinCells)) { done = true; } grid.UndoMove(bestMove); } } } if (!done) { int depth = 3; bestMove = MiniMaxRoot(depth, true); } float newTime = Time.realtimeSinceStartup; timeSpent = newTime - actualTime; Debug.Log(positionCount + " in " + timeSpent); toDo(bestMove); }