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 }); }
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 }); }