/// <summary> /// Executed when it is the AI's turn if the AI is being used. /// </summary> IEnumerator AITurn() { MinimaxPair <Player[], double> moveToMake = Minimax(playerMap, difficulty, true); Player[] nextBoard = moveToMake.bestMove; int movePos = GetNextMove(playerMap, nextBoard); MakeMove(playerMap, ai, movePos); SetPly(human); while (ply == ai) { yield return(null); } // COMMENT EVERYTHING ABOVE FOR A HUMAN VS. HUMAN GAME // COMMENT EVERYTHING BELOW FOR A HUMAN VS. AI GAME //if (Input.GetMouseButtonUp(0)) //{ // int clickedSquare = GetClickedSquare(); // List<int> legalMoves = GetLegalMoves(playerMap, ai); // if (clickedSquare > -1 && legalMoves.Contains(clickedSquare)) // { // MakeMove(playerMap, ply, clickedSquare); // SetPly(human); // } //} //while (ply == ai) yield return null; }
/// <summary> /// Minimax algorithm for the AI. /// </summary> /// <param name="boardMap">A 64-indexed list of Players representing a board, where each square is a player.</param> /// <param name="depth">The number of moves the AI will look ahead.</param> /// <param name="maximizingPlayer">True if calculating own score, false if calculating opposing player's score.</param> /// <returns>A MinimaxPair object containing the best board and its score</returns> MinimaxPair <Player[], double> Minimax(Player[] boardMap, int depth, bool maximizingPlayer) { Player[] gameTreeMap = CopyPlayerMap(boardMap); List <int> legalMoves; if (maximizingPlayer) { legalMoves = GetLegalMoves(gameTreeMap, ai); } else { legalMoves = GetLegalMoves(gameTreeMap, human); } if (legalMoves.Count == 0 || depth == 0) { return(new MinimaxPair <Player[], double>(gameTreeMap, Evaluate(gameTreeMap))); } MinimaxPair <Player[], double> bestBoard = new MinimaxPair <Player[], double>(); if (maximizingPlayer) { bestBoard.bestScore = Mathf.NegativeInfinity; foreach (int legalMove in legalMoves) { MakeMove(gameTreeMap, ply, legalMove); Player[] newGameTreeMap = CopyPlayerMap(gameTreeMap); MinimaxPair <Player[], double> nextMove = Minimax(newGameTreeMap, depth - 1, false); if (nextMove.bestScore > bestBoard.bestScore) { bestBoard.bestMove = nextMove.bestMove; bestBoard.bestScore = nextMove.bestScore; } } return(bestBoard); } else { bestBoard.bestScore = Mathf.Infinity; foreach (int legalMove in legalMoves) { MakeMove(gameTreeMap, ply, legalMove); Player[] newGameTreeMap = CopyPlayerMap(gameTreeMap); MinimaxPair <Player[], double> nextMove = Minimax(newGameTreeMap, depth - 1, true); if (nextMove.bestScore < bestBoard.bestScore) { bestBoard.bestMove = nextMove.bestMove; bestBoard.bestScore = nextMove.bestScore; } } return(bestBoard); } }