static void Main(string[] args) { IGameBoard board = ...; IConsoleView view = ...; //Game Loop while (!board.IsFinished) { //Print Board Console.WriteLine(view.BoardToString(board)); //Print Possible Moves Console.WriteLine("Possible moves:"); IEnumerable <IGameMove> possibleMoves = board.GetPossibleMoves(); Console.WriteLine(string.Join(",", possibleMoves.Select(view.MoveToString))); //Print the current player and input their move. Console.WriteLine("It is {0}’s turn.", view.PlayerToString(board.CurrentPlayer)); Console.WriteLine("Enter a move: "); string input = Console.ReadLine(); // Parse move and check if it's possible/valid IGameMove toApply = view.ParseMove(input); IGameMove foundMove = possibleMoves.FirstOrDefault(toApply.Equals); if (foundMove == null) { Console.WriteLine("Sorry, that move is invalid."); } else { board.ApplyMove(foundMove); } } }
private static MinimaxBestMove FindBestMove(IGameBoard b, long alpha, long beta, int depthLeft) { if (depthLeft == 0 || b.IsFinished) { return(new MinimaxBestMove() { Weight = b.BoardWeight, Move = null }); } bool isMaximizing; long bestWeight; if (b.CurrentPlayer == 2) { isMaximizing = false; bestWeight = beta; } else { isMaximizing = true; bestWeight = alpha; } IGameMove bestMove = null; var possible_moves = b.GetPossibleMoves(); foreach (var move in possible_moves) { b.ApplyMove(move); var w = FindBestMove(b, alpha, beta, depthLeft - 1).Weight; b.UndoLastMove(); if (isMaximizing == true && w > bestWeight) { bestWeight = w; bestMove = move; //want the maximum alpha = Math.Max(alpha, w); } else if (isMaximizing == false && w < bestWeight) { bestWeight = w; bestMove = move; //want the minimumz beta = Math.Min(beta, w); } if (alpha >= beta) { break; } } return(new MinimaxBestMove() { Weight = bestWeight, Move = bestMove }); }
private static MinimaxBestMove FindBestMove(IGameBoard board, long alpha, long beta, int depthLeft, bool isMaximizing) { if (depthLeft == 0 || board.IsFinished) { return new MinimaxBestMove() { Weight = board.BoardWeight, Move = null } } ; IGameMove bestMove = null; foreach (var move in board.GetPossibleMoves()) { board.ApplyMove(move); var w = FindBestMove(board, alpha, beta, depthLeft - 1, !isMaximizing); board.UndoLastMove(); if (isMaximizing && w.Weight > alpha) { bestMove = move; alpha = w.Weight; if (beta <= alpha) { return new MinimaxBestMove() { Weight = beta, Move = bestMove } } ; } else if (!isMaximizing && w.Weight < beta) { bestMove = move; beta = w.Weight; if (beta <= alpha) { return new MinimaxBestMove() { Weight = alpha, Move = bestMove } } ; } } return(new MinimaxBestMove() { Weight = isMaximizing ? alpha : beta, Move = bestMove }); } } }
private static MinimaxBestMove FindBestMove(IGameBoard b, int depthLeft, bool maximize, int alpha, int beta) { // Implement the minimax algorithm. // Your first attempt will not use alpha-beta pruning. Once that works, // implement the pruning as discussed in the project notes. if (depthLeft == 0 || b.IsFinished) { return(new MinimaxBestMove { Weight = b.Weight, Move = null }); } int bestWeight = maximize ? Int32.MinValue : Int32.MaxValue; IGameMove bestMove = null; foreach (var move in b.GetPossibleMoves()) { b.ApplyMove(move); int weight = FindBestMove(b, depthLeft - 1, !maximize, alpha, beta).Weight; b.UndoLastMove(); if (maximize && weight > alpha) { alpha = weight; } else if (!maximize && weight < beta) { beta = weight; } if (!(alpha < beta)) { return(new MinimaxBestMove { Weight = maximize ? beta : alpha, Move = bestMove }); } if (maximize && weight > bestWeight) { bestWeight = weight; bestMove = move; } else if (!maximize && weight < bestWeight) { bestWeight = weight; bestMove = move; } } return(new MinimaxBestMove { Weight = bestWeight, Move = bestMove }); }
private static MinimaxBestMove FindBestMove(IGameBoard b, long alpha, long beta, int depthLeft, bool isMaximizing) { //long bestWeight; if (depthLeft == 0 || b.IsFinished) { return new MinimaxBestMove { Weight = b.BoardWeight, Move = null } } ; //bestWeight = (b.CurrentPlayer == 1) ? long.MinValue : long.MaxValue; IGameMove bestMove = null; var possibleMoves = b.GetPossibleMoves(); foreach (IGameMove m in possibleMoves) { b.ApplyMove(m); long weight = (FindBestMove(b, alpha, beta, depthLeft - 1, !isMaximizing)).Weight; b.UndoLastMove(); if (isMaximizing && weight > alpha) { alpha = weight; bestMove = m; } else if (!isMaximizing && weight < beta) { beta = weight; bestMove = m; } if (alpha >= beta) { return(new MinimaxBestMove { Weight = (isMaximizing) ? beta : alpha, Move = bestMove }); } } return(new MinimaxBestMove { Weight = (isMaximizing) ? alpha : beta, Move = bestMove }); } }
private static MinimaxBestMove FindBestMove(IGameBoard b, long alpha, long beta, long depthLeft) { if (depthLeft == 0 || b.IsFinished) { return(new MinimaxBestMove { Move = null, Weight = b.BoardWeight }); } var iAlpha = alpha; var iBeta = beta; bool isMaximizing = b.CurrentPlayer == 1; IGameMove bestMove = null; foreach (var move in b.GetPossibleMoves()) { if (!(iAlpha < iBeta)) { return(new MinimaxBestMove { Weight = isMaximizing ? iBeta : iAlpha, Move = bestMove }); } b.ApplyMove(move); var w = FindBestMove(b, iAlpha, iBeta, depthLeft - 1).Weight; b.UndoLastMove(); if (isMaximizing) { if (w > iAlpha) { iAlpha = w; bestMove = move; } } else { if (w < iBeta) { iBeta = w; bestMove = move; } } } return(new MinimaxBestMove { Weight = isMaximizing ? iAlpha : iBeta, Move = bestMove }); }
private static MinimaxBestMove FindBestMove(IGameBoard b, long alpha, long beta, int depthLeft) { if (depthLeft == 0 || b.IsFinished == true) { return(new MinimaxBestMove() { Weight = b.BoardWeight, Move = null }); } else { MinimaxBestMove move = new MinimaxBestMove(); move.Move = null; if (b.CurrentPlayer == 1) { move.Weight = long.MinValue; } else if (b.CurrentPlayer == 2) { move.Weight = long.MaxValue; } foreach (var m in b.GetPossibleMoves()) { b.ApplyMove(m); long w = FindBestMove(b, alpha, beta, depthLeft - 1).Weight; b.UndoLastMove(); if ((b.CurrentPlayer == 1) && w > alpha) { move.Weight = w; move.Move = m; alpha = w; } else if ((b.CurrentPlayer == 2) && w < beta) { move.Weight = w; move.Move = m; beta = w; } if (!(alpha < beta)) { return(move); } } return(move); } }
//private static MinimaxBestMove FindBestMove(IGameBoard b, int alpha, int beta, int depthLeft, bool maximize) { //private static Tuple<long, IGameMove> FindBestMove(IGameBoard board, int depth, bool isMaximizing, int alpha, int beta) // alpha = MAXIMUM Lower bound of possible solutions // beta = MINIMUM upper bound of possible solutions //private static MinimaxBestMove FindBestMove(IGameBoard board, int depth, bool isMaximizing, int alpha, int beta) //{ // if (depth == 0 | board.IsFinished) // return new MinimaxBestMove { // Weight = (int)board.BoardWeight, // Move = null // }; // long bestWeight = (isMaximizing) ? Int64.MinValue : Int64.MaxValue; // IGameMove bestMove = null; // foreach (var possibleMove in board.GetPossibleMoves()) { // board.ApplyMove(possibleMove); // var nextBestMove = FindBestMove(board, depth - 1, !isMaximizing, alpha, beta); // board.UndoLastMove(); // // If maximizing the AI's own advantage // if (isMaximizing) { // // if found the nextMove's weight to be higher than the last found (beta) // // replace it with that. // if (nextBestMove.Weight >= beta) { // bestWeight = nextBestMove.Weight; // bestMove = possibleMove; // } // // if the weight is less than alpha, keep searching // if (nextBestMove.Weight <= alpha) continue; // bestMove = possibleMove; // alpha = nextBestMove.Weight; // } // else { // Minimizing the enemy "human"'s advantage // // if human player's weight for that square is less than or equal to // // "alpha" or a calculated/pulled weight or the lowest advantage possible // if (nextBestMove.Weight <= alpha) { // // return that value. // bestWeight = nextBestMove.Weight; // bestMove = possibleMove; // } // // else keep going down the tree // if (nextBestMove.Weight >= beta) continue; // bestMove = possibleMove; // beta = nextBestMove.Weight; // } // } // // when done, this is the result. // return new MinimaxBestMove { // Weight = (int)bestWeight, // Move = bestMove // }; //} // -- Old AI, non alpha/beta -- // private static MinimaxBestMove FindBestMove(IGameBoard board, int depth, bool isMaximizing, int alpha, int beta) { // if (depth == 0 || board.IsFinished) // return new MinimaxBestMove { // Weight = board.BoardWeight, // Move = null // }; // long bestWeight = (isMaximizing) ? Int64.MinValue : Int64.MaxValue; // IGameMove bestMove = null; // foreach (IGameMove possMove in board.GetPossibleMoves()) { // board.ApplyMove(possMove); // MinimaxBestMove w = FindBestMove(board, depth - 1, !isMaximizing, alpha, beta); // board.UndoLastMove(); // // if maximized and weight is greater than best weight // // or not maximized and weight is less than best weight // if (isMaximizing && w.Weight > bestWeight || !isMaximizing && w.Weight < bestWeight) { // bestWeight = w.Weight; // bestMove = possMove; // } // } // return new MinimaxBestMove { // Weight = bestWeight, // Move = bestMove // }; // } private static MinimaxBestMove FindBestMove(IGameBoard board, int depth, bool isMaximizing, long alpha, long beta) { if (depth == 0 || board.IsFinished) { return new MinimaxBestMove { Weight = board.BoardWeight, Move = null } } ; long bestWeight = (isMaximizing) ? Int64.MinValue : Int64.MaxValue; IGameMove bestMove = null; foreach (var move in board.GetPossibleMoves()) { board.ApplyMove(move); var w = FindBestMove(board, depth - 1, !isMaximizing, alpha, beta); board.UndoLastMove(); if (isMaximizing && w.Weight > alpha) { alpha = w.Weight; bestMove = move; } else if (!isMaximizing && w.Weight < beta) { beta = w.Weight; bestMove = move; } if (alpha >= beta) { long opponentsWeight = (isMaximizing) ? beta : alpha; return(new MinimaxBestMove() { Move = move, Weight = opponentsWeight }); } } long myWeight = (isMaximizing) ? alpha : beta; return(new MinimaxBestMove() { Move = bestMove, Weight = myWeight }); } }
//private static MinimaxBestMove FindBestMove(IGameBoard b, int depthLeft, bool maximize) { private static MinimaxBestMove FindBestMove(IGameBoard b, int depthLeft, bool maximize, int alpha, int beta) { // Implement the minimax algorithm. // Your first attempt will not use alpha-beta pruning. Once that works, // implement the pruning as discussed in the project notes. // maximize = player 1 // !maximize = player 2 if (depthLeft == 0 || b.IsFinished) { return(new MinimaxBestMove() { Weight = b.Weight, Move = null }); } //int bestWeight = maximize ? int.MinValue : int.MaxValue; IGameMove bestMove = null; foreach (var m in b.GetPossibleMoves()) { b.ApplyMove(m); MinimaxBestMove w = FindBestMove(b, depthLeft - 1, !maximize, alpha, beta); b.UndoLastMove(); if (maximize && w.Weight > alpha) { alpha = w.Weight; bestMove = m; } else if (!maximize && w.Weight < beta) { beta = w.Weight; bestMove = m; } if (alpha >= beta) { break; } } return(new MinimaxBestMove() { Weight = maximize ? alpha : beta, Move = bestMove }); }
private static MinimaxBestMove FindBestMove(IGameBoard b, long alpha, long beta, int depthLeft) { if (depthLeft == 0 || b.IsFinished) { return(new MinimaxBestMove() { Move = null, Weight = b.BoardWeight }); } bool isMaximizing = (b.CurrentPlayer == 1) ? true : false; //long bestWeight = (isMaximizing) ? long.MinValue : long.MaxValue; IGameMove bestMove = null; foreach (var move in b.GetPossibleMoves()) { b.ApplyMove(move); var w = FindBestMove(b, alpha, beta, depthLeft - 1); b.UndoLastMove(); if (isMaximizing && w.Weight > alpha) { alpha = w.Weight; bestMove = move; } else if (!isMaximizing && w.Weight < beta) { beta = w.Weight; bestMove = move; } if (alpha >= beta) { long opponentsWeight = (isMaximizing) ? beta : alpha; return(new MinimaxBestMove() { Move = move, Weight = opponentsWeight }); } } long myWeight = (isMaximizing) ? alpha : beta; return(new MinimaxBestMove() { Move = bestMove, Weight = myWeight }); }
private static MinimaxBestMove FindBestMove(IGameBoard b, long alpha, long beta, int depth, bool isMaximizing) { if (depth == 0 || b.IsFinished) { return(new MinimaxBestMove { Weight = b.BoardWeight, Move = null }); } long bestWeight = isMaximizing ? alpha : beta; IGameMove bestMove = null; foreach (IGameMove possibleMove in b.GetPossibleMoves()) { b.ApplyMove(possibleMove); long w = FindBestMove(b, alpha, beta, depth - 1, !isMaximizing).Weight; b.UndoLastMove(); if (isMaximizing && w > alpha) { alpha = Math.Max(alpha, w); bestWeight = w; bestMove = possibleMove; } else if (!isMaximizing && w < beta) { beta = Math.Min(beta, w); bestWeight = w; bestMove = possibleMove; } if (alpha >= beta) { return(new MinimaxBestMove { Weight = bestWeight, Move = bestMove }); } } return(new MinimaxBestMove { Weight = bestWeight, Move = bestMove }); }
private static MinimaxBestMove FindBestMove(IGameBoard b, long alpha, long beta, int depthLeft, bool isMaximizing) { if (depthLeft == 0 || b.IsFinished) { return(new MinimaxBestMove { Weight = b.BoardWeight, Move = null }); } IGameMove bestMove = null; var possMoves = b.GetPossibleMoves(); foreach (IGameMove move in possMoves) { b.ApplyMove(move); long w = FindBestMove(b, alpha, beta, depthLeft - 1, !isMaximizing).Weight; b.UndoLastMove(); if (isMaximizing && w > alpha) { alpha = w; bestMove = move; } else if (!isMaximizing && w < beta) { beta = w; bestMove = move; } if (alpha >= beta) { return(new MinimaxBestMove { Weight = (isMaximizing) ? beta : alpha, Move = bestMove }); } } return(new MinimaxBestMove { Weight = (isMaximizing) ? alpha : beta, Move = bestMove }); }
private static MinimaxBestMove FindBestMove(IGameBoard b, int depthLeft, bool maximize, int alpha, int beta) { // Implement the minimax algorithm. // Your first attempt will not use alpha-beta pruning. Once that works, // implement the pruning as discussed in the project notes. if (depthLeft == 0 || b.IsFinished) { return(new MinimaxBestMove { Move = null, Weight = b.Weight }); } IGameMove bestMove = null; foreach (var possibleMove in b.GetPossibleMoves()) { b.ApplyMove(possibleMove); var nextBestMove = FindBestMove(b, depthLeft - 1, !maximize, alpha, beta); b.UndoLastMove(); if (maximize) { // i.e. alpha became > beta, so return this if (nextBestMove.Weight >= beta) { return(new MinimaxBestMove { Weight = beta, Move = possibleMove }); } if (nextBestMove.Weight <= alpha) { continue; } bestMove = possibleMove; alpha = nextBestMove.Weight; } else { // i.e. beta became < alpha, so return this if (nextBestMove.Weight <= alpha) { return(new MinimaxBestMove { Weight = alpha, Move = possibleMove }); } if (nextBestMove.Weight >= beta) { continue; } bestMove = possibleMove; beta = nextBestMove.Weight; } } return(new MinimaxBestMove { Move = bestMove, Weight = maximize ? alpha : beta }); }
private static MinimaxBestMove FindBestMove(IGameBoard b, int depthLeft, bool maximize, int alpha, int beta) { // Implement the minimax algorithm. // Your first attempt will not use alpha-beta pruning. Once that works, // implement the pruning as discussed in the project notes. if (depthLeft == 0 || b.IsFinished) { return new MinimaxBestMove() { Weight = b.Weight, Move = null } } ; IGameMove bestMove = null; foreach (var move in b.GetPossibleMoves()) { b.ApplyMove(move); var w = FindBestMove(b, depthLeft - 1, !maximize, alpha, beta).Weight; b.UndoLastMove(); if (b.CurrentPlayer == 1 && w > alpha) { alpha = w; bestMove = move; } else if (b.CurrentPlayer == 2 && w < beta) { beta = w; bestMove = move; } if (alpha >= beta) { if (b.CurrentPlayer == 1) { return(new MinimaxBestMove() { Weight = beta, Move = bestMove }); } else { return(new MinimaxBestMove() { Weight = alpha, Move = bestMove }); } } } if (b.CurrentPlayer == 1) { return(new MinimaxBestMove() { Weight = alpha, Move = bestMove }); } else { return(new MinimaxBestMove() { Weight = beta, Move = bestMove }); } } }
private static MinimaxBestMove FindBestMove(IGameBoard b, int depthLeft, bool isMaximizing, long alpha, long beta) { if (depthLeft == 0 || b.IsFinished) { return(new MinimaxBestMove() { Weight = b.BoardWeight, Move = null }); } //long bestWeight = isMaximizing ? long.MinValue : long.MaxValue; //long local_alpha = int.MinValue; //long local_beta = int.MaxValue; //alpha = long.MinValue; //beta = long.MaxValue; IGameMove bestMove = null; foreach (IGameMove move in b.GetPossibleMoves()) { b.ApplyMove(move); MinimaxBestMove w = FindBestMove(b, depthLeft - 1, !isMaximizing, alpha, beta); b.UndoLastMove(); if (isMaximizing && w.Weight > alpha) { //bestWeight = w.Weight; bestMove = move; alpha = w.Weight; //local_alpha = w.Weight; } else if (!isMaximizing && w.Weight < beta) { //bestWeight = w.Weight; bestMove = move; beta = w.Weight; //local_beta = w.Weight; } if (!(alpha < beta)) { if (isMaximizing) { return(new MinimaxBestMove() { Weight = beta, Move = bestMove }); } else { return(new MinimaxBestMove() { Weight = alpha, Move = bestMove }); } } } /* * return new MinimaxBestMove() * { * Weight = bestWeight, * Move = bestMove * }; */ if (isMaximizing) { return(new MinimaxBestMove() { //Weight = local_alpha, Weight = alpha, Move = bestMove }); } else { return(new MinimaxBestMove() { //Weight = local_beta, Weight = beta, Move = bestMove }); } }
private static MinimaxBestMove FindBestMove(IGameBoard b, int depthLeft, bool maximize, int alpha, int beta) { // Implement the minimax algorithm. // Your first attempt will not use alpha-beta pruning. Once that works, // implement the pruning as discussed in the project notes. MinimaxBestMove move = new MinimaxBestMove(); //tree empty if (depthLeft == 0 || b.IsFinished) { move = new MinimaxBestMove(); move.Weight = b.Weight; move.Move = null; return(move); } //initializaitons int bestWeight = int.MaxValue; IGameMove bestMove = null; if (maximize) { bestWeight *= -1; } var possMoves = b.GetPossibleMoves(); foreach (var possMove in possMoves) { b.ApplyMove(possMove); //return best move MinimaxBestMove w = FindBestMove(b, depthLeft - 1, !maximize, alpha, beta); b.UndoLastMove(); //update alpha if (maximize && w.Weight > alpha) { alpha = w.Weight; bestWeight = w.Weight; bestMove = possMove; //return if alpha not less than beta if (alpha >= beta) { w.Weight = beta; w.Move = bestMove; return(w); } } //update beta else if (!maximize && w.Weight < beta) { beta = w.Weight; bestWeight = w.Weight; bestMove = possMove; //return if alpha not less than beta if (alpha >= beta) { w.Weight = alpha; w.Move = bestMove; return(w); } } move.Weight = bestWeight; move.Move = bestMove; } return(move); }