I'm trying to write a program to play "Pangolin" (like this guy - it asks yes/no questions, walking down a binary tree until it gets to a leaf node. It then "guesses", and if the user says the answer was wrong, asks the user what they were thinking of and for a question that distinguishes that from the incorrect gues. It then adds the new data to the tree).
This is the my struct for a tree node. NodeType is QUESTION_NODE for nodes containing a question or OBJECT_NODE for nodes containing an "object" - that is the thing the program deduces the user to be thinking of. Question nodes have pointers to child nodes - one for yes and one for no.
typedef struct _TreeNode {
NodeType type;
union {
char* question;
char* objectName;
} nodeString;
//children for yes and no answers: will be invalid when type is OBJECT_NODE
struct _TreeNode* yes;
struct _TreeNode* no;
} TreeNode;
As this is a learning exercise, I'm trying to do it with double pointers. Here is the function that is supposed to add a question node to the tree:
void addData(TreeNode** replace, char* wrongGuess) {
//create a new object node for what the user was thinking of
// ... (code to get user input and build the new object node struct) ... //
//create a new question node so we don't suck at pangolin so much
// ... (code to get a question from the user and put it in a question node struct) ... //
//link the question node up to its yes and no
printf("What is the answer for %s?\n", newObjectName);
if (userSaysYes()) {
newQuestionNodePtr->yes = newObjectNodePtr;
newQuestionNodePtr->no = *replace;
}
else {
newQuestionNodePtr->no = newObjectNodePtr;
newQuestionNodePtr->yes = *replace;
}
//redirect the arc that brought us to lose to the new question
*replace = newQuestionNodePtr;
}
The addData function is then called thus:
void ask(node) {
//(... ask the question contained by "node" ...)//
//get a pointer to the pointer that points to the yes/no member pointer
TreeNode** answerP2p;
answerP2p = userSaysYes() ? &(node.yes) : &(node.no);
//(... the user reports that the answer we guessed was wrong ...)//
puts("I am defeated!");
//if wrong, pass the pointer to pointer
addData(answerP2p, answerNode.nodeString.objectName);
My (presumably wrong) understanding is this:
In "ask()", I am passing addData a pointer which points to "node"'s member "yes" (or no). That member is in turn a pointer. When, in addData, I assign to "*replace", this should modify the struct, redirecting its "yes" (or no) member pointer to point to the new question node I have created.
I have debugged and found that the newQuestionNode and newObjectNode are created successfully. newQuestionNode's children are correctly assigned. However the new question node is not inserted into the tree. The "*replace = newQuestionNodePtr" line does not have the effect I would expect, and the node referred to by "node" in the "ask" scope does not have its child pointer redirected.
Can anyone see what is wrong in my understanding? Or perhaps a way in which I haven't expressed it right in my code? Sorry this question is so long.