Programming & Problem Solving
Letter Game
In this project, you'll implement a player in a game similar to Scrabble, with the difference being that your player will bid on letters in an attempt to get the "good" ones. The goal is to implement a bidding strategy that will help you form better words and accrue more points.
A game consists of r rounds, and a round consists of 7p bids, in which p is the number of players (maximum 14); players are only allowed to get 7 letters per round. At the end of each round, points are awarded for the word that is created, and then we move onto the next round. At the end of the final round, the player with the most points wins.
There is a common pool of 98 letters distributed as in Scrabble, but without the blanks. At the start of a round, each player starts with n concealed letters known only to that player, with n anywhere from 0 to 6. Players then bid for letters, with each letter in turn (appearing in random order) going to the highest bidder. In a single round, letters are selected without replacement, so once somebody has the single 'Z' nobody else will have a 'Z'. Letters are reset at the start of a new round.
Players bid with points. Each player starts with 100 points to enable them to bid at the start of the game. As the round progresses, the point total will change as the players lose points to get letters, then gain points at the end of the round as they create words. A player cannot bid more points than he/she possesses, and a bid of zero points is allowed. Past bids are public information: every player knows how much each player has bid on each letter.
Players submit a single bid for each letter, and all bids are made simultaneously, without knowledge of other players' bids for that letter. The player who obtains the letter is determined according to the rules of a Vickrey Auction: the player who bids the most is the winner, but the amount they pay is that of the second-highest bid. If there is a tie for the high bid, the simulator will choose among the highest bids randomly.
After all 7p letters have been auctioned off in the round, each player tries to make as high-scoring a word as they can. A word will be considered valid if and only if it appears in a standard word list that we will supply. A word scores exactly what the word would have scored in Scrabble according to the points associated with the letters. In addition, a player who uses all seven letters receives a 50 point bonus. There is no bonus for words containing fewer than seven letters. The score is added to the player's total score, and the game continues with the next round.
Future variants we may explore include:
allowing players to acquire more than 7 letters per round
increasing the number of letters that are offered in each round
Letter Counts and Scores
Letter |
Count (out of 98) |
Score |
A |
9 |
1 |
B |
2 |
3 |
C |
2 |
3 |
D |
4 |
2 |
E |
12 |
1 |
F |
2 |
4 |
G |
3 |
2 |
H |
2 |
4 |
I |
9 |
1 |
J |
1 |
8 |
K |
1 |
5 |
L |
4 |
1 |
M |
2 |
3 |
N |
6 |
1 |
O |
8 |
1 |
P |
2 |
3 |
Q |
1 |
10 |
R |
6 |
1 |
S |
4 |
1 |
T |
6 |
1 |
U |
4 |
1 |
V |
2 |
4 |
W |
2 |
4 |
X |
1 |
8 |
Y |
2 |
4 |
Z |
1 |
10 |
Setting up the simulator
Download the simulator as an Eclipse project from Blackboard. To set it up:
Create a new Eclipse project called "LetterGame1.0".
Copy all of the content from the tar file that you downloaded into the workspace directory and refresh the Eclipse project.
Add the .jar file to the project's Java Build Path. After a while, the project errors should disappear.
Create a "Java Application" Run Configuration for the project with main class = lettergame.ui.GameEngine
When you run the project, you should see the simulator UI launch.
You can configure the number of hidden letters (that are assigned secretly at the beginning of a round) and the number of rounds in the game.
To add a player to the game, select it from the dropdown list and click "Add Player". Start with lettergame.g0.RandomPlayer.
Click "Begin New Game" to start a new game; this will take a few seconds at first as it loads the dictionary (which is in textFiles/dictionary.txt)
Click "Step" to move ahead one letter. You will see info about who won the bid in the lower right corner, and more details in the console output.
Click "Play" to play continuously (configure the Delay with the slider at the bottom right)
Click "Pause" to temporarily pause the game.
Creating your own player
Create a class called lettergame.gX.GroupXPlayer where X is your group number. This class must extend the abstract class lettergame.ui.Player, which means implementing the various methods:
newGame: this is called at the beginning of a new game; it gives you your ID and tells you how many rounds are in the game and how many players there are (including you)
newRound: this is called at the start of a round within a game; it gives you your initial secret state (including your score and any secret letters you've been assigned), as well as the current round number
getBid: this is called each time your player is asked to bid on a letter; in addition to the letter you're bidding on, there's info about past bids, too; this method is not called if you already have 7 letters, though
bidResult: this is called after the winner of the bid has been decided; if you won the bid, be sure to add the letter to currentLetters
getWord: this is called at the end of the round; you're asked which word you'd like to form out of your currentLetters; if you return a word that you're not legally allowed to make (because you don't have the right letters, or if it's not in the dictionary), the word will be ignored
updateScores: called at the end of a round, when the scores are updated
The Player class also includes these fields:
logger: for logging (don't use System.out.println)
currentLetters: ArrayList of all the letters you've won so far
myID: so that you know who you are
wordlist: ArrayList of all the words in the dictionary
See lettergame.g0.RandomPlayer for an example and some documentation.
About the rest of the API:
To know what a letter's value is, use the Letter's getValue method
Use the static methods in LetterGameValues to find out word score, letter score, letter frequency
The getWord() method in RandomPlayer contains code that will create the best-scoring word from the letters that you have acquired, though you are certainly not obligated to use this code.
To add your Player to the application, add the name of your class to the file Game.playerlist (if you have more than one, the class names should be separated by newlines, i.e. one per line).