예제 #1
0
        /// <summary>
        /// Does a random move
        /// </summary>
        /// <param name="currentBoard">Board to calculate random move</param>
        /// <returns>Random move</returns>
        public Board NextMove(Board currentBoard)
        {
            // Generate moves
            List<Board> nextMoves = currentBoard.GenerateMoves(Game.Instance.GetTurn());

            // create random and get random number
            System.Random random = new System.Random();
            int move = random.Next(0, nextMoves.Count);

            // return move
            if (nextMoves.Count > 0)
                return nextMoves[move];
            else
                throw new Exception();
            return currentBoard;
        }
예제 #2
0
        /// <summary>
        /// Does the next move
        /// </summary>
        /// <param name="currentBoard">Board to calculate best move</param>
        /// <returns>Best boardsituation</returns>
        public Board NextMove(Board currentBoard)
        {
            Board evaluationBoard = new Board();
            bool evaluationBoardSet = false;
            int valuelast = Int32.MinValue;
            List<Board> sameHighest = new List<Board>();
            List<Board> moves = currentBoard.GenerateMoves(Game.Instance.GetTurn());
            foreach (Board board in moves)
            {
                int value = 0;

                if(board.IsTileMoved)
                    value = MiniMaxFunction(board, plieDepth, Game.Instance.GetTurn(), Game.Instance.GetTurn());
                else
                    value = MiniMaxFunction(board, plieDepth, Game.Instance.GetTurn(), !Game.Instance.GetTurn());

                if (value > valuelast || !evaluationBoardSet)
                {
                    sameHighest = new List<Board>();
                    sameHighest.Add(board);
                    evaluationBoard = board;
                    valuelast = value;
                    evaluationBoardSet = true;
                }
                else if (value == valuelast)
                {
                    sameHighest.Add(board);
                }
            }

            if (sameHighest.Count > 1 && sameHighest.Contains(evaluationBoard))
            {
                System.Random random = new System.Random();
                evaluationBoard = sameHighest[random.Next(0, sameHighest.Count - 1)];
                while (evaluationBoard.IsTileMoved)
                    evaluationBoard = sameHighest[random.Next(0, sameHighest.Count - 1)];
            }
            if (IsEqual(evaluationBoard, currentBoard))
                throw new Exception();
            //Logger.AddLine("MiniMax: boards with same value: " + sameHighest.Count + " of " + moves.Count + " moves");
            Logger.AddLine("Board -> Evaluation value: " + evaluationBoard.Evaluation(Game.Instance.GetTurn(), Game.Instance.GetTurn()));
            return evaluationBoard;
        }
        /// <summary>
        /// Evaluates the board
        /// </summary>
        /// <param name="board">Provided board</param>
        /// <param name="isRed">Is player red's turn</param>
        /// <returns></returns>
        public static int Evaluate(Board board, bool isRed)
        {
            // evaluation value
            int lEvaluationValue = 0;

            // starttime
            DateTime lStartTime = DateTime.Now;

            // if won, we don't have to do things
            if (board.IsWon())
                lEvaluationValue = 1000000;
            else
            {
                if (board.IsTileMoved)
                {
                    List<Board> nextMoves = board.GenerateMoves(isRed);
                    if (nextMoves.Count == 1)
                    {
                        return nextMoves[0].Evaluation(isRed, isRed);
                    }
                }

                // temp values
                int lEmptySpots = 0;
                int lOwnHead = 0;

                // temp value for storing the to be checked head position
                BoardPosition lHead = BoardPosition.RedHead;
                if (!isRed)
                    lHead = BoardPosition.WhiteHead;

                // loop trough board
                for (int x = 0; x < 21; x++)
                {
                    for (int y = 0; y < 20; y++)
                    {
                        //if (boardPositions[x, y] == lHead)
                        //    lOwnHead++;

                        #region "Check if piece belongs to current player"

                        bool lCheck = false;

                        if (board.BoardSituation[x, y] != BoardPosition.Empty && board.BoardSituation[x, y] != BoardPosition.Tile)
                        {
                            if (isRed)
                            {
                                if (board.BoardSituation[x, y] == BoardPosition.RedHead || board.BoardSituation[x, y] == BoardPosition.RedTail)
                                    lCheck = true;
                            }
                            else if (!isRed)
                            {
                                if (board.BoardSituation[x, y] == BoardPosition.WhiteHead || board.BoardSituation[x, y] == BoardPosition.WhiteTail)
                                    lCheck = true;
                            }
                        }

                        #endregion

                        if (lCheck)
                        {
                            #region "Left Column"

                            // x - -
                            // x - -
                            // x - -
                            if (x > 0)
                            {
                                // x - -
                                // - - -
                                // - - -
                                if (y > 0)
                                {
                                    if (board.BoardSituation[x - 1, y - 1] == BoardPosition.Tile)
                                        lEmptySpots++;
                                    else if (board.BoardSituation[x - 1, y - 1] == lHead)
                                        lOwnHead++;
                                }

                                // - - -
                                // x - -
                                // - - -
                                if (board.BoardSituation[x - 1, y] == BoardPosition.Tile)
                                    lEmptySpots++;
                                else if (board.BoardSituation[x - 1, y] == lHead)
                                    lOwnHead++;

                                // - - -
                                // - - -
                                // x - -
                                if (y < (20 - 1))
                                {
                                    if (board.BoardSituation[x - 1, y + 1] == BoardPosition.Tile)
                                        lEmptySpots++;
                                    else if (board.BoardSituation[x - 1, y + 1] == lHead)
                                        lOwnHead++;
                                }
                            }

                            #endregion

                            #region "Middle column"

                            // - x -
                            // - x -
                            // - x -

                            // - x -
                            // - - -
                            // - - -
                            if (y > 0)
                            {
                                if (board.BoardSituation[x, y - 1] == BoardPosition.Tile)
                                    lEmptySpots++;
                                else if (board.BoardSituation[x, y - 1] == lHead)
                                    lOwnHead++;
                            }

                            // - - -
                            // - x -
                            // - - -
                            // needs no check, is this position

                            // - - -
                            // - - -
                            // - x -
                            if (y < (20 - 1))
                            {
                                if (board.BoardSituation[x, y + 1] == BoardPosition.Tile)
                                    lEmptySpots++;
                                else if (board.BoardSituation[x, y + 1] == lHead)
                                    lOwnHead++;
                            }

                            #endregion

                            #region "Right column"

                            // - - x
                            // - - x
                            // - - x
                            if (x < (21 - 1))
                            {
                                // - - x
                                // - - -
                                // - - -
                                if (y > 0)
                                {
                                    if (board.BoardSituation[x + 1, y - 1] == BoardPosition.Tile)
                                        lEmptySpots++;
                                    else if (board.BoardSituation[x + 1, y - 1] == lHead)
                                        lOwnHead++;
                                }

                                // - - -
                                // - - x
                                // - - -
                                if (board.BoardSituation[x + 1, y] == BoardPosition.Tile)
                                    lEmptySpots++;
                                else if (board.BoardSituation[x + 1, y] == lHead)
                                    lOwnHead++;

                                // - - -
                                // - - -
                                // - - x
                                if (y < (20 - 1))
                                {
                                    if (board.BoardSituation[x + 1, y + 1] == BoardPosition.Tile)
                                        lEmptySpots++;
                                    else if (board.BoardSituation[x + 1, y + 1] == lHead)
                                        lOwnHead++;
                                }
                            }

                            #endregion
                        }
                    }
                }

                // calculate evalution value
                int evalAdd = 0;
                if (Game.Instance.CurrentPlayerNumPieces() > 0)
                {
                    //evalAdd = (lEmptySpots * (lOwnHead / Game.Instance.CurrentPlayerNumPieces()));
                    evalAdd = lEmptySpots * (lOwnHead ^ 2);
                }

                lEvaluationValue = lEmptySpots + evalAdd;
            }

            #region "debug"
            //DateTime lStopTime = DateTime.Now;
            //TimeSpan lDiff = lStopTime - lStartTime;

            //Logger.AddLine("Board -> Evaluation value: " + lEvaluationValue + " (calculated in: " + lDiff.TotalMilliseconds + " ms)");
            #endregion

            return lEvaluationValue;
        }
예제 #4
0
        /// <summary>
        /// Does the next move
        /// </summary>
        /// <param name="currentBoard">Board to calculate best move</param>
        /// <returns>Best boardsituation</returns>
        public Board NextMove(Board currentBoard)
        {
            Board evaluationBoard = new Board();
            bool evaluationBoardSet = false;
            evaluationBoard.BoardSituation[0, 0] = BoardPosition.RedTail;
            int valuelast = Int32.MinValue;
            List<Board> sameHighest = new List<Board>();
            int alpha = Int32.MinValue + 10;
            int beta = Int32.MaxValue;
            List<Board> moves = currentBoard.GenerateMoves(Game.Instance.GetTurn());
            foreach (Board board in moves)
            {
                if (board.IsTileMoved)
                    alpha = AlphaBetaFunction(board, plieDepth, Game.Instance.GetTurn(), Game.Instance.GetTurn(), alpha, beta);
                else
                    alpha = AlphaBetaFunction(board, plieDepth, Game.Instance.GetTurn(), !Game.Instance.GetTurn(), alpha, beta);

                if (alpha > valuelast || !evaluationBoardSet)
                {
                    sameHighest = new List<Board>();
                    sameHighest.Add(board);
                    evaluationBoard = board;
                    valuelast = alpha;
                    evaluationBoardSet = true;
                }
                else if (alpha == valuelast)
                {
                    sameHighest.Add(board);
                }
            }

            if (sameHighest.Count > 1 && sameHighest.Contains(evaluationBoard))
            {
                int highest = Int32.MinValue;
                List<Board> highestOfTheHighest = new List<Board>();
                foreach (Board board in sameHighest)
                {
                    int eval = Int32.MinValue;
                    if(board.IsTileMoved)
                        eval = board.Evaluation(Game.Instance.GetTurn(), Game.Instance.GetTurn());
                    else
                        eval = board.Evaluation(Game.Instance.GetTurn(), !Game.Instance.GetTurn());
                    if (eval > highest)
                    {
                        highest = eval;
                        highestOfTheHighest = new List<Board>();
                        highestOfTheHighest.Add(board);
                    }
                    else if (eval == highest)
                        highestOfTheHighest.Add(board);
                }
                System.Random random = new System.Random();
                evaluationBoard = highestOfTheHighest[random.Next(0, highestOfTheHighest.Count - 1)];
            }
            if (IsEqual(evaluationBoard, currentBoard))
                throw new Exception();

            Logger.AddLine("AB: boards with same value: " + sameHighest.Count + " of " + moves.Count + " moves");
            Logger.AddLine("Board -> Evaluation value: " + evaluationBoard.Evaluation(Game.Instance.GetTurn(), Game.Instance.GetTurn()));
            return evaluationBoard;
        }
예제 #5
0
        private int AlphaBetaFunction(Board node, int depth, bool isPlayerAMax, bool turnPlayerA, int alphaEval, int betaEval)
        {
            if (node.IsWon() || depth <= 0)
            {
                return node.Evaluation(isPlayerAMax, turnPlayerA);
            }
            if (this.transtable)
            {
                if (table.IsCalculatedBefore(node, depth, isPlayerAMax, turnPlayerA))
                    return table.GetCalculatedValue(node, depth, isPlayerAMax, turnPlayerA);
            }

            int value = Int32.MinValue;

            List<Board> possibleMoves = node.GenerateMoves(turnPlayerA);

            turnPlayerA = !turnPlayerA;

            if (isPlayerAMax == turnPlayerA)
                possibleMoves = Order(possibleMoves, true, true);
            else
                possibleMoves = Order(possibleMoves, false, false);

            foreach (Board board in possibleMoves)
            {
                if (turnPlayerA == isPlayerAMax)
                {

                    if(board.IsTileMoved)
                        value = Math.Max(value, AlphaBetaFunction(board, depth - 1, isPlayerAMax, !turnPlayerA, alphaEval, betaEval));
                    else
                        value = Math.Max(value, AlphaBetaFunction(board, depth - 1, isPlayerAMax, turnPlayerA, alphaEval, betaEval));

                    alphaEval = Math.Max(value, alphaEval);
                    if (betaEval <= alphaEval)
                    {
                        if (this.transtable)
                            table.InsertCalculatedValue(node, depth, isPlayerAMax, !turnPlayerA, alphaEval);
                        return alphaEval;
                    }
                }
                else
                {

                    if(board.IsTileMoved)
                        value = Math.Max(value, -AlphaBetaFunction(board, depth - 1, isPlayerAMax, !turnPlayerA, alphaEval, betaEval));
                    else
                        value = Math.Max(value, -AlphaBetaFunction(board, depth - 1, isPlayerAMax, turnPlayerA, alphaEval, betaEval));

                    betaEval = Math.Min(value, betaEval);
                    if (betaEval <= alphaEval)
                    {
                        if (this.transtable)
                            table.InsertCalculatedValue(node, depth, isPlayerAMax, !turnPlayerA, betaEval);
                        return betaEval;
                    }
                }
            }

            if (this.transtable)
                table.InsertCalculatedValue(node, depth, isPlayerAMax, !turnPlayerA, value);

            return value;
        }
예제 #6
0
        private int MiniMaxFunction(Board node, int depth, bool isPlayerAMax, bool turnPlayerA)
        {
            if (depth <= 0 || node.IsWon())
            {
                return node.Evaluation(isPlayerAMax, turnPlayerA);
            }
            if (this.transtable)
            {
                if(table.IsCalculatedBefore(node, depth, isPlayerAMax, turnPlayerA))
                    return table.GetCalculatedValue(node, depth, isPlayerAMax, turnPlayerA);
            }

            int alpha = Int32.MinValue;

            List<Board> possibleMoves = node.GenerateMoves(turnPlayerA);

            turnPlayerA = !turnPlayerA;

            if (possibleMoves.Count == 0)
                throw new Exception();

            foreach (Board board in possibleMoves)
            {

                if (turnPlayerA == isPlayerAMax)
                {
                    if(board.IsTileMoved)
                        alpha = Math.Max(alpha, MiniMaxFunction(board, depth - 1, isPlayerAMax, !turnPlayerA));
                    else
                        alpha = Math.Max(alpha, MiniMaxFunction(board, depth - 1, isPlayerAMax, turnPlayerA));
                }
                else
                {
                    if(board.IsTileMoved)
                        alpha = Math.Max(alpha, -MiniMaxFunction(board, depth - 1, isPlayerAMax, !turnPlayerA));
                    else
                        alpha = Math.Max(alpha, -MiniMaxFunction(board, depth - 1, isPlayerAMax, turnPlayerA));
                }
            }
            if(this.transtable)
            {
                table.InsertCalculatedValue(node, depth, isPlayerAMax, !turnPlayerA, alpha);
            }

            return alpha;
        }
예제 #7
0
        /// <summary>
        /// Evaluates the board
        /// </summary>
        /// <param name="board">Provided board</param>
        /// <param name="isRed">Is player red's turn</param>
        /// <returns></returns>
        public static int Evaluate(Board board, bool isPlayerAMax, bool turnPlayerA)
        {
            // evaluation value
            int lEvaluationValue = 0;

            // starttime
            DateTime lStartTime = DateTime.Now;

            // if won, we don't have to do things
            if (board.IsWon())
                if (isPlayerAMax == turnPlayerA)
                    lEvaluationValue = -140;
                else
                    lEvaluationValue = 140;
            else
            {
                // check if tile moved, if so, return evaluation value of next board of tile moved
                if (board.IsTileMoved)
                {
                    List<Board> nextMoves = board.GenerateMoves(turnPlayerA);
                    if (nextMoves.Count > 0)
                    {
                        return nextMoves[0].Evaluation(isPlayerAMax, !turnPlayerA);
                    }
                }
                else
                {
                    // tiles not moves, so we can continue here
                    List<PieceSituation> goodSituations = FindSituations(board.BoardSituation, turnPlayerA);
                    List<PieceSituation> badSituations = FindSituations(board.BoardSituation, !turnPlayerA);

                    if (goodSituations.Count > 0)
                    {
                        IOrderedEnumerable<PieceSituation> orderedGood = from e in goodSituations orderby e select e;
                        if (orderedGood.First() == PieceSituation.ThreeHeads)
                            lEvaluationValue = 100;
                        else if (orderedGood.First() == PieceSituation.ThreeHeadsWithSpace)
                            lEvaluationValue = 60;
                        else if (orderedGood.First() == PieceSituation.ThreeHeadsBlocked)
                            lEvaluationValue = 20;
                    }
                    else if (badSituations.Count > 0)
                    {
                        IOrderedEnumerable<PieceSituation> orderedBad = from e in badSituations orderby e select e;
                        if (orderedBad.First() == PieceSituation.ThreeHeads)
                            lEvaluationValue = -100;
                        else if (orderedBad.First() == PieceSituation.ThreeHeadsWithSpace)
                            lEvaluationValue = -60;
                        else if (orderedBad.First() == PieceSituation.ThreeHeadsBlocked)
                            lEvaluationValue = -20;
                    }
                }
            }

            // add amount of head times 5 to eval value
            int addToEval = 0;

            if (turnPlayerA)
                addToEval += 5 * board.RedHeads;
            else
                addToEval += 5 * board.WhiteHeads;

            return (lEvaluationValue + addToEval);
        }