Пример #1
0
        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);
                }
            }
        }
Пример #2
0
        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
            });
        }
    }
}
Пример #4
0
        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
            });
        }
Пример #7
0
        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);
            }
        }
Пример #8
0
        //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
            });
        }
    }
Пример #9
0
        //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
            });
        }
Пример #10
0
        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
            });
        }
Пример #11
0
        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
            });
        }
Пример #12
0
        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
            });
        }
Пример #13
0
        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
            });
        }
Пример #14
0
        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
                });
            }
        }
    }
Пример #15
0
        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
                });
            }
        }
Пример #16
0
        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);
        }