Exemplo n.º 1
0
        // Only selects a random piece and position when there is no plays better than the one originally selected
        public static winningMove RandomPlay(winningMove winChoice)
        {
            int        rand;
            var        rnd = new Random();
            List <int> playablePieces;
            List <int> playablePositions;

            if (winChoice.heuristicValue == 0)
            {
                playablePositions = AIFunctions.makePlayablePositionList(winChoice.winningNode.gameBoard);
                if (playablePositions.Count() == 0)
                {
                    return(winChoice);
                }
                else if (playablePositions.Count() - 1 == 0)
                {
                    rand = 0;
                }
                else
                {
                    rand = rnd.Next(0, playablePositions.Count() - 1);
                }
                winChoice.winningNode.moveOnBoard = playablePositions[rand];

                playablePieces = AIFunctions.makePlayablePiecesOnly(winChoice.winningNode.pieces);
                if (playablePieces.Count() == 0)
                {
                    return(winChoice);
                }
                else if (playablePieces.Count() - 1 == 0)
                {
                    rand = 0;
                }
                else
                {
                    rand = rnd.Next(0, playablePieces.Count() - 1);
                }
                winChoice.winningNode.pieceToPlay = playablePieces[rand];
            }

            return(winChoice);
        }
Exemplo n.º 2
0
        // Generates all the piece selections that could possibly be made for a given gamestate.
        public static void generateChildrenPiece(Node currentNode, Node parentNode, int maxDepth, int depth)
        {
            int pieceMapCount = 0;
            int childCount    = 0;

            while (pieceMapCount < MAXGAMEBOARD)
            {
                if (currentNode.pieces[pieceMapCount].getPlayablePiece())
                {
                    totalGamestates++;
                    Node nextNode = new Node();

                    for (int counter = 0; counter < MAXGAMEBOARD; counter++)
                    {
                        string value = currentNode.gameBoard[counter];
                        nextNode.gameBoard[counter] = value;
                    }

                    nextNode.pieceToPlay = pieceMapCount;
                    int newMove = currentNode.moveOnBoard;

                    nextNode.moveOnBoard = newMove;
                    nextNode.parent      = parentNode;

                    parentNode.children[childCount] = nextNode;

                    AIFunctions.copyPieceMap(nextNode, currentNode, pieceMapCount);

                    childCount++;
                    if (depth < maxDepth)
                    {
                        Node childNode      = nextNode;
                        Node nextParentNode = childNode;
                        int  piece          = nextNode.pieceToPlay;
                        int  newDepth       = depth + 1;
                        generateChildrenGamestate(childNode, nextParentNode, piece, maxDepth, newDepth);
                    }
                }
                pieceMapCount++;
            }
        }
Exemplo n.º 3
0
        // Generates all the moves that could possibly be made for a given gamestate and piece.
        public static void generateChildrenGamestate(Node currentNode, Node parentNode, int piece, int maxDepth, int depth)
        {
            int boardPosCount = 0;
            int childCount    = 0;

            while (boardPosCount < MAXGAMEBOARD)
            {
                if (currentNode.gameBoard[boardPosCount] == null)
                {
                    Node nextNode = new Node();
                    for (int counter = 0; counter < MAXGAMEBOARD; counter++)
                    {
                        string value = currentNode.gameBoard[counter];
                        nextNode.gameBoard[counter] = value;
                    }
                    nextNode.gameBoard[boardPosCount] = currentNode.pieces[piece].getPiece();

                    nextNode.moveOnBoard = boardPosCount;

                    nextNode.parent = parentNode;
                    parentNode.children[childCount] = nextNode;

                    AIFunctions.copyPieceMap(nextNode, currentNode, piece);
                    nextNode.pieceToPlay = NULLPIECE;

                    childCount++;
                    if (depth < maxDepth)
                    {
                        Node childNode      = nextNode;
                        Node nextParentNode = childNode;
                        int  newDepth       = depth + 1;
                        generateChildrenPiece(childNode, nextParentNode, maxDepth, newDepth);
                    }
                }
                boardPosCount++;
            }
        }
Exemplo n.º 4
0
        public moveData generateTree(string[] newGameBoard, int piece, Piece[] currentPieces, int difficulty)
        {
            int    piecesOnBoard;
            int    maxDepth;
            int    positionToBlock;
            bool   boardBlockable = false;
            string moveToSend;
            string pieceOnDeck;

            Node newNode = new Node();

            newNode.gameBoard   = newGameBoard;
            newNode.pieceToPlay = piece;
            root = newNode;
            Node currentNode = root;
            Node parentNode;

            parentNode         = currentNode;
            currentNode.pieces = currentPieces;

            positionToBlock = AIFunctions.findWinningPositionToBlock(newGameBoard, currentPieces[piece].piece);
            if (difficulty == 3 && positionToBlock != -1 && Heuristic.calculateHeuristic(newGameBoard, currentPieces[piece].piece) > 0)
            {
                boardBlockable = true;
            }

            // Sets tree depth according to how many pieces are on the board
            piecesOnBoard = AIFunctions.countPiecesOnBoard(newGameBoard);
            maxDepth      = AIFunctions.setTreeDepth(piecesOnBoard, difficulty);

            // Generates game tree
            generateChildrenGamestate(currentNode, parentNode, piece, maxDepth, 0);

            // Finds the best move in the game tree based on a heuristic.
            winningMove move = NegaMax.searchForBestPlay(currentNode, maxDepth, 0, -MAXGAMEBOARD, MAXGAMEBOARD, true);

            if (boardBlockable && !move.isWin && piecesOnBoard != MAXGAMEBOARD - 1)
            {
                // Erases old winning move then adds new move to board.
                // Also sets old piece to playable again.
                move.winningNode.gameBoard[move.winningNode.moveOnBoard] = null;
                move.winningNode.gameBoard[positionToBlock] = currentPieces[piece].piece;
                move.winningNode.pieces[move.winningNode.pieceToPlay].setPlayable(true);

                move.winningNode = AIFunctions.checkForOpponentWin(move.winningNode, currentPieces[piece].piece);

                pieceOnDeck = move.winningNode.pieceToPlay == NULLPIECE?
                              NULLPIECE.ToString() : move.winningNode.pieces[move.winningNode.pieceToPlay].piece;

                moveToSend = move.winningNode.pieces[positionToBlock].piece;
            }
            else
            {
                if (piecesOnBoard != 0 && move.winningNode.pieceToPlay != NULLPIECE)
                {
                    move.winningNode = AIFunctions.checkForOpponentWin(move.winningNode, null);
                }

                moveToSend = move.winningNode.pieces[move.winningNode.moveOnBoard].piece;
                //Checks for win by opponent, given the piece chosen
                //If win it makes it equal to the next child and so on
                pieceOnDeck = move.winningNode.pieceToPlay == NULLPIECE?
                              NULLPIECE.ToString() : move.winningNode.pieces[move.winningNode.pieceToPlay].piece;
            }

            return(new moveData
            {
                lastMoveOnBoard = moveToSend,
                pieceToPlay = pieceOnDeck
            });
        }
Exemplo n.º 5
0
        public moveData generateTree(string[] newGameBoard, int piece, Piece[] currentPieces, int difficulty)
        {
            // hashing function would go here
            // Followed by a lookup in the transposition table
            //HashFunction.ZobristHash zash = new HashFunction.ZobristHash();
            //zash.init_zobristHash();


            totalGamestates = 0;
            int    piecesOnBoard;
            int    maxDepth;
            int    positionToBlock;
            bool   boardBlockable = false;
            string moveToSend;

            positionToBlock = AIFunctions.findWinningPositionToBlock(newGameBoard, currentPieces[piece].piece);
            if (difficulty == 3 && positionToBlock != -1 && Heuristic.calculateHeuristic(newGameBoard, currentPieces[piece].piece) > 0)
            {
                boardBlockable = true;
            }

            Node newNode = new Node();

            newNode.gameBoard   = newGameBoard;
            newNode.pieceToPlay = piece;
            root = newNode;

            Node currentNode = root;
            Node parentNode;

            parentNode         = currentNode;
            currentNode.pieces = currentPieces;

            // Sets tree depth according to how many pieces are on the board
            piecesOnBoard = AIFunctions.countPiecesOnBoard(newGameBoard);
            maxDepth      = AIFunctions.setTreeDepth(piecesOnBoard, difficulty);

            generateChildrenGamestate(currentNode, parentNode, piece, maxDepth, 0);

            winningMove move = NegaMax.searchForBestPlay(currentNode, maxDepth, 0, -MAXGAMEBOARD, MAXGAMEBOARD, true);

            //Checks for win by opponent, given the piece chosen
            //If win it makes it equal to the next child and so on
            if (piecesOnBoard != 0 && move.winningNode.pieceToPlay != NULLPIECE && difficulty > 1)
            {
                move.winningNode = AIFunctions.checkForOpponentWin(move.winningNode);
            }

            // This is bad but it works.
            string pieceOnDeck = move.winningNode.pieceToPlay == NULLPIECE?
                                 NULLPIECE.ToString() : move.winningNode.pieces[move.winningNode.pieceToPlay].piece;

            if (boardBlockable)
            {
                moveToSend = move.winningNode.pieces[positionToBlock].piece;
            }
            else
            {
                moveToSend = move.winningNode.pieces[move.winningNode.moveOnBoard].piece;
            }

            return(new moveData
            {
                lastMoveOnBoard = moveToSend,
                pieceToPlay = pieceOnDeck
            });
        }