James Wei
Professor Peck
March 26, 2014
Slides by James Wei
•
A look at Boggle
•
Classes of Boggle
•
Understanding the design
•
Implementing a word finder
•
Implementing a lexicon
•
Implementing an autoplayer
•
Analysis
•
Grading
•
Summary
Outline
A look at Boggle
•
We are creating AI to play the game Boggle
•
The AI will make use of three main tools to find words on a boggle board:
•
A lexicon for knowing which words are valid
•
A word finder for searching for a specific word on the board
•
An autoplayer for searching the board for words
•
We will also analyze different implementations of these tools to see which ones are better
•
Sample playthrough
Classes of Boggle
•
The (more important) classes of Boggle:
•
BoggleMain
– runs Boggle
•
IWordOnBoardFinder
– interface for finding the position of a single word on a Boggle board
•
ILexicon – interface for a list of all valid words and the ability to query for them
•
IAutoPlayer
– interface for an AI Boggle player
•
LexiconBenchmark
– performs stress and correctness tests on Lexicon implementations
•
BoggleStats – compares performance for different lexicon/autoplayer combinations
•
TestLexicon/TestWordFinder – test your code
Understanding the Design
•
Boggle is a great example of the uses of inheritance! You will write multiple implementations for various interfaces.
•
As mentioned before, these interfaces include:
•
ILexicon
•
IWordOnBoardFinder
•
IAutoPlayer
Understanding the Design
•
Steps to Boggle:
•
Player enters a guess
•
Computer looks for word and highlights if found
•
When time runs out, computer looks for all valid words on board
•
Computer lists out all valid words
Understanding the Design
•
Break it down—what tasks must we be able to handle (and what’s handled for us)?
•
Given a String, determine if it is a word
•
Given a word, determine its exists on the board
•
Given a board, find all valid words in it
•
Framework for playing the game is given
Understanding the Design
•
Break it down—what tools will handle each individual task?
•
We determine if a String is a valid word using a lexicon, as defined by ILexicon
•
We search boards for individual words and obtain the positions of those words with a word finder, as defined by IWordOnBoardFinder
•
We determine the entire list of words on a board by using an autoplayer, as defined by IAutoPlayer
Understanding the Design
•
What are we given? What will we write?
•
Lexicons: we start with SimpleLexicon , which holds a dictionary as a list of Strings, and TrieLexicon , which uses tries (a variant of a tree) to organize words
•
We will write BinarySearchLexicon , which uses binary search to make querying the lexicon faster
•
For extra credit , you may also write
CompressedTrieLexicon , which is a more optimized implementation of TrieLexicon
Understanding the Design
Understanding the Design
•
What are we given? What will we write?
•
Word Finders: we start with our so-called
BadWordOnBoardFinder , which employs the beautiful strategy of always returning nothing
•
We will write GoodWordOnBoardFinder , which uses recursive backtracking to find the cells at which a word can be found on the board
Understanding the Design
•
What are we given? What will we write?
•
AutoPlayers: we have LexiconFirstAutoPlayer , which relies on a working implementation of
IWordOnBoardFinder to search the board for every possible word in the lexicon
•
We will write BoardFirstAutoPlayer , which uses recursive backtracking to search the board for all of valid words, instead of searching the board for each word in the lexicon specifically
Understanding the Design
Implementation – Lexicon
•
Look at BinarySearchLexicon . Most methods are already implemented for you, but you must complete one:
LexStatus wordStatus(String)
• wordStatus must:
•
Use binary search to see if the string exists in the lexicon (use Collections.binarySearch, check online for documentation on its usage)
•
Determine if a string that is not found is a PREFIX by finding the word in the lexicon which would succeed it if inserted and seeing if the string is a prefix to that word
Implementation – Lexicon
• What’s a
LexStatus ?
• It’s an enum , aka a special data type which must take one of several predefined constants
•
Our enum has three values:
•
LexStatus.WORD
•
LexStatus.PREFIX
•
LexStatus.NOT_WORD
•
More on enums: http://docs.oracle.com/javase/tutorial/java/javaOO/enum.html
•
Look at IWordOnBoardFinder
—there is one method to implement in this interface
List<BoardCell> cellsForWord(BoggleBoard, String)
• cellsForWord must:
•
Use recursive backtracking to find the cells in which a word on the board is found
•
Return a List of BoardCell objects which represent the position of each letter on the board in order
•
Hints to get started: what is the base case? What about the recursive step?
•
Two other classes to consider here, BoggleBoard and BoardCell , which are java objects representing the board and cell
•
BoggleBoard is implemented as a String array showing the faces of the board
•
So this board to the right is represented by the String array:
[“LORE”, “LTSR”, “AOSP”,
“MOTG”]
• BoardCell represents the position of one cell on the board—does not store the cell’s value!
Implementation – AutoPlayer
•
Look at BoardFirstAutoPlayer . Most methods are already implemented for you, but you must complete one: void findAllValidWords(BoggleBoard, ILexicon, int)
• findAllValidWords must:
• Iterate over all cells on a board for use as a “start”
•
For each starting cell, use recursive backtracking to find every word starting at that cell
•
Use an ILexicon to determine hits and base cases
•
Use the IPlayer add method to mark found words
Analysis
•
When you finish coding the assignment, you will have three (four with extra credit) lexicon implementations and two autoplayers
•
Now the question is—which ones are better?
•
You will analyze your different implementations using the BoggleStats class we have provided for you
Analysis
•
How to use BoggleStats
? Pretty easy…
• main method calls runTests, which calls doTests
• doTests will create two autoplayers, a
LexiconFirst and a BoardFirst, then it will use each autoplayer to find all valid words on a series of randomly generated boards
•
The Lexicon used by BoggleStats is passed in to doTests as an argument
•
You may change the instance variable
NUM_TRIALS as appropriate
•
You will need to modify doTests to return the highest scoring board for part of the analysis
Analysis
•
Your analysis has a few parts:
•
Compare running different autoplayers with different lexicons (with at least 500 trials per combination).
Include both empirical data AND code analysis!
•
Play lots of auto-games—start with 100, then 1,000,
10,000, 50,000. Use your findings to predict how long it’d take for 100,000 and 1,000,000 games
•
In your 10,000 auto-games, print out the Boggle board you find with the highest score (and the score)
•
Run these tests for both 4x4 and 5x5 boards
Grading
•
Your grade is based on:
•
Code (16 pts + 1 E.C.):
•
Word finder code passes tests
•
Lexicon code passes tests
•
Functional autoplayer
•
CompressedTrieLexicon implementation (extra credit)
•
Analysis (4 pts):
•
All combinations of autoplayers and lexicons
•
Sufficient number of trials per combination (500 bare minimum, likely need more for other parts of analysis)
•
High scores for 4x4 and 5x5 board sizes, and the boards corresponding to those scores
Wrap-Up
•
Recommended plan of attack?
•
Start by looking over everything, understanding the classes and the program design
•
Implement BinarySearchLexicon ; test with
TestLexicon which is provided
•
Implement GoodWordOnBoardFinder (you need to make this class yourself); test with
TestWordFinder
•
Modify BoggleMain to use your new word finder and try playing Boggle
•
Implement BoardFirstAutoPlayer ; try playing
Boggle with this autoplayer
Wrap-Up
•
Recommended plan of attack?
•
Check your BoardFirstAutoPlayer by running
BoggleStats with 100+ trials; your autoplayer should find the same number of words in every board as
LexiconFirstAutoPlayer
•
Using BoggleStats , try running large numbers of autoplayer games using all combinations of lexicons and autoplayers
•
In your analysis, compare performance of different lexicon/autoplayer combinations; make sure to include both empirical data and code analysis
•
For extra credit , implement CompressedTrieLexicon and include it in your analysis
One Last Thing…
• Start early! Seriously. Or you’ll be sadder than this woman:
Start early!