/** File is: Ani.java 5-11-06 Version 1.0
Author Clark Elliott. Status: throw-away code to illustrate connectionless
browser-based animal game.
WEB CLIENT
Just a standard web browser. Start by pointing to http://localhost:4001.
Pedagogy question:
What happens if the user presses the back button on the browser? Note
that only a portion of the state is indexed on the client. CurrentAnimalNode
is based on the *presumed* browser path: always forward.
One solution is to use the following constructs:
node nodeArray = new node[4000]; // max of 4000 animals.
int nodeCounter;
[In every new node]: this.nodeID = nodeCounter++;
nodeArray[this.nodeID] = this;
Then, when sending any node to the browser, send the ID of the node.
Whenever that state is returned from the browser (back button or not)
CurrentAnimalNode can be set based on the ID. In this way the full
state of the game is contained in every page. The key element is that
an integer value, which can be marshalled back and forth to the
browser, is sent in place of a node pointer, which cannot be marshalled.
----------------------------------------------------------------------*/
import java.io.*; // Get the Input Output libraries
import java.net.*; // Get the Java networking libraries
class AnimalWorker extends Thread { // Class definition
Socket sock; // Class member, socket, local to Worker.
AnimalTree ani;
// Constructor: assign args s, a, to local values.
AnimalWorker (Socket s, AnimalTree a) {sock = s; ani = a;}
public void run(){
PrintStream out = null; BufferedReader in = null;
String NewHost = "localhost";
String buf = "";
int newPort;
Socket clientSock;
try {
out = new PrintStream(sock.getOutputStream());
in = new BufferedReader (new InputStreamReader(sock.getInputStream()));
String inLine = in.readLine();
System.out.println("Just got: " + inLine);
// START OF GAME:
if (inLine.indexOf("state-start-game-yn") > -1){
if (inLine.indexOf("response-no") > -1){
System.out.println("EXIT from game.");
out.println("
Game Over
");
}
else{
System.out.println("Starting the game");
sendHTMLheader(out);
sendHTMLQuestion(out, ani.CurrentAnimalNode.stringdata);
sendHTMLNodeState(out);
sendHTMLRadio(out);
}
} // INTERNAL NODE:
else if (inLine.indexOf("state-node-question-yn") > -1){
System.out.println("Got internal node.");
if (inLine.indexOf("response-yes") > -1){
ani.CurrentAnimalNode = ani.CurrentAnimalNode.left;
}
else{
ani.CurrentAnimalNode = ani.CurrentAnimalNode.right;
}
if (ani.IsLeaf(ani.CurrentAnimalNode)){ // reached an animal, so guess:
System.out.println("Now guessing the Animal");
sendHTMLheader(out);
out.println("
Is the animal" +
ani.aORn(ani.CurrentAnimalNode.stringdata) +
ani.CurrentAnimalNode.stringdata + "?
");
sendHTMLGuessState(out);
sendHTMLRadio(out);
}else{ // just another internal node:
sendHTMLheader(out);
out.println("
" + ani.CurrentAnimalNode.stringdata + "
");
sendHTMLNodeState(out);
sendHTMLRadio(out);
}
} // LEAF NODE:
else if (inLine.indexOf("state-guess-question-yn") > -1){
if (inLine.indexOf("response-yes") > -1){
ani.CurrentAnimalNode = ani.TreeHead;
sendHTMLheader(out);
sendHTMLGloatAndStart(out);
//sendHTMLStartGame(out);
sendHTMLRadio(out);
}
else{
sendHTMLheader(out);
sendHTMLAskWhat(out);
sendHTMLAnimalTextState(out);
sendHTMLInputBoxAnimal(out);
}
} // GOT NEW ANIMAL as TEXT:
else if (inLine.indexOf("state-animal-text") > -1){
sendHTMLheader(out);
int i1 = inLine.indexOf("inbox") + 6;
int i2 = inLine.indexOf(" ", i1) + 1;
String newAnimal = new String(inLine.substring(i1, i2));
System.out.println("New Animal is: " + newAnimal);
ani.newAnimal = newAnimal; // save for later processing
out.println("
Enter a question that is YES for" +
ani.aORn(newAnimal) + newAnimal + " but NO for" +
ani.aORn(ani.CurrentAnimalNode.stringdata) +
ani.CurrentAnimalNode.stringdata + "
");
sendHTMLAnimalQuestionState(out);
sendHTMLInputBoxQuestion(out);
} // GOT NEW QUESTION as TEXT:
else if (inLine.indexOf("state-input-question-text") > -1){
int i3 = inLine.indexOf("inbox") + 6;
int i4 = inLine.indexOf(" ", i3) + 1;
String q = new String(inLine.substring(i3, i4));
String q2 = q.replace('+', ' '); // Clean up from query string...
q = q2.replaceAll("%3F", "?");
ani.MakeInternalNode(ani.CurrentAnimalNode, q);
ani.CurrentAnimalNode = ani.TreeHead;
sendHTMLheader(out);
sendHTMLStartGame(out);
sendHTMLRadio(out);
}
else{ // DEFAULT is to just start the game:
System.out.println("REACHED DEFAULT STATE");
sendHTMLheader(out);
ani.CurrentAnimalNode = ani.TreeHead;
sendHTMLStartGame(out);
sendHTMLRadio(out);
}
out.flush(); sock.close();
} catch (IOException ioe) {System.out.println(ioe);}
}
static void sendHTMLheader (PrintStream out){
out.println("HTTP/1.1 200 OK");
out.println("Content-Length: 700"); // who knows how long, faking it.
out.println("Content-Type: text/html");
out.println("");
out.println(" ");
out.println("