This code implements a simple binary search for answers. The nodes all have questions, but the leaf-node has a suggestion for an answer.
The player is prompted to verify if this is correct, but if it’s not the player is requested for the right answer and a question to ask to tell the difference
Console version
/*
* Guess.java - main file.
*
*/
import java.io.*;
import java.util.*;
class Node {
Node yes = null;
Node no = null;
String desc = null;
public Node(String desc) {
this.desc = desc;
}
}
class ConsoleIO {
public static boolean YES = true;
public static boolean NO = false;
HashSet < String > positives = new HashSet < String > ();
HashSet < String > negatives = new HashSet < String > ();
static ConsoleIO io = null;
private static BufferedReader br = null;
private void populatePositives() {
positives.add("YES");
positives.add("Y");
positives.add("YEAH");
}
private void populateNegatives() {
negatives.add("NO");
negatives.add("N");
negatives.add("NOPE");
negatives.add("FUCK");
}
private ConsoleIO() {
br = new BufferedReader(new InputStreamReader(System. in ));
}
private static ConsoleIO checkInstance() {
if (io == null) {
io = new ConsoleIO();
io.populateNegatives();
io.populatePositives();
}
return io;
}
public static String get() {
checkInstance();
String r = "";
try {
r = br.readLine();
} catch (IOException e) {
System.err.println("Input error");
}
return r;
}
/**
* Get an input from the user, can be any string.
*
* @param prompt
* @return
*/
public static String getInput(String prompt) {
System.out.print(prompt);
System.out.flush();
return ConsoleIO.get().trim();
}
/**
* Get a simple yes/no answer.
*
* @param prompt
* @return
*/
public static boolean getYesNo(String prompt) {
String s = getInput(prompt).trim().toUpperCase();
while (true) {
if (io.positives.contains(s)) {
return true;
}
if (io.negatives.contains(s)) {
return false;
}
s = getInput(prompt).trim().toUpperCase();
}
}
}
/**
*
* @author tovare
*
*/
public class Guess {
Node head = null;
Node current = null;
void search() {
current = head;
// Traverse our yes/no questions until we hit a leaf node.
while (current.no != null) {
if (ConsoleIO.getYesNo(current.desc + "? ")) {
current = current.yes;
} else {
current = current.no;
}
}
if (ConsoleIO.getYesNo("Is it a " + current.desc + "? ")) {
System.out.println("Yippee! I win! \n\n");
} else {
Node n = new Node(ConsoleIO.getInput("What animal is it? "));
Node a = new Node(ConsoleIO.getInput("What seperates a " + n.desc + " from a " + current.desc + "? "));
a.yes = n;
a.no = current;
head = a;
}
}
public void play() {
head = new Node("Dog");
boolean inPlay = ConsoleIO.getYesNo("Animals, wanna play? ");
while (inPlay) {
search();
inPlay = ConsoleIO.getYesNo("Wanna play again? ");
}
}
/**
* @param args
*/
public static void main(String[] args) {
Guess game = new Guess();
game.play();
}
}
Applet version
The applet version was written in 1997 and uses a state machine to keep track of the current state while responding to asynchronous events from the GUI.
/*
* Requires JDK 1.1 or higher
*/
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
class Node {
Node yes;
Node no;
String text;
Node(String t) {
yes = null;
no = null;
text = t;
}
}
public class GuessTheAnimal extends Applet implements ActionListener {
private static final long serialVersionUID = 1L;
final int GAMESTART_REQUEST = 0;
final int COMPUTER_GUESSES = 1;
final int COMPUTER_GUESSES_FEATURE = 2;
final int ANIMAL_NAME_REQUEST = 3;
final int NEW_FEATURE_REQUEST = 4;
Node head;
Node current;
int state;
TextArea output;
TextField input;
public GuessTheAnimal() {
head = new Node("DOG");
state = GAMESTART_REQUEST;
setLayout(new BorderLayout());
output = new TextArea("COMPUTER: Animals, wanna play?\n");
input = new TextField();
add(output, "Center");
add(input, "South");
input.addActionListener(this);
state = GAMESTART_REQUEST;
}
void askQuestion() {
if (current.no == null) {
output.append("Is it a " + current.text + "?\n");
} else {
output.append(current.text + "?\n");
}
}
public void respond(String userText) {
switch (state) {
case GAMESTART_REQUEST:
if (userText.startsWith("Y")) {
current = head;
askQuestion();
state = COMPUTER_GUESSES;
}
break;
case COMPUTER_GUESSES:
if (current.no == null) {
if (userText.startsWith("YES")) {
output.append("Yippee, I win!\n");
output.append("Wanna play again?\n");
state = GAMESTART_REQUEST;
} else {
output.append("What animal is it?\n");
state = ANIMAL_NAME_REQUEST;
}
} else {
if (userText.startsWith("YES")) {
current = current.yes;
askQuestion();
} else if (userText.startsWith("NO")) {
current = current.no;
askQuestion();
} else {
output.append("Answer Yes or No please.\n");
}
}
break;
case ANIMAL_NAME_REQUEST:
current.yes = new Node(userText);
output.append("What separates a " + userText + " from a " + current.text + "?\n");
state = NEW_FEATURE_REQUEST;
break;
case NEW_FEATURE_REQUEST:
current.no = new Node(current.text);
current.text = userText;
state = GAMESTART_REQUEST;
output.append("Wanna play again?\n");
break;
}
}
public void actionPerformed(ActionEvent e) {
output.append(input.getText() + "\n");
respond(input.getText().toUpperCase());
input.setText("");
}
}