Tov Are Jacobsen

 Guess the animal

 

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 correct answer and a question to ask in order to tell the difference

 

 

Console version

 

The Node class implements the primary datastructure.

 ConsoleIO is a class to abstract the console IO and makes the main program much clearer.

.Guess implements guess the animal, this version is very readable.


  1. /*
  2.  *  Guess.java - main file.
  3.  *  
  4.  */
  5. package com.tovare.guessanimal;
  6.  
  7. import java.io.*;
  8. import java.util.*;
  9.  
  10. class Node {
  11.         Node yes = null;
  12.         Node no = null;
  13.         String desc = null;
  14.  
  15.         public Node( String desc){
  16.                 this.desc = desc;
  17.         }
  18.        
  19. }
  20.  
  21. class ConsoleIO{
  22.        
  23.         public static boolean YES = true;
  24.         public static boolean NO = false;
  25.         HashSet<String> positives = new HashSet<String>();
  26.         HashSet<String> negatives = new HashSet<String>();
  27.  
  28.  
  29.         static ConsoleIO io = null;
  30.         private static BufferedReader br = null;
  31.  
  32.         private void populatePositives(){
  33.                 positives.add("YES");
  34.                 positives.add("Y");
  35.                 positives.add("YEAH");
  36.         }
  37.        
  38.         private void populateNegatives(){
  39.                 negatives.add("NO");
  40.                 negatives.add("N");
  41.                 negatives.add("NOPE");
  42.                 negatives.add("FUCK");
  43.         }
  44.        
  45.         private ConsoleIO(){
  46.                 br = new BufferedReader( new InputStreamReader( System.in));
  47.         }
  48.        
  49.         private static ConsoleIO checkInstance(){
  50.                 if(io == null){
  51.                         io = new ConsoleIO();
  52.                         io.populateNegatives();
  53.                         io.populatePositives();
  54.                 }
  55.                 return io;
  56.         }
  57.        
  58.         public static String get(){
  59.                 checkInstance();
  60.                 String r = "";
  61.                 try{
  62.                         r =  br.readLine();
  63.                 }catch( IOException e){
  64.                         System.err.println("Input error");
  65.                 }
  66.                 return r;
  67.         }
  68.  
  69.         /**
  70.          * Get an input from the user, can be any string.
  71.          *
  72.          * @param prompt
  73.          * @return
  74.          */
  75.         public static String getInput( String prompt){
  76.                 System.out.print(prompt);
  77.                 System.out.flush();
  78.                 return ConsoleIO.get().trim();
  79.         }
  80.  
  81.         /**
  82.          * Get a simple yes/no answer.
  83.          *
  84.          * @param prompt
  85.          * @return
  86.          */
  87.         public static boolean getYesNo( String prompt){
  88.                 String s = getInput(prompt).trim().toUpperCase();
  89.                 while(true){
  90.                         if(io.positives.contains(s)){
  91.                                 return true;
  92.                         }
  93.                         if(io.negatives.contains(s)){
  94.                                 return false;
  95.                         }
  96.                         s = getInput(prompt).trim().toUpperCase();
  97.                 }
  98.         }
  99.        
  100. }
  101.  
  102.  
  103.  
  104. /**
  105.  *
  106.  * @author tovare
  107.  *
  108.  */
  109. public class Guess {
  110.  
  111.         Node head = null;
  112.         Node current = null;
  113.  
  114.         void search(){
  115.                 current =  head;
  116.                 // Traverse our yes/no questions until we hit a leaf node.
  117.                 while(current.no != null){
  118.                         if(ConsoleIO.getYesNo(current.desc+"? ")){
  119.                                 current = current.yes;
  120.                         }else{
  121.                                 current = current.no;
  122.                         }
  123.                 }
  124.                 if(ConsoleIO.getYesNo("Is it a "+current.desc+"? ")){
  125.                         System.out.println("Yippee! I win! \n\n");
  126.                 }else{
  127.                         Node n = new Node(ConsoleIO.getInput("What animal is it? "));
  128.                         Node a = new Node(ConsoleIO.getInput("What seperates a "+n.desc+" from a "+current.desc+"? "));
  129.                         a.yes = n;
  130.                         a.no = current;
  131.                         head = a;
  132.                 }
  133.         }
  134.        
  135.         public void play(){
  136.                 head = new Node("Dog");
  137.                 boolean inPlay = ConsoleIO.getYesNo("Animals, wanna play? ");
  138.                 while(inPlay){
  139.                         search();
  140.                         inPlay = ConsoleIO.getYesNo("Wanna play again? ");
  141.                 }
  142.         }
  143.        
  144.        
  145.         /**
  146.          * @param args
  147.          */
  148.         public static void main( String[] args) {
  149.                 Guess game = new Guess();
  150.                 game.play();
  151.         }
  152.  
  153. }

 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.

 

  1. /*
  2.  * Requires JDK 1.1 or higher
  3.  */
  4. import java.awt.*;
  5. import java.awt.event.*;
  6. import java.applet.*;
  7.  
  8. class Node {
  9.     Node yes;
  10.     Node no;
  11.     String text;
  12.     Node( String t) {
  13.         yes=null;
  14.         no=null;
  15.         text = t;
  16.     }
  17. }
  18.  
  19. public class GuessTheAnimal extends Applet implements ActionListener {
  20.         private static final long serialVersionUID = 1L;
  21.         final int GAMESTART_REQUEST=0;
  22.     final int COMPUTER_GUESSES=1;
  23.     final int COMPUTER_GUESSES_FEATURE=2;
  24.     final int ANIMAL_NAME_REQUEST=3;
  25.     final int NEW_FEATURE_REQUEST=4;
  26.     Node head;
  27.     Node current;
  28.     int state;
  29.     TextArea output;
  30.     TextField input;
  31.  
  32.     public GuessTheAnimal() {
  33.         head = new Node("DOG");
  34.         state = GAMESTART_REQUEST;
  35.         setLayout( new BorderLayout() );
  36.         output = new TextArea("COMPUTER: Animals, wanna play?\n");
  37.         input = new TextField();
  38.         add(output,"Center");
  39.         add(input,"South");
  40.         input.addActionListener(this);
  41.         state=GAMESTART_REQUEST;
  42.     }
  43.  
  44.     void askQuestion() {
  45.         if (current.no == null) {
  46.             output.append("Is it a "+current.text+"?\n");
  47.         } else {
  48.              output.append(current.text+"?\n");
  49.         }
  50.     }
  51.  
  52.     public void respond( String userText) {
  53.         switch(state) {
  54.         case GAMESTART_REQUEST:
  55.             if (userText.startsWith("Y")) {
  56.                 current=head;
  57.                 askQuestion();
  58.                 state=COMPUTER_GUESSES;
  59.             }
  60.             break;
  61.          case COMPUTER_GUESSES:
  62.             if (current.no == null) {
  63.                 if (userText.startsWith("YES")){
  64.                     output.append("Yippee, I win!\n");
  65.                     output.append("Wanna play again?\n");
  66.                     state=GAMESTART_REQUEST;
  67.                 }else{
  68.                     output.append("What animal is it?\n");
  69.                     state=ANIMAL_NAME_REQUEST;
  70.                 }
  71.              }else{
  72.                 if (userText.startsWith("YES")) {
  73.                     current = current.yes;
  74.                     askQuestion();
  75.                 } else if (userText.startsWith("NO")) {
  76.                     current = current.no;
  77.                     askQuestion();
  78.                 } else {
  79.                     output.append("Answer Yes or No please.\n");
  80.                 }
  81.              }
  82.              break;
  83.         case ANIMAL_NAME_REQUEST:
  84.             current.yes = new Node(userText);
  85.             output.append("What separates a "+userText+" from a "+current.text+"?\n");
  86.             state=NEW_FEATURE_REQUEST;
  87.             break;
  88.         case NEW_FEATURE_REQUEST:
  89.             current.no=new Node(current.text);
  90.             current.text=userText;
  91.             state=GAMESTART_REQUEST;
  92.             output.append("Wanna play again?\n");          
  93.             break;
  94.          }
  95.     }
  96.  
  97.     public void actionPerformed( ActionEvent e) {
  98.         output.append(input.getText()+"\n");
  99.         respond(input.getText().toUpperCase());
  100.         input.setText("");
  101.     }
  102. }