In this article, we will create a program that resembles 20 questions using a custom made binary tree. Any prior knowledge of Binary Trees is not necessary, though having basic knowledge of C# programming and creating classes is assumed. Thank you for your interest in my work.
Project Details
Create a game that asks users to think of an object and test that object against previously known questions and answers. If the object is outside of the computer's knowledge then the computer's knowlege will need to be updated.
(Note: see Sample Output for more information)
Binary Trees
Used to hold computer's knowledge. Each node has an object or question field and a reference to a 'yes' and 'no' node.

Binary Trees
Introduction to Binary Trees: A binary tree is a very efficient data structure consisting of nodes that point to each other. Each node has a data field and two references to other nodes. When progressing through a tree, one starts at the root node and moves to another node, left or right, until reaching a null reference. A node containing two null references is called a leaf node. For more information about binary trees visit: http://en.wikipedia.org/wiki/Binary_tree.

Using Binary Trees in our program: Each node will contain a question and two links to other nodes. If 'yes' is entered for a question, yes Node will be referenced. When the referenced node is a leaf node, the computer will make a guess on the object. Answering 'no' to the root node, in the example to the right, will produce the following output:
Is your object living? No
Are you thinking of a(n) Door? Yes
The computer wins!
If the computer's guess is incorrect, a new object and question has to be inserted into the tree.

Coding Binary Nodes
Programming the Binary Node Class
Create a new project named MCS_Week1 and add a new class named BTNode.cs. Add the following code which creates a constructor for the class. We are using three variables: message, noNode, and yesNode.
Creating the BTNode Class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MCS_Week_001
{
class BTNode
{
string message; //holds user's question or if a leaf node an object
BTNode noNode; //reference to node if user enters no
BTNode yesNode; //reference to node if user enters yes
public BTNode(string nodeMessage)
{
message = nodeMessage;
noNode = null;
yesNode = null;
}
}
}
Adding Mutator Methods
The constructor's variables need mutator methods. These methods allow variables within a class to be changed by creating a public method that changes them. Add the following code to your BTNode class.
Adding Mutator Methods to BTNode Class
//Mutator Methods
public void setMessage(string nodeMessage)
{
message = nodeMessage;
}
public string getMessage()
{
return message;
}
public void setNoNode(BTNode node)
{
noNode = node;
}
public BTNode getNoNode()
{
return noNode;
}
public void setYesNode(BTNode node)
{
yesNode = node;
}
public BTNode getYesNode()
{
return yesNode;
}
Checking Leaf Nodes
When a node has two null references the computer has no more questions and the computer is ready to make a guess. The following method will check to see if a node is a leaf node and it will be used later when progressing through the binary trees. Add the following code inside your BTNode class.
Creating the BTNode Class
public bool isQuestion()
{
if (noNode == null && yesNode == null)
return false;
else
return true;
}
Progressing Through the Binary Tree
This game requires a user to answer a question. If the user answers yes, it asks the next question contained in the yesNode. To access the next node we are going to use a method called query(). To access the yes node use yesNode.query() and noNode for the no node. This method will also have to reconstruct the tree when the computer does not know the answer. This is done in the updateTree() method. Add the following code to your BTNode class. A complete BTNode.cs file can be found at the end of this resource.
Query through the Binary Tree
public void query()
{
if (this.isQuestion())
{
Console.WriteLine(this.message);
Console.Write("Enter 'y' for yes and 'n' for no: ");
char input = getYesOrNo(); //y or n
if (input == 'y')
yesNode.query();
else
noNode.query();
}
else
this.onQueryObject();
}
public void onQueryObject()
{
Console.WriteLine("Are you thinking of a(n) " + this.message + "?");
Console.Write("Enter 'y' for yes and 'n' for no: ");
char input = getYesOrNo(); //y or n
if (input == 'y')
Console.Write("The Computer Wins\n");
else
updateTree();
}
private void updateTree()
{
Console.Write("You win! What were you thinking of?");
string userObject = Console.ReadLine();
Console.Write("Please enter a question to distinguish a(n) "
+ this.message + " from " + userObject + ": ");
string userQuestion = Console.ReadLine();
Console.Write("If you were thinking of a(n) " + userObject
+ ", what would the answer to that question be?");
char input = getYesOrNo(); //y or n
if (input == 'y')
{
this.noNode = new BTNode(this.message);
this.yesNode = new BTNode(userObject);
}
else
{
this.yesNode = new BTNode(this.message);
this.noNode = new BTNode(userObject);
}
Console.Write("Thank you my knowledge has been increased");
this.setMessage(userQuestion);
}
Coding Binary Tree
Creating the BTTree Class
When a new game is created, a reference to a root node is needed which holds the first question of the game. The BTTree Class will store the root reference and two object nodes. These object nodes are the two choices for the first question. Create a new class and name it BTTree.cs. Add the following code to the class.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MCS_Week_001
{
class BTTree
{
BTNode rootNode;
public BTTree(string question, string yesGuess, string noGuess)
{
rootNode = new BTNode(question);
rootNode.setYesNode(new BTNode(yesGuess));
rootNode.setNoNode(new BTNode(noGuess));
}
public void query()
{
rootNode.query();
}
}
}
Mike RamseyPosted Feb 18, 2013, 10:00 AM
Great code project and explanation. I would like to use this and expand upon it to store the binary tree to file and load it on a subsequent play through. In the source code there is a loadTree method but it is incomplete and throws a build error. I commented it out to get the code to compile and run, but I am wondering how to implement that method on start up so that if a binary tree was already present it would use it. Any help would be much appreciated. Thanks