/* * Play the "animal" game, in which the program attempts to guess an animal * that the user is thinking of by asking yes or no questions. Eventually, * the program either will guess the user's animal or run out of questions * to ask. In the latter case, the program will ask the user to provide a * yes-or-no question that would distinguish between the user's animal and * the program's best guess. * The data structure of questions and guesses is essentially a binary tree, * with each internal node having a "yes" branch and a "no" branch. Leaves * of the tree represent animals to be guessed by the program. If the program * fails to guess the user's animal, it replaces one of the leaves of the tree * by a node containing the new question, whose children are the program's * best guess and the animal provided by the user. * The structure of the program is simple. It initializes the question/guess * data structure, then plays games as long as the user is interested. In each * game, the program starts at the top of the tree (the root) and progresses * toward the bottom (the leaves) depending on the user's responses. Once it * reaches a leaf, it either has won or lost, and handles the situation as * described above. */ int main (int argc, char *argv[]) { char *treefile = NULL; TreeType tree; PositionType pos; char *newQuestion, *newAnswer; if (argc > 1) { treefile = argv[1]; } tree = InitTree (treefile); printf("%s", "Think of an animal. I will try to guess what it is.\n" "Please answer my questions with yes or no.\n"); while (TRUE) { pos = Top (tree); while (!IsLeaf (tree, pos)) { pos = Answer(Question(tree,pos))? YesNode(tree,pos): NoNode(tree,pos); } if (Answer (Guess (tree, pos))) { printf ("I got it right!\n"); } else { GetNewInfo (tree, pos, &newAnswer, &newQuestion); ReplaceNode (tree, pos, newAnswer, newQuestion); } if (!Answer ("Want to play again? ")) { WriteTree(tree, treefile); exit (0); } } }
/* * Play the "animal" game, in which the program attempts to guess an animal * that the user is thinking of by asking yes or no questions. Eventually, * the program either will guess the user's animal or run out of questions * to ask. In the latter case, the program will ask the user to provide a * yes-or-no question that would distinguish between the user's animal and * the program's best guess. * The data structure of questions and guesses is essentially a binary tree, * with each internal node having a "yes" branch and a "no" branch. Leaves * of the tree represent animals to be guessed by the program. If the program * fails to guess the user's animal, it replaces one of the leaves of the tree * by a node containing the new question, whose children are the program's * best guess and the animal provided by the user. * The structure of the program is simple. It initializes the question/guess * data structure, then plays games as long as the user is interested. In each * game, the program starts at the top of the tree (the root) and progresses * toward the bottom (the leaves) depending on the user's responses. Once it * reaches a leaf, it either has won or lost, and handles the situation as * described above. */ int main () { TreeType tree; PositionType pos; char *newQuestion, *newAnswer; tree = InitTree (); // unitTest(); printf("%s", "Think of an animal. I will try to guess what it is.\n" "Please answer my questions with yes or no.\n"); while (TRUE) { pos = Top (tree); while (!IsLeaf (tree, pos)) { pos = Answer (Question (tree, pos))? YesNode (tree, pos): NoNode (tree, pos); } if (Answer (Guess (tree, pos))) { printf ("I got it right!\n"); } else { GetNewInfo (tree, pos, &newAnswer, &newQuestion); ReplaceNode (tree, pos, newAnswer, newQuestion); } if (!Answer ("Want to play again? ")) { exit (0); } } return 0; }
int TrackerNewCand(CTracker * I, TrackerRef * ref) { int result = 0; int index = GetNewInfo(I); int id; TrackerInfo *I_info = I->info; if(index) { TrackerInfo *info = I_info + index; info->ref = ref; info->next = I->cand_start; if(info->next) I_info[info->next].prev = index; I->cand_start = index; id = GetUniqueValidID(I); if(OVreturn_IS_OK(OVOneToOne_Set(I->id2info, id, index))) { info->id = (result = id); info->type = CAND_INFO; I->n_cand++; } else { ReleaseInfo(I, index); } } return result; }
int TrackerNewIter(CTracker * I, int cand_id, int list_id) { int result = 0; if((cand_id >= 0) || (list_id >= 0)) { int index = GetNewInfo(I); int id; TrackerInfo *I_info = I->info; if(index) { TrackerInfo *info = I_info + index; info->next = I->iter_start; if(info->next) I_info[info->next].prev = index; I->iter_start = index; id = GetUniqueValidID(I); if(OVreturn_IS_OK(OVOneToOne_Set(I->id2info, id, index))) { info->id = (result = id); info->type = ITER_INFO; I->n_iter++; if(cand_id && list_id) { /* seeking a specific member */ int hash_key = TRACKER_HASH_KEY(cand_id, list_id); OVreturn_word hash_start = OVOneToOne_GetForward(I->hash2member, hash_key); if(OVreturn_IS_OK(hash_start)) { int member_index = hash_start.word; TrackerMember *I_member = I->member; TrackerMember *member; while(member_index) { member = I_member + member_index; if((member->cand_id == cand_id) && (member->list_id == list_id)) { info->first = member_index; break; } member_index = member->hash_next; } } } else if(list_id) { /* for iterating over cands in a list */ OVreturn_word list_index = OVOneToOne_GetForward(I->id2info, list_id); if(OVreturn_IS_OK(list_index)) { TrackerInfo *list_info = I_info + list_index.word; info->first = list_info->first; } } else if(cand_id) { /* for iterating over lists in a cand */ OVreturn_word cand_index = OVOneToOne_GetForward(I->id2info, cand_id); if(OVreturn_IS_OK(cand_index)) { TrackerInfo *cand_info = I_info + cand_index.word; info->first = cand_info->first; } } } else { ReleaseInfo(I, index); } } } return result; }