//append nodes void Field::appendNode(Players_Character player_append, Node* n) { if (existNode(n)) { std::cout << "The node has already been used" << std::endl; //throw some error } else { m_allnodes[(int)player_append].push_back(*n); } }
void lookForWinningMove(binaryTreePtr tree) /* here we check if there's any winning moves for the user right now * this is because the computer would rather block a move, than go for the win * when there's a move eval is set to 1000 so that we know it will be the biggest value on minmax * the same happens on a losing move with a value off -1000 * Pre-condition: none * Post-condition: we have checked for a winning move */ { //go to the root level nextNode(tree,TOROOT); //get the game area infoPtr root = retrieveNodeElm(tree); //goto the second level nextNode(tree,TOLEFT); //get the game area for this option infoPtr temp = retrieveNodeElm(tree); //can we win now? if (canWeWinNow(temp) == 1) { //make this option a possible winning move temp->eval = 1000; root->eval = 1000; }else { //can we lose now? given that there's not a winning move somewhere if ( (canWeLoseNow(temp) == 1) && (root->eval != 1000) ) { //make this a possible losing move temp->eval = -1000; root->eval = -1000; } } //travese through the rest of the options on this level while (existNode(tree,TORIGHT) == 1) { //go to next option nextNode(tree,TORIGHT); //get the game area for this option temp = retrieveNodeElm(tree); //can we win now? if (canWeWinNow(temp) == 1) { //make this option a possible winning move temp->eval = 1000; root->eval = 1000; }else { //can we lose now? given that there's not a winning move somewhere if ( (canWeLoseNow(temp) == 1) && (root->eval != 1000) ) { //make this a possible losing move temp->eval = -1000; root->eval = -1000; } } } }
void expandTree(binaryTreePtr tree) /* This procedure expands a unique tree for the current game state * Pre-condition: the tree has been allocated in memory * Post-condition: a tree has been created for the given game state */ { if (tree != NULL) { //get the current gamestate for the level in tree we are on infoPtr gameInfo = retrieveNodeElm(tree); //store the adress of the current node in the tree treeNodePtr current; current = getCurrentNode(tree); //get the root level's game state nextNode(tree,TOROOT); infoPtr rootInfo = retrieveNodeElm(tree); //go back to current level setCurrentNode(tree,current); //we only extend 2 levels, this counts how many we have done int cmpSquares = squaresAvailable(rootInfo) - squaresAvailable(gameInfo); //is there any sqaures available? if ( (cmpSquares < 3) && (squaresAvailable(gameInfo) != 0) ) { //generate the next level for the tree generateSquares(tree); //go back to the node we started with setCurrentNode(tree, current); //go to the first node on the next level nextNode(tree, TOLEFT); //set this as the current node current = getCurrentNode(tree); //call this procedure again, to expand the next level expandTree(tree); //go back to first node of level we are working with setCurrentNode(tree, current); //does it have a next node on this level? while (existNode(tree, TORIGHT) == 1) { //then go to the next node nextNode(tree, TORIGHT); //get node on this level we are working with current = getCurrentNode(tree); //generate a next level for this node expandTree(tree); //back to working level setCurrentNode(tree, current); } } } }
void makeMove(binaryTreePtr tree, infoPtr gameInfo) /* This procedure will make the best move available * Pre-condition: none * Post-condition: the best move has been made */ { //go to the root nextNode(tree, TOROOT); //get the info for root/the top level infoPtr root = retrieveNodeElm(tree); //goto first node of next level nextNode(tree, TOLEFT); //get the info for this node infoPtr temp = retrieveNodeElm(tree); //is this the value on this level that gave root it's value? if (root->eval == temp->eval) { //it is! Then copy the game area to root copyGameArea(temp, root); }else { //is there a next node on this level and is the current node's value not //equal to the root's? while ((existNode(tree,TORIGHT) == 1) && (root->eval != temp->eval)) { //goto next node on level nextNode(tree, TORIGHT); //get the info for this node temp = retrieveNodeElm(tree); //is this the value on this level that gave root it's value? if (root->eval == temp->eval) { //it is! Then copy the game area to root copyGameArea(temp, root); } } } //copy the playArea from the root to the game's playArea copyGameArea(root,gameInfo); }
void bestMove(binaryTreePtr tree) /* This procedure will determine the best move available * by using a minmax method to either compute the value (on a leaf) * or sending it one level up where will be decided if the minimum or the maximum value will be used * Pre-condition:none * Post-condition: the root of the tree now has the minmax value needed */ { infoPtr gameInfo,temp; treeNodePtr current; //retrieve the current node's info gameInfo = retrieveNodeElm(tree); //is this a leaf? if ((existNode(tree,TOLEFT)== -1) ) { //then compute the value of this square gameInfo->eval = evaluateSquares(gameInfo); }else { //go down a level, to first node nextNode(tree, TOLEFT); //get the current node in tree current = getCurrentNode(tree); //get the info for this node temp = retrieveNodeElm(tree); //call this procedure again, this will send up a value bestMove(tree); //go back to first node on the level setCurrentNode(tree, current); //set the parent level's value to this node's gameInfo->eval = temp->eval; //is there a next node on this level? while (existNode(tree,TORIGHT) == 1) { //then go to the next node nextNode(tree, TORIGHT); //set this as the current node on this level current = getCurrentNode(tree); //get the info for this node temp = retrieveNodeElm(tree); //call this procedure again, this will send up a value bestMove(tree); //go back to node on this level we're working on setCurrentNode(tree, current); //who's turn was it last if (gameInfo->turn == COMPUTER) { //if temp->eval is smaller if (gameInfo->eval > temp->eval) { //this is the new minimum value gameInfo->eval = temp->eval; } }else { //if temp->eval is bigger if (gameInfo->eval < temp->eval) { //this is the new maximum value gameInfo->eval = temp->eval; } } } } }