1. Adventure Game
This page describes the Adventure Game that CS206 is designing.
1.1. File Format
The first thing we decided in class was the file format for the game. A game looks like the following:
// This is a sample Game Format File. We will typically
// end these files with the .game extension
// There are 4 kinds of lines:
// 1. blank lines
// 2. comment lines (lines that start with a slash)
// 3. node lines (start with +, tab-separated, name, description)
// 4. edge lines (start with -, tab-separated, fromName, dir, toName)
// 5. double edge line (starts with =, tab-separated, from, dir, to) creates symmetric links
+ street You are on a deadend street. There is an open sewer nearby.
+ sewer You are in the sewer
+ tunnel1 You are in the tunnels
+ tunnel2 You are in the tunnels
+ deadend You are at the deadend
+ goal You found the gold!
- street down sewer
- sewer east tunnel1
- tunnel1 south tunnel2
= tunnel1 north deadend
- tunnel2 west goal
- tunnel1 north tunnel1
- tunnel1 east tunnel1
- tunnel2 north tunnel1
- tunnel2 east tunnel1
* key deadend The golden key
1.2. File IO
We also designed a InputFile class to make life easy with opening files. We want to be able to make opening up a file, and processing it line-by-line, easy. Like:
...
InputFile in = new InputFile("test.game");
String line = in.getLine();
while (! in.EOF() ) {
// process each line...
line = in.getLine();
}
...
Here is some code that implements such functions:
import java.io.*;
public class InputFile {
BufferedReader reader;
boolean eof;
public InputFile(String filename) {
reader = null;
eof = false;
try {
reader = new BufferedReader( new FileReader(filename));
} catch (FileNotFoundException e) {
System.out.println("file not found: " + filename);
return;
}
}
public boolean EOF() {
return eof;
}
public String readLine() {
String line = null;
try {
line = reader.readLine();
} catch (IOException e) {
System.out.println("error reading file");
return null;
}
if (line == null)
eof = true;
return line;
}
}
1.3. Command-line Arguments
You can pass information to your Java program like the following. First, call your program (say "Game") followed by any options:
% java Game option1 23 "this is a test"
You can access this information through the String array that you pass to main:
public static void main(String [] args) {
System.out.println( args[0] ); // prints: option1
System.out.println( args[1] ); // prints: 23
System.out.println( args[2] ); // prints: this is a test
}
If you don't pass an argument, you'll get an ArrayIndexOutOfBoundsException. Note that these are all strings.
1.4. Associative Arrays
Wouldn't it be cool to refer to an item by a number. Oh, you can do that with arrays:
array[42].name = "Sam";
Wouldn't it be cool to refer to an item by a name. Oh, you can do that too! Think:
array["sam"].name = "Sam"
Java doesn't actually use that syntax. You do it this way:
...
HashMap dictionary = new HashMap();
dictionary.put("sam") = new Person();
dictionary.get("sam").name = "Sam Houstin";
System.out.println("Sam's fullname is: " + dictionary.get("sam").name );
...
Many languages call associative arrays by different names: hash table (or just hash for short), dictionary, or associative array.
1.5. Tokenizer
A tokenizer is an object that can break strings up into pieces based on a delimiter. Here is a tokenizer breaking a sentence ("This is a test") into four words by separating them by the space delimiter:
StringTokenizer tokenizer = new StringTokenizer("This is a test", " ");
String word1 = tokenizer.nextToken(); // this
String word2 = tokenizer.nextToken(); // is
String word3 = tokenizer.nextToken(); // a
String word4 = tokenizer.nextToken(); // test
Unfortunately, it isn't that clean in Java; you have to protect against some exceptions:
StringTokenizer tokenizer = null;
String command = null;
try {
tokenizer = new StringTokenizer(line, " ");
command = tokenizer.nextToken();
} catch (NullPointerException e) {
command = "";
} catch (NoSuchElementException e) {
command = "";
}
The delimiter can be more than just a character---it could be a long string: "---THIS IS THE DELIMITER---" for example.
You will probably want to .trim() the strings returned from the tokenizer.
Note that we will use the tab character to delimit our game file. Tab is represented in Java as "\t".
2. Putting it all together
Creating a new constructor that takes a filename might be called as follows:
public static void main(String [ ] args) {
Game game = new Game(args[0]);
if (game.reachable()) {
System.out.println("This is a valid map.");
game.play();
} else
System.out.println("This is not a valid map.");
System.out.println("Goodbye!");
}
import java.util.*;
class WordCounter {
public static void main(String [ ] args) {
AssociativeArray dictionary = new AssociativeArray();
InputFile in = new InputFile(args[0]);
String line = in.readLine();
while (! in.EOF()) {
line = line.trim();
dictionary.assign(line, dictionary.retrieve(line) + 1);
line = in.readLine();
}
Iterator keys = dictionary.iterator();
Object k = null;
while(keys.hasNext()) {
k = keys.next();
System.out.println(k + ": " + dictionary.retrieve(k));
}
}
}
import java.util.*;
class AssociativeArray {
HashMap array;
public AssociativeArray() {
array = new HashMap();
}
public int retrieve(Object o) {
return retrieve((String) o);
}
public int retrieve(String key) {
if (array.get(key) == null)
return 0;
else
return ((Integer)array.get(key)).intValue();
}
public void assign(String key, int value) {
array.put(key, new Integer(value));
}
public Iterator iterator() {
return array.keySet().iterator();
}
public static void main(String [] args) {
AssociativeArray x = new AssociativeArray();
x.assign("cat", 42);
if (x.retrieve("cat") == 42)
System.out.println("pass!");
if (x.retrieve("dog") == 0)
System.out.println("pass!");
}
}
