A5.2: Ghost

Announcements and Clarifications

7/27 Due Date Changed to Sunday 5/30 @ 5:00pm

7/29 Updated common_words.txt to remove the word "and/or", please download the new file here

Brief Description

Your task in this assigment is to implement the game Ghost using a prefix tree. You will also implement a simple AI algorithm to construct a computer player for Ghost.

Goals and Requirements

Rules

Ghost is a simple two player word game. Each turn a player must pick a letter. The sequence of letters selected since the start of the game must form the beginning of an English word. If a player chooses a letter that completes an English word, that player loses. If a player chooses a letter that prevents any word from being formed, that player loses. See below for several example plays.

Implementation

All of the design decisions are up to you. You may implement your prefix tree however you choose, however before starting consider the important operations in the problem space. Remember that a prefix tree is a multiway tree where each node stores a character. Paths from the root to a leaf is a word stored in the tree. Paths from the root to an internal node is a prefix of a word stored in the tree.

The game will consist of two players, a human player (entering letters on the console) and a computer player. The computer player will operate in one of two possible modes. In the first mode the computer player will simply select some random letter between A and Z for each of its moves. In the second mode, the computer player will select moves that cause it to win. More information on how to implement an intelligent algorithm for the computer player see the next section.

The initial configuration of the game will be set using command line arguments:

 java Ghost dictionary_file first_player comp_mode 

The first argument is the dictionary file which is a list containing all the "valid" English words (this file need not contain all English words, but a large subset of them). A sample file is available here (source). The second argument describes who goes first, if 1 is passed the human, if 0 is passed the computer plays first. The final argument is the computer's AI mode. If 0 is passed the computer chooses moves randomly, if 1 is passed the computer uses the algorithm we describe later.

A several sample runs of the game are shown below:

wolf(15)%java Ghost common_words.txt 0 1
Computer goes first
Computer's choice: N
Current prefix: N
Enter letter choice: i
Computer's choice: A
Current prefix: NIA
Enter letter choice: c
Computer's choice: I
Current prefix: NIACI
Enter letter choice: n
Completed word NIACIN, you lose.
wolf(15)% java Ghost common_words.txt 1 1
Player goes first
Current prefix: 
Enter letter choice: J
Computer's choice: O
Current prefix: JO
Enter letter choice: g
Computer's choice: G
Current prefix: JOGG
Enter letter choice: L
Computer's choice: E
Completed word JOGGLE, computer loses.
wolf(16)% java Ghost common_words.txt 1 1
Player goes first
Current prefix: 
Enter letter choice: K
Computer's choice: H
Current prefix: KH
Enter letter choice: e
Computer's choice: D
Current prefix: KHED
Enter letter choice: d
No word begins with the letters KHEDD, you lose.

AI Algorithm

The algorithm that you will be implementing is from a family of algorithms called min-max algorithms. The idea behind min-max algorithms is to make your moves based on considering the moves an optimal opponent (one that always makes the right move) would make in response. The algorithm classifies moves as winning moves or losing moves. The description of the algorithm to classify moves is recursive in nature:

This algorithm is naturally applicable to prefix trees because each node in the prefix tree represents a choice in the game. Your algorithm will recurse through your data structure alternating turns. Each time the computer must make a choice, you should run the algorithm on the 26 possible choices for the computer's move. If any of the choices is a winning move, the computer is guaranteed to win the game and should make that move. If the computer has no winning moves, the computer should randomly select a possible move. If the computer has multiple winning moves it should select one of them at random.

For example, consider the following dictionary of three words:

AND
ANTLER
COW

Suppose the computer was playing first, the computer needs to decide whether to choose A or C first. If the computer choose C the human must choose O, then the computer will choose W and lose. So choosing C is a losing move. Suppose the computer choose A, the human player must choose N. Now the computer has a choice between D and T. If the computer selects D it loses, if the computer selects T eventually the human player will select R and lose, this means that T is a winning move for the computer. This means A is a winning move for the computer. The computer chooses A for its first move.

Commenting and Style

Handin

Please hand all necessary files into your handin directory in a subdirectory named Ghost. Your application class should be called Ghost.java. There should be exactly one class declared within each .java file. If your program does anything strange (bugs), awesome(extra features) or has a non-intuitive interface please include a file called README.txt which explain them. If there are bugs in your program but you do not describe them in your README you will lose more credit than if you had described them.

Hints