The Softer Blog

2005-07-29

Learning Animals Game - Implementation

This is a very simple OO (Java) implementation of the classic artificial intelligence "Animals Game".


//Author: Klaus Wuestefeld
//This code is hereby placed in the public domain.

import javax.swing.JOptionPane;

public class LearningAnimalsGame {

static TreeElement _root = new Leaf("Monkey");

public static void main(String[] ignored) {
Player player = new Player();
do {
player.acnowledge("Please imagine a kind of animal"
+ " and I will try to guess what it is.");

_root = _root.learnFrom(player);
} while (player.confirms("Do you want to play again?"));
}
}

class Player {

boolean confirms(String proposition) {
return JOptionPane.YES_OPTION == JOptionPane.showConfirmDialog(null,
proposition, "Confirm", JOptionPane.YES_NO_OPTION);
}

public void acnowledge(String message) {
JOptionPane.showMessageDialog(null, message);
}

public String answer(String question) {
return JOptionPane.showInputDialog(null, question);
}
}

interface TreeElement {
TreeElement learnFrom(Player player);
}

class Leaf implements TreeElement {

private final String _kindOfAnimal;

Leaf(String kindOfAnimal) {
_kindOfAnimal = kindOfAnimal;
}

public TreeElement learnFrom(Player player) {
if (player.confirms("Is " + _kindOfAnimal
+ " the kind of animal you imagined?")) {

player.acnowledge("I knew it!  :)");
return this;
}

String newKind = player.answer("I give up."
+ " What kind of animal did you imagine?");

String difference = player
.answer("Please complete: The difference between " + newKind
+ " and " + this._kindOfAnimal + " is that " + newKind
+ "...");

return new Node(new Leaf(newKind), this, difference);
}
}

class Node implements TreeElement {

private final String _characteristic;
private TreeElement _yes;
private TreeElement _no;

public Node(TreeElement yes, TreeElement no, String characteristic) {
_characteristic = characteristic;
_yes = yes;
_no = no;
}

public TreeElement learnFrom(Player player) {
if (player.confirms("Is it true that the kind of"
+ " animal you imagined " + _characteristic + "?")) {
_yes = _yes.learnFrom(player);
} else {
_no = _no.learnFrom(player);
}
return this;
}
}