Saint Louis University |
Computer Science 150
|
Dept. of Math & Computer Science |
Our goal is to design a program to simulate a game of Boggle. The program will display a randomly chosen board, allow the user to enter as many words as he or she can find. The software will check that each entered word is legitimate. When the user is done entering words, the software should also produce a list of all other words which could have been found on that board.
For this assignment, you are allowed to work with one other student if you wish (in fact, we suggest that you do so). If any student wishes to have a partner but has not been able to locate one, please let the instructor know so that we can match up partners.
Please make sure you adhere to the policies on academic integrity in this regard.
ln -s /home/home0/goldwasser/lib/boggleUtil.py . ln -s /home/home0/goldwasser/lib/bogshort.txt . ln -s /home/home0/goldwasser/lib/boglong.txt .
The first of these are some utilties we have written to generate new boards and to display them (details below). The last two of these files are dictionaries. bogshort.txt contains 19912 words (most common words, but not plurals of nouns, or varying tenses of verbs). boglong.txt contains 117661 words and is much more complete (this is purported to be the official scrabble dictionary).
A Boggle board is comprised of 16 dice. Each side of a die is typically marked with a single letter from the English alphabet, though one dice has a side marked with 'Qu' (more about this later). To start the game, the dice are shaken up and then placed in a 4x4 grid. An example of such a game board is shown here.
A player is then asked to find as many words as possible on the game board. A word can be find by stepping from die to neighboring die, where this step can either be horizontal, vertical or diagonal. Such a path must be found so as to spell the word from beginning to end. Moreso, you may not use the same die twice when spelling a single word.
For example, the word WALK can be found as shown in the following figure.
The goal of the player is to list as many words as possible which can be found on the board. More formally, for a player to get credit for a word, the following conditions must be satisfied:
In the multiplayer version of Boggle, players only get credit for words which they find that are not found by any other players. In our one-player version, we will let the human player take the first turn, getting credit for all words he or she finds; then we let the computer take the second turn, taking credit for all remaining words not used by the player. The scoring for the official game gives more points for longer words, based upon the following formula:
Number of letters | 3 | 4 | 5 | 6 | 7 | 8 or more |
---|---|---|---|---|---|---|
Points awarded | 1 | 1 | 2 | 3 | 5 | 11 |
Here is a sample run of our program. Note that your program does not need to match the precise formatting shown here, but this should demonstrate the spirit of the game and the expected interactions.
Welcome to Boggle. What is the name of the wordlist file? [default: bogsmall.txt] What board number? [default: random] 180 R Qu I C U E R O I W Y K T D A L Please enter words, one per line. When you are done enter a blank line. walk lad tie die or -- Words must use at least three letters. ore core rice -- Sorry. That word cannot be formed on the gameboard. york -- Sorry. That word is not in the wordfile. cork quirk rock -- Sorry. That word cannot be formed on the gameboard. lawyer law yore ore -- You already used that word. year -- Sorry. That word cannot be formed on the gameboard. daddy -- Sorry. That word cannot be formed on the gameboard. day way tie -- You already used that word. wit ------------------------------------------ Player used 598.168277 seconds. You found 14 words worth a total of 17 points. core cork day die lad law lawyer ore quirk tie walk way wit yore Now it is the computer's turn... ------------------------------------------ Computer used 0.487780 seconds. The computer found 32 additional words for 39 points. adieu awe awry aye coy crew cry dye dyer ire irk kayo lady lay lye lyric okay query quirky royal rue rye tid tidal tidy tier wad wadi weir wry yak yaw ------------------------------------------ Would you like to play again? [default: Y] n Okay. Thanks for playing!
We will be starting you off with some utilities for generating and
representing a game board. The game board is viewed as a
two-dimensional structure. This can be naturally modeled in Python as
a list of lists That is the board can be thought of as a list
of columns, where each column is then a list of dice. For example, on
the board diagramed earlier in this description, the first column can
be viewed as a list
Syntactically, if we have a variable board representing such
a list of lists, then we can refer to an individual die using a syntax
such as board[2][3] which is the die 'A' in our example.
Namely, the simpler expression, board[2] would represent the
column
Given such a representation of a board, I have provided three utility functions for you to use:
newBoard()
By default, will randomly generate a new board structure and
return it to the caller. However it first prompts the user for
a 'game number' and if provided, will give the user a
particular game board rather than a new randomly
generated one.
drawBoard(board)
In this form, the board is drawn in pure text on the standard
output screen.
drawBoard(board,canvas,scale)
In this form, a picture of the board is displayed on the given
Canvas. By default it is scaled for a 200x200 canvas, but for
larger canvases, an alternate scale factor can be specified
relative to the default (e.g. with scale=2, it generates a
roughly 400x400 image).
clearHighlights(board)
(See next blurb about the representation of the dice.) This
simply clears the highlights for all of the dice.
Rather than representing the board directly as such a two-dimensional list of strings, we have created a class Die to represent each of the dice. The operations supported by a die are:
getValue()
returns a string represnting the visbile side of the die. Note
that the text will be all lower-case (even though our figures
show them as upper case).
setHighlight()
Requests that this die be displayed in 'highlighted' form when
the board is subsequently drawn.
clearHighlight()
Requests that this die no longer be displayed in 'highlighted'
form when the board is subsequently drawn.
The major challenges are:
Basic straightforward code to control the flow of a game.
Checking aspects of validity of a player's word, such as the length, whether it is in the dictionary, and whether it has been used already.
Checking the validity of a player's word as to whether it can legally be formed on a game board.
To do this, we strongly recommend thinking about formulating this as a recursive behavior. The key to get this working will be to carefully consider the signature of your recursion, that is, what information must be given as parameters and what information must be returned.
You might also consider the goal of being able to highlight the location of a valid word visually. To do this, you will need to have a routine that does not simply given a boolean response to whether or not a word is on the board, but in the positive case, provides a representation of the path used in verifying the word.
The ability to report all words which the player missed (and to do so efficiently, even on the large dictionary).
There are really two ways to find all such words. The first way is a word-based search. Presuming that you already have a function working which checks whether a given word appears on the game board, you can simply loop through all the words in the official dictionary and check whether each appears on the board. This takes minimal effort in terms of coding, but unfortunately you will find that it is quite slow, even on the shorter dictionary.
A completely different apprach is one we will term path-based. Rather than searching for specific words, try to form paths on the board and then check whether such a path leads you to a word in the dictionary. To make this efficient, the idea is to build short paths and then before going on, check whether the prefix you have actually occurs in the dictionary. That is, if you start tracing a path starting with "TRG" and you find that there are no words anywhere in the official dictionary starting with "TRG" then there is no need to continue spending time exploring this path.
Therefore, you will need to write a separate routine to be able to effectively check whether a given prefix occurs in the official dictionary. Since the words are kept alphabetized in a list, we can use binary search to accomplish this task. Checking whether a prefix occurs is very similar to checking whether an actual word occurs. With some minor adjustments, the binary search code we have already seen can be adapted to suit this task.
You should submit your new file, boggle.py, which contains all of your own code. This file must be submitted electronically.
You should also submit a separate 'readme' text file, as outlined in the general webpage on programming assignments.
Please see details regarding the submission process from the general programming web page, as well as a discussion of the late policy.
Write the efficient version of the software for finding all possible words on the board, using the path-based search rather than the word-based search, as described above.