Beispiel #1
0
 /// <summary>
 /// Executes AI move
 /// </summary>
 /// <param name="currentBoard">The current board</param>
 public void Execute(Board currentBoard)
 {
     if (algorithm != null)
     {
         Board next = algorithm.NextMove(currentBoard);
         if(IsEqual(currentBoard, next))
             throw new Exception();
         Game.Instance.SetBoard(next);
     }
 }
Beispiel #2
0
        private bool IsEqual(Board boardA, Board boardB)
        {
            for (int x = 0; x < 21; x++)
            {
                for (int y = 0; y < 20; y++)
                {
                    if (boardA.BoardSituation[x, y] != boardB.BoardSituation[x, y])
                        return false;
                }
            }

            return true;
        }
Beispiel #3
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;
        }
Beispiel #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;
            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;
        }
Beispiel #5
0
 /// <summary>
 /// 
 /// </summary>
 /// <returns></returns>
 public object Clone()
 {
     Board b = new Board((BoardPosition[,])this.BoardSituation.Clone());
     b.WhiteItems = this.WhiteItems;
     b.IsTileMoved = this.IsTileMoved;
     b.RedItems = this.RedItems;
     b.MovedTilePosition = this.movedTilePosition;
     return b;
 }
Beispiel #6
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="turnPlayerA"></param>
        /// <returns></returns>
        public List<Board> ChangeBoardPosition(bool turnPlayerA)
        {
            List<Board> boards = new List<Board>();

            BoardPosition colorHead = BoardPosition.WhiteHead;
            BoardPosition colorTail = BoardPosition.WhiteTail;

            if (turnPlayerA)
            {
                colorHead = BoardPosition.RedHead;
                colorTail = BoardPosition.RedTail;
            }

            for (int x = 0; x < 21; x++)
            {
                for (int y = 0; y < 20; y++)
                {
                    if (boardPositions[x, y] == colorHead || boardPositions[x, y] == colorTail)
                    {
                        for (int j = -1; j < 2; j++)
                        {
                            for (int i = -1; i < 2; i++)
                            {
                                if (!(i == 0 && j == 0) && (x + i >= 0 && x + i < 21) && (y + j >= 0 && y + j < 20))
                                {
                                    // Moving a piece to a empty tile next to him
                                    if (boardPositions[x + i, y + j] == BoardPosition.Tile)
                                    {
                                        if ((this.isTileMoved && (this.movedTilePosition.X == x + i && this.movedTilePosition.Y == y + j)) || !this.isTileMoved)
                                        {
                                            BoardPosition[,] newBoardPosition = (BoardPosition[,])boardPositions.Clone();

                                            newBoardPosition[x, y] = BoardPosition.Tile;
                                            newBoardPosition[x + i, y + j] = boardPositions[x, y];

                                            Board newBoard = new Board(newBoardPosition);
                                            newBoard.RedItems = this.RedItems;
                                            newBoard.WhiteItems = this.WhiteItems;
                                            newBoard.IsTileMoved = false;
                                            boards.Add(newBoard);
                                        }
                                    }
                                    // Moving a piece by jumping over a other piece next to him
                                    else if (boardPositions[x + i, y + j] != BoardPosition.Empty)
                                    {
                                        if (x + i + i >= 0 && x + i + i < 21 && y + j + j >= 0 && y + j + j < 20)
                                        {
                                            if (boardPositions[x + i + i, y + j + j] == BoardPosition.Tile || (this.isTileMoved && boardPositions[x + i + i, y + j + j] == BoardPosition.Empty))
                                            {
                                                if ((this.isTileMoved && (this.movedTilePosition.X == x + i + i && this.movedTilePosition.Y == y + j + j)) || !this.isTileMoved)
                                                {
                                                    BoardPosition[,] newBoardPosition =
                                                        (BoardPosition[,])boardPositions.Clone();
                                                    newBoardPosition[x, y] = BoardPosition.Tile;

                                                    if (boardPositions[x, y] == colorTail)
                                                        newBoardPosition[x + i + i, y + j + j] = colorHead;
                                                    else
                                                        newBoardPosition[x + i + i, y + j + j] = colorTail;

                                                    Board newBoard = new Board(newBoardPosition);
                                                    newBoard.RedItems = this.RedItems;
                                                    newBoard.WhiteItems = this.WhiteItems;
                                                    newBoard.IsTileMoved = false;
                                                    boards.Add(newBoard);
                                                }
                                            }
                                            else if (boardPositions[x + i + i, y + j + j] == BoardPosition.Empty && !isTileMoved)
                                            {
                                                Point moveTileTo = new Point(x + i + i, y + j + j);

                                                foreach (Point movablePoint in movablePoints)
                                                {
                                                     if(boardPositions[movablePoint.X, movablePoint.Y] == BoardPosition.Tile)
                                                     {
                                                        BoardPosition[,] newBoardPosition = (BoardPosition[,])boardPositions.Clone();
                                                        newBoardPosition[movablePoint.X, movablePoint.Y] = BoardPosition.Empty;
                                                        newBoardPosition[moveTileTo.X, moveTileTo.Y] = BoardPosition.Tile;
                                                        bool canBeMovedThere = false;

                                                        if (newBoardPosition[moveTileTo.X + 1, moveTileTo.Y] != BoardPosition.Empty)
                                                            canBeMovedThere = true;
                                                        if (newBoardPosition[moveTileTo.X - 1, moveTileTo.Y] != BoardPosition.Empty)
                                                            canBeMovedThere = true;
                                                        if (newBoardPosition[moveTileTo.X, moveTileTo.Y + 1] != BoardPosition.Empty)
                                                            canBeMovedThere = true;
                                                        if (newBoardPosition[moveTileTo.X, moveTileTo.Y - 1] != BoardPosition.Empty)
                                                            canBeMovedThere = true;

                                                        if (canBeMovedThere)
                                                        {
                                                            Board newBoard = new Board(newBoardPosition);
                                                            newBoard.RedItems = this.RedItems;
                                                            newBoard.WhiteItems = this.WhiteItems;
                                                            newBoard.IsTileMoved = true;
                                                            newBoard.MovedTilePosition = moveTileTo;
                                                            boards.Add(newBoard);
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                    else if (!isTileMoved && (boardPositions[x + i, y + j] == BoardPosition.Empty || boardPositions[x + i + i, y + j + j] == BoardPosition.Empty))
                                    {
                                        bool isMovableTile = false;

                                        if ((i == -1 && j == -1) ||
                                            (i == 1 && j == 1) ||
                                            (i == -1 && j == 1) ||
                                            (i == 1 && j == -1))
                                        {
                                            int currentI = x + i;
                                            int currentJ = y + j;

                                            if (currentJ - 1 >= 0)
                                                if (boardPositions[currentI, currentJ - 1] != BoardPosition.Empty) isMovableTile = true;
                                            if (currentJ + 1 < 20)
                                                if (boardPositions[currentI, currentJ + 1] != BoardPosition.Empty) isMovableTile = true;
                                            if (currentI + 1 < 21)
                                                if (boardPositions[currentI + 1, currentJ] != BoardPosition.Empty) isMovableTile = true;
                                            if (currentI - 1 >= 0)
                                                if (boardPositions[currentI - 1, currentJ] != BoardPosition.Empty) isMovableTile = true;
                                        }
                                        else
                                            isMovableTile = true;

                                        if (isMovableTile)
                                        {
                                            Point moveTileTo = new Point(x + i, y + j);
                                            if (boardPositions[x + i, y + j] != BoardPosition.Empty)
                                            {
                                                moveTileTo.X += i;
                                                moveTileTo.Y += j;
                                            }
                                            foreach (Point movablePoint in movablePoints)
                                            {
                                                if(boardPositions[movablePoint.X, movablePoint.Y] == BoardPosition.Tile)
                                                {
                                                    BoardPosition[,] newBoardPosition = (BoardPosition[,])boardPositions.Clone();
                                                    newBoardPosition[movablePoint.X, movablePoint.Y] = BoardPosition.Empty;
                                                    newBoardPosition[moveTileTo.X, moveTileTo.Y] = BoardPosition.Tile;
                                                    bool canBeMovedThere = false;

                                                    if (newBoardPosition[moveTileTo.X + 1, moveTileTo.Y] != BoardPosition.Empty)
                                                        canBeMovedThere = true;
                                                    if (newBoardPosition[moveTileTo.X - 1, moveTileTo.Y] != BoardPosition.Empty)
                                                        canBeMovedThere = true;
                                                    if (newBoardPosition[moveTileTo.X, moveTileTo.Y + 1] != BoardPosition.Empty)
                                                        canBeMovedThere = true;
                                                    if (moveTileTo.Y - 1 >= 0) {
                                                        if (newBoardPosition[moveTileTo.X, moveTileTo.Y - 1] != BoardPosition.Empty)
                                                            canBeMovedThere = true;
                                                    }

                                                    if (canBeMovedThere)
                                                    {
                                                        Board newBoard = new Board(newBoardPosition);
                                                        newBoard.RedItems = this.RedItems;
                                                        newBoard.WhiteItems = this.WhiteItems;
                                                        newBoard.IsTileMoved = true;
                                                        newBoard.MovedTilePosition = moveTileTo;
                                                        boards.Add(newBoard);
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            if (boards.Count == 0)
                throw new Exception();
            return boards;
        }
 public bool IsCalculatedBefore(Board board, int depth, bool isPlayerAMax, bool turnPlayerA)
 {
     Int64 hashKey = CreateHashKey(board, depth, isPlayerAMax, turnPlayerA);
     int position = (int)Math.Abs((hashKey % tableSize));
     HashObject hashObject = tableContent[position];
     if (hashObject == null)
         return false;
     if (hashObject.depth >= depth && hashObject.hashKey == hashKey && hashObject.isPlayerAMax == isPlayerAMax && hashObject.turnPlayerA == turnPlayerA)
         return true;
     return false;
 }
 public int GetCalculatedValue(Board board, int depth, bool isPlayerAMax, bool turnPlayerA)
 {
     Int64 hashKey = CreateHashKey(board, depth, isPlayerAMax, turnPlayerA);
     int position = (int)Math.Abs((hashKey % tableSize));
     HashObject hashObject = tableContent[position];
     if (hashObject == null)
         throw new Exception("Board has not been calculated before and inserted into the transposition table");
     if (hashObject.depth >= depth && hashObject.hashKey == hashKey && hashObject.isPlayerAMax == isPlayerAMax && hashObject.turnPlayerA == turnPlayerA)
         return hashObject.value;
     else
         throw new Exception("Board has not been calculated before and inserted into the transposition table");
 }
 /// <summary>
 /// starts a new game
 /// </summary>
 /// <param name="playerA">playersettings of player A</param>
 /// <param name="playerB">playersettings of player B</param>
 /// <param name="startBoard">a board to start with</param>
 /// <param name="startPlayer">player that turns first</param>
 public void StartGame(PlayerSettings playerA, PlayerSettings playerB, Board startBoard, int startPlayer)
 {
     Game.Instance.StartGame(playerA, playerB, startBoard, startPlayer);
 }
Beispiel #10
0
        /// <summary>
        /// place pace to a point and switches the turn
        /// </summary>
        /// <param name="point">point for piece</param>
        public void PlacePiece(Point point)
        {
            Board b = (Board)board.Clone();
            b.BoardSituation[point.X, point.Y] = (turnPlayerA ? BoardPosition.RedTail : BoardPosition.WhiteTail);

            if (turnPlayerA)
                b.RedItems++;
            else
                b.WhiteItems++;

            bool isInList = false;
            b.CalculateMovableTiles();
            List<Board> possibleMoves = board.GenerateMoves(turnPlayerA);

            foreach (Board pm in possibleMoves)
            {
                if(pm.CompareTo(b)==0)
                    isInList = true;
            }

            if (isInList)
            {
                board = b;

                Logger.AddLine(GetCurrentPlayerNumber() + "-> Placed piece on: " + point.X + ", " + point.Y);
                Logger.AddLine("Board -> Evaluationvalue: " + board.Evaluation(turnPlayerA, turnPlayerA));

                ChangePlayer();
            }
            else
            {
                Logger.AddLine(GetCurrentPlayerNumber() + "-> Placing piece on: " + point.X + ", " + point.Y + " is not a valid move");
            }
        }
Beispiel #11
0
        /// <summary>
        /// move tile to a new point
        /// </summary>
        /// <param name="a">from point</param>
        /// <param name="b">to point</param>
        public void MoveTile(Point a, Point b)
        {
            Board cloneBoard = (Board)board.Clone();

            cloneBoard.BoardSituation[b.X, b.Y] = BoardPosition.Tile;
            cloneBoard.BoardSituation[a.X, a.Y] = BoardPosition.Empty;
            cloneBoard.IsTileMoved = true;
            cloneBoard.MovedTilePosition = new Point(b.X, b.Y);
            cloneBoard.CalculateMovableTiles();

            List<Board> possibleMoves = board.GenerateMoves(turnPlayerA);
            bool isInList = false;

            foreach (Board pm in possibleMoves)
            {
                if (pm.CompareTo(cloneBoard) == 0)
                    isInList = true;
            }

            if (isInList)
            {
                Logger.AddLine(GetCurrentPlayerNumber() + "-> Moved tile from: " + a.X + ", " + a.Y + " to " + b.X + ", " + b.Y);

                board = cloneBoard;
            }
            else
            {
                Logger.AddLine(GetCurrentPlayerNumber() + "-> It's not possible to move tile from: " + a.X + ", " + a.Y + " to " + b.X + ", " + b.Y);
            }
        }
Beispiel #12
0
        /// <summary>
        /// move piece to a new point and switches the turn
        /// </summary>
        /// <param name="a">from point</param>
        /// <param name="b">to point</param>
        public void MovePiece(Point a, Point b)
        {
            Board cloneBoard = (Board)board.Clone();

            BoardPosition old = cloneBoard.BoardSituation[a.X, a.Y];
            cloneBoard.IsTileMoved = false;
            if(Math.Abs(a.X - b.X)==2 || Math.Abs(a.Y - b.Y) == 2)
            {
                switch (old)
                {
                    case BoardPosition.RedTail:
                        old = BoardPosition.RedHead;
                        break;
                    case BoardPosition.RedHead:
                        old = BoardPosition.RedTail;
                        break;
                    case BoardPosition.WhiteTail:
                        old = BoardPosition.WhiteHead;
                        break;
                    case BoardPosition.WhiteHead:
                        old = BoardPosition.WhiteTail;
                        break;
                }
            }

            cloneBoard.BoardSituation[b.X, b.Y] = old;
            cloneBoard.BoardSituation[a.X, a.Y] = BoardPosition.Tile;
            cloneBoard.CalculateMovableTiles();
            List<Board> possibleMoves = board.GenerateMoves(turnPlayerA);
            bool isInList = false;

            foreach (Board pm in possibleMoves)
            {
                if (pm.CompareTo(cloneBoard) == 0)
                    isInList = true;
            }

            if(isInList)
            {
                Logger.AddLine(GetCurrentPlayerNumber() + "-> Moved piece from: " + a.X + ", " + a.Y + " to " + b.X + ", " + b.Y);
                board = cloneBoard;
                ChangePlayer();
            }
            else
            {
                Logger.AddLine(GetCurrentPlayerNumber() + " -> It's not possible to move piece from: " + a.X + ", " + a.Y + " to " + b.X + ", " + b.Y);
            }
        }
Beispiel #13
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;
        }
        /// <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);
        }
Beispiel #15
0
 /// <summary>
 /// 
 /// </summary>
 /// <param name="board"></param>
 public void IsMoveValid(Board board)
 {
     // IMPLEMENTATION NEEDED
 }
Beispiel #16
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="toChange"></param>
        /// <returns></returns>
        private List<Board> NewBoardPosition(BoardPosition toChange)
        {
            List<Board> boards = new List<Board>();

            for (int x = 0; x < 21; x++)
            {
                for (int y = 0; y < 20; y++)
                {
                    if (boardPositions[x, y] == BoardPosition.Tile)
                    {
                        BoardPosition[,] newBoardPosition = (BoardPosition[,])boardPositions.Clone();
                        newBoardPosition[x, y] = toChange;

                        Board newBoard = new Board(newBoardPosition);

                        if (toChange == BoardPosition.RedTail)
                        {
                            newBoard.RedItems = this.RedItems + 1;
                            newBoard.WhiteItems = this.WhiteItems;
                        }
                        else
                        {
                            newBoard.RedItems = this.RedItems;
                            newBoard.WhiteItems = this.WhiteItems + 1;
                        }
                        newBoard.IsTileMoved = false;
                        boards.Add(newBoard);
                    }
                }
            }

            return boards;
        }
Beispiel #17
0
 /// <summary>
 /// sets the board
 /// </summary>
 /// <param name="board">the new board</param>
 public void SetBoard(Board board)
 {
     if (IsEqual(this.board, board))
         throw new Exception();
     this.board = board;
 }
        /// <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;
        }
Beispiel #19
0
        /// <summary>
        /// starts a new game with a startboard and a turningplayer
        /// </summary>
        /// <param name="playerA">playersettings of player A</param>
        /// <param name="playerB">playersettings of player B</param>
        /// <param name="startBoard">a board to start with</param>
        /// <param name="startPlayer">player that turns first</param>
        public void StartGame(PlayerSettings playerA, PlayerSettings playerB, Board startBoard, int startPlayer)
        {
            this.playerA = new AIPlayer(playerA);
            this.playerB = new AIPlayer(playerB);
            NumMovesA = 0;
            NumMovesB = 0;
            this.board = startBoard;
            this.turnPlayerA = (startPlayer == 0 ? true : false);

            Logger.AddLine("Start new game, with startboard and turningPlayer");

            MakeAIMove();
        }
 public void InsertCalculatedValue(Board board, int depth, bool isPlayerAMax, bool turnPlayerA, int value)
 {
     Int64 hashKey = CreateHashKey(board, depth, isPlayerAMax, turnPlayerA);
     int position = (int)Math.Abs((hashKey % tableSize));
     HashObject hashObject = tableContent[position];
     if (hashObject == null)
         tableContent[position] = new HashObject(depth, hashKey, value, isPlayerAMax, turnPlayerA);
     else
     {
         bool collision = true;
         while (collision)
         {
             position = (int)Math.Abs((hashKey % tableSize));
             hashObject = tableContent[position];
             if (hashObject == null)
                 collision = false;
             else if (hashObject.hashKey != hashKey || hashObject.isPlayerAMax != isPlayerAMax || hashObject.turnPlayerA != turnPlayerA)
                 TableResize();
             else
                 collision = false;
         }
         tableContent[position] = new HashObject(depth, hashKey, value, isPlayerAMax, turnPlayerA);
     }
 }
Beispiel #21
0
        /// <summary>
        /// starts a new game
        /// </summary>
        /// <param name="playerA">playersettings of player A</param>
        /// <param name="playerB">playersettings of player B</param>
        public void StartGame(PlayerSettings playerA, PlayerSettings playerB)
        {
            this.playerA = new AIPlayer(playerA);
            this.playerB = new AIPlayer(playerB);

            NumMovesA = 0;
            NumMovesB = 0;

            // random first player
            System.Random r = new System.Random();
            int player = r.Next(1, 3);

            turnPlayerA = true;
            if (player == 2)
                turnPlayerA = false;

            board = new Board();

            Logger.AddLine("Start new game");

            MakeAIMove();
        }
        private Int64 CreateHashKey(Board board, int depth, bool isPlayerAMax, bool turnPlayerA)
        {
            Int64 result = 0;

            if (isPlayerAMax)
                result = result ^ playerAMax;
            else
                result = result ^ playerBMax;

            if (turnPlayerA)
                result = result ^ this.turnPlayerA;
            else
                result = result ^ turnPlayerB;

            for (int x = 0; x < 21; x++)
            {
                for (int y = 0; y < 20; y++)
                {
                    switch (board.BoardSituation[x, y])
                    {
                        case BoardPosition.Empty:
                            result = result ^ emptySpacesKeys[x, y];
                            break;
                        case BoardPosition.Tile:
                            result = result ^ tilesKeys[x, y];
                            break;
                        case BoardPosition.RedTail:
                            result = result ^ redTailKeys[x, y];
                            break;
                        case BoardPosition.RedHead:
                            result = result ^ redheadKeys[x, y];
                            break;
                        case BoardPosition.WhiteTail:
                            result = result ^ whiteTailKeys[x, y];
                            break;
                        case BoardPosition.WhiteHead:
                            result = result ^ whiteHeadKeys[x, y];
                            break;
                    }
                }
            }

            return result;
        }
Beispiel #23
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;
        }
        public static void updateBoard()
        {
            // set calculation to true
            calculating = true;
            Thread.Sleep(50);
            while (boardAnimating)
            {
                Thread.Sleep(50);
            }

            newBoard = UIConnector.Instance.GetBoard();
            UIConnector.Instance.MaxAIMoves(aiMoves);
            aiMoves++;
            manager.currentBoard = newBoard.BoardSituation;
            manager.redItems = newBoard.RedItems;
            manager.whiteItems = newBoard.WhiteItems;
            manager.SetupBoard();

            // set calculation to false;
            calculating = false;

            Thread.Sleep(1450);
            updateBoard();
        }
Beispiel #25
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;
        }