- Pair, stage 2 project
- Due by End of Day, Friday Sept 18th by 5pm
An anagram is a word or phrase formed by rearranging the letters of a different word or phrase. Adagrams is a fictional game in which a player is given a random set of letters and must make an anagram using those letters. Adagrams has a specific scoring system, so that the player's submitted anagram scores points. The rules for Adagrams are roughly inspired by the "Letter Round" portion of the British game show Countdown.
While working on Adagrams, it may help to think of a physical metaphor for this game, such as other common word games like Scrabble or Bananagrams. These analog games all feature a pool of letter tiles that the player draws from.
In this version of Adagrams, we will only be working with the English alphabet.
- Write Ruby code with methods that declare data, read data, and manipulate data
- Write Ruby code with methods that take in parameters, use parameters, and return manipulated data
- Use pair-programming techniques
- Instill the habit of running unit tests to verify that the program works as expected
We will make a Ruby implementation of Adagrams that runs in the command line.
The program should also pass the provided unit tests.
Utilize good pair programming practices. Refer to articles from the Agile Alliance, the Agile Institute, and our own suggestions for pairing if you need a refresher for some best practices. Switch driver and navigator roles often. When there is uncertainty or confusion, step away from the keyboard and discuss, plan, and document on paper or whiteboard before continuing.
We have provided some driver code for your Adagrams game in the files wave-1-game.rb
, wave-2-game.rb
, wave-3-game.rb
, and wave-4-game.rb
. Running $ ruby wave-1-game.rb
will begin a command-line game that uses your Adagrams code. The boilerplate code will break the first time you run it: working through the waves specified below should create a running version of the game. Implementing code to make this game run is not a substitute for making the tests pass. It is simply there for you and your pair to reference how the Game may run during each wave, to have better perspective of what your program can do, and to get some practice reading other peoples' code. We fully expect you to create the specified methods to specification and making the tests pass.
- You'll be working with an assigned pair. High-five your pair.
- Choose one person to fork the project repo.
- Add the other person in the pair (who didn't fork) to the forked repo as a collaborator. Instructions here.
- Pick one machine to work on for the first few days.
- That machine will clone the forked repo:
$ git clone [YOUR FORKED REPO URL]
cd
into the dir created.
Note: At this point, we have to work off of one machine, and if we need to share code with each other, we need to do something awkward, unreliable, and slow, like email files of code to each other. Later this week, we'll learn how to get the code onto both machines and collaborate simultaneously using Git.
First, come up with a "plan of action" for how you want to work as a pair. Discuss your learning style, how you prefer to receive feedback, and one team communication skill you want to improve with this experience.
Take time to read through the Wave 1 implementation requirements and the tests for wave 1. Write down your questions, and spend some time going through your understanding of the requirements and tests with your pair. Make sure you both can run $ rake
and see the tests fail.
Come up with a "plan of action" for your implementation with your pair.
If, after you and your pair have taken some time to think through the problem and would like direction for how to dissect the problem, or if you need clarity on the terms/vocabulary we used in this project, you can check out a small hint we've provided.
This project has external dependencies. This means that someone else built a very good code tool, and we want to use it... by downloading and installing it. If our external dependency is a Ruby gem, then we need to install it.
We need to install three dependencies: minitest
, minitest-reporters
, and minitest-skip
for this project. We do so with these three commands:
$ gem install minitest
$ gem install minitest-reporters
$ gem install minitest-skip
It's possible that you've already done this in a previous lesson. Re-installing it does not have any negative side-effects.
minitest seems like a pretty cool Gem.
The tests for this project are written in minitest, a testing framework by Seattle Ruby Brigade. Hooray Seattle and Ruby!
- From the project root, you should be able to execute all of your tests by running
rake
in Terminal
For those curious about `rake`, click here
rake
(official site) is a program that runs tasks that we define. In this case, we have a pre-defined task that executes the tests. By running rake
, we are saying something like, "Please run the tasks, which includes the task that executes the tests."
We have provided unit tests for you to run. A complete project will pass all provided tests.
To run the tests, in the command line, navigate to the project root and then run the command $ rake
(without the $
. Remember, $
indicates that it is a command line command.)
When you first open the project and run the tests with rake
, you should have 0 passing tests and 17 failures. You should see something similar to the following screenshots:
What do these errors mean? These errors should help guide you with the next step to completing the project.
Do not move onto a new wave of requirements until the minimum requirements of the previous wave are complete and your tests are green across the board for all methods you've implemented. (Wave 1 tests are in the "draw_letters method" describe block, Wave 2 tests are in the "uses_available_letters? method" describle block, etc.)
Here is what it looks like when all 17 tests are passing:
Note: The screenshots say 16 tests instead of the correct 17 tests.
Our first job is to build a hand of 10 letters for the user. To do so, add a method called draw_letters
in adagrams.rb
. This method should have the following properties:
- No parameters
- Returns an array of ten strings
- Each string should contain exactly one letter
- These represent the hand of letters that the player has drawn
- The letters should be randomly drawn from a pool of letters
- This letter pool should reflect the distribution of letters as described in the table below
- There are only 2 available
C
letters, sodraw_letters
cannot ever return more than 2C
s - Since there are 12
E
s but only 1Z
, it should be 12 times as likely for the user to draw anE
as aZ
- Invoking this method should not change the pool of letters
- Imagine that the user returns their hand to the pool before drawing new letters
Letter : Qty. | Letter : Qty. |
---|---|
A : 9 | N : 6 |
B : 2 | O : 8 |
C : 2 | P : 2 |
D : 4 | Q : 1 |
E : 12 | R : 6 |
F : 2 | S : 4 |
G : 3 | T : 6 |
H : 2 | U : 4 |
I : 9 | V : 2 |
J : 1 | W : 2 |
K : 1 | X : 1 |
L : 4 | Y : 2 |
M : 2 | Z : 1 |
Note: Making sure that the drawn letters match the rules of the letter pool can be straightforward or very difficult, depending on how you build the data structure for the letter pool. It is worth spending some time with your partner to think carefully about this.
Next, we need a way to check if an input word (a word a player submits) only uses characters that are contained within a collection (or hand) of drawn letters. Essentially, we need a way to check if the word is, indeed, an anagram of some or all of the given letters in the hand.
To do so, add a method called uses_available_letters?
in adagrams.rb
. This method should have the following properties:
- Has two parameters:
input
, the first parameter, describes some input word, and is a stringletters_in_hand
, the second parameter, describes an array of drawn letters in a hand. You can expect this to be an array of ten strings, with each string representing a letter
- Returns either
true
orfalse
- Returns
true
if every letter in theinput
word is available (in the right quantities) in theletters_in_hand
- Returns
false
if not; if there is a letter ininput
that is not present in theletters_in_hand
or has too much of compared to theletters_in_hand
We want a method that returns the score of a given word as defined by the Adagrams game.
Name this method score_word
in adagrams.rb
. This method should have the following properties:
- Has one parameter:
word
, which is a string of characters - Returns an integer representing the number of points
- Each letter within
word
has a point value. The number of points of each letter is summed up to represent the total score ofword
- Each letter's point value is described in the table below
- If the length of the word is 7, 8, 9, or 10, then the word gets an additional 8 points
Letter | Value |
---|---|
A, E, I, O, U, L, N, R, S, T | 1 |
D, G | 2 |
B, C, M, P | 3 |
F, H, V, W, Y | 4 |
K | 5 |
J, X | 8 |
Q, Z | 10 |
After several hands have been drawn, words have been submitted, checked, scored, and played, we want a way to find the highest scoring word. This method looks at the array of words
and calculates which of these words has the highest score, applies any tie-breaking logic, and returns the winning word in a special data structure.
Add a method called highest_score_from
in adagrams.rb
. This method should have the following properties:
- Has one parameter:
words
, which is an array of strings - Returns a single hash that represents the data of a winning word and its score. The hash should have the following keys:
:word
, whose value is a string of a word:score
, whose value is the score of that word
- In the case of tie in scores, use these tie-breaking rules:
- prefer the word with the fewest letters...
- ...unless one word has 10 letters. If the top score is tied between multiple words and one is 10 letters long, choose the one with 10 letters over the one with fewer tiles
- If the there are multiple words that are the same score and the same length, pick the first one in the supplied list
We want to be able to verify that a word that a player submits is a valid word against the English dictionary.
We have the English dictionary available as a CSV file. We want to write a method that checks an input word against the words listed in the CSV file. If the word is found in the CSV file, then the word is valid and can be played.
Add a method called is_in_english_dict?
in adagrams.rb
. This method should have the following properties:
- Has one parameter:
input
, which is a string - Returns a boolean
true
, ifinput
is in the provided English dictionaryfalse
, ifinput
is not in the provided English dictionary
- Uses the English dictionary found in
assets/dictionary-english.csv
There are no unit tests provided for this wave, but there is driver code found in wave-5-game.rb
. Feel free to alter test/adagrams_test.rb
and add some!
Nota Bene: The original data for all of the alpha words of the English dictionary was found freely available at dwyl/english-word
's repo, and was modified to only include words under 10 characters.
Check out the feedback template which lists the items instructors will be looking for as they evaluate your project.