PA4
PA4 - 00000111 Little Words (Loops and Arrays)
Due Dates and Submission Details
See submission details below for all due dates and submission details. Note there are multiple submission parts.
Honor Code
This assignment should be completed individually to maximize learning. It is important that you adhere to the Course Policies, particularly the section on Programming Assignments. Also relevant is the JMU Honor Code.
Objectives
- Write loops that contain nested if-else statements.
- Write loops for contexts that are appropriate for both while/do-while and for structures.
- Pass arrays as method arguments and return values.
- Manipulate, initialize, copy and compare elements of arrays of Strings.
- Generate random numbers based on an algorithm.
- Practice using tools such as checkstyle and JUnit.
Background
In this program, you will implement a simplified text version of the 7 Little Words — game. (For those of you who may not know, 00000111 interpreted as a base 2 number is 7 in base 10.) The 7 Little Words website explains the game and will allow you to play it. Our text version is very similar, but breaks every solution word into only two pieces, then displays those words in text boxes vertically instead of as a graphical grid. Our version does not give the hint of how many letters a solution is but otherwise works very similar to the game on the website. The clues must be solved in order and the user can ask for multiple hints for each clue. Hints can be the first letter of the solution, the first "slice" or part of the solution word in the puzzle, or the whole word.
Requirements
You will be writing two classes for this assignment, Generator.java
and TerminalUI.java
and one test class, GeneratorTest.java
. The methods for the first two classes will have methods as described below. Note that each method must be implemented exactly as described. See the example input
and output
below for the form of the interaction with the user.
TerminalUI.java
-
public static String promptForString(Scanner in, String message, int min)
This method will prompt the user using the message passed to it, read in the user's response as a String from the Scanner
in
and then return the response as a String. If the user enters a string with a length (number of letters/char) strictly less than the length indicated bymin
, then they will be reprompted.Example:
TerminalUI.promptForString(in, "Enter string", 2)
where the user enters "m" would reprompt until a longer word is entered. If the first string of 2 or more letters the user enters is "magnetism", the string returned will be magnetism. Note that if quotes are included in the user's entry they will be included in the String returned by the method. Below is an example from running TerminalUIDriver.Enter string: m Enter string: Enter string: magnetism Your string was magnetism
-
public static int promptForInt(Scanner in, String message, int max)
This method will prompt the user using the message passed to it, read in the user's response as an integer from the Scanner in and then return the response as an
int
. If the user enters an integer that is strictly less than one or greater thanmax
, then they should be reprompted for a new integer.Example:
TerminalUI.promptForInt(in, "Enter integer 1-12", 12)
where the user enters 0 would reprompt until an integer between 1 and 12 inclusive is entered. If the first number the user enters that is within the range 1-12 is 12, theint
returned will be 12. Below is an example from runningTerminalUIDriver
.Enter integer 1-12: 0 Enter integer 1-12: 13 Enter integer 1-12: 12 Your integer was 12
-
public static void promptNDisplayHints(Scanner in, String solution)
This method will prompt the user to see if they want a hint as described below, then print out the correct hint, reprompting as long as the user asks for a proper hint. If the user enters an "n" or any other response than a proper hint, the prompting stops.
Example:
TerminalUI.promptNDisplayHints(in, "magnetism")
where the user enters each kind of hint in order, would display each hint in order. Below is an example from runningTerminalUIDriver
.Want a hint? Enter "f" for first letter "s" for first slice "w" for whole word "n" for none: f m Want a hint? Enter "f" for first letter "s" for first slice "w" for whole word "n" for none: s magn Want a hint? Enter "f" for first letter "s" for first slice "w" for whole word "n" for none: w magnetism Want a hint? Enter "f" for first letter "s" for first slice "w" for whole word "n" for none: n
Generator.java
-
public static String[] wordSplicer(String[] solutions)
This method will split each of the words of the solutions array in half. If the word has an odd number of characters the smaller piece will be the first slice and the longer the second slice. A "board" array of half words will be returned. board array will have twice as many elements as the solutions array and the first two elements will be the two halves of first solution word, the third and fourth elements the two halves of the second solution word, etc. Note that this method should return null if the solutions array is null or of zero length. If there are words in the solutions array they will be a minimum of two letters (char). The algorithm used for this section should work with any reasonable size solutions array.
Example:
Generator.wordSplicer(new String[] {"tofutti", "magnetism"})
would return {"tof", "utti", "magn", "etism"}. -
public static String[] randomizer(String[] board, int seed)
This method will return a new copy of
Example:board
such that the slices in the board are in a new random order in the board. The original array should not be changed. If the board isnull
or the number of slices in the board is less than 2, null should be returned. The algorithm used to randomize the array should be to step through the array from beginning to the end, switching each element in the array with an element at another "random" index in the array. This random index should be found by instantiating an object of the Random class using the seed parameter as the seed and then obtaining consecutive random indices by invoking thenextDouble()
method on the Random object.Generator.randomizer(new String[] {"tof", "utti", "magn", "etism", "edi", "fice", "gri", "nder", "groun", "dling", "thes", "aurus","bu", "ll"}, 0)
would return {"dling", "aurus", "edi", "tof", "fice", "gri", "magn", "ll", "bu", "utti", "nder", "etism", "groun", "thes"}.
-
public static String clueToString(String[] clues)
This method will create a string that will print out the clues. Each clue should be on it's own line with the user referenced number (i.e. first element is 1 as opposed to 0), followed immediately by a ')', followed by a space, and then the clue. If the clues array is null or empty, the method should return the empty string ("").
Example:
Generator.clueToString(new String[] {"a small bird", "common flavor"})
would return "1) a small bird\n2) common flavor\n". -
public static String boardToString(String[] board)
This method will create a string that will print out the board. Each slice should look like it is in a box. Each slice will be preceded and followed by a line of dashes as long as the slice plus an additional 9 dashes. The line with the slice will be as follows: a |, followed by a space, followed by the user referenced number (i.e. first element is 1 as opposed to 0) formatted as two digits, followed by a space, followed by |, followed by a space, and then the clue, followed by a space and then a final |.
Example:
Generator.boardToString(new String[] {"tof", "utti"})
would return
"------------\n| 01 | tof |\n------------\n-------------\n| 02 | utti |\n-------------\n".
Testing
This assignment requires you to use both of the testing techniques you have learned so far. TerminalUI.java
should be tested first using TerminalUIDriver.java
and test.in and test.exp files as in PA2. The driver code is provided for you below along with one test. Generator.java
should be tested using JUnit and your GeneratorTest.java file will be submitted as part of your submission. Note that the examples given in the method explanations above are provided in JUnit below. Don't forget to include tests for invalid inputs as described for each method.
You should test TerminalUI with several of your own tests, but included here is a pa4TUItest1.in and a pa4TUItest1.exp to give you one verified command-line test.
Below is a set of tests you may find helpful for testing Generator.java.
Assert.assertArrayEquals("Error in test1: wordSplicer", new String[] {"tof", "utti", "magn", "etism"}, Generator.wordSplicer(new String[] {"tofutti", "magnetism"})); Assert.assertArrayEquals("Error in test1: randomizer", new String[] {"dling", "aurus", "edi", "tof", "fice", "gri", "magn", "ll", "bu", "utti", "nder", "etism", "groun", "thes"}, Generator.randomizer(new String[] {"tof", "utti", "magn", "etism", "edi", "fice", "gri", "nder", "groun", "dling", "thes", "aurus","bu", "ll"}, 0)); Assert.assertEquals("Error in test1: clueToString", "1) a small bird\n2) common flavor\n", Generator.clueToString(new String[] {"a small bird", "common flavor"})); String actualBoard = Generator.boardToString(board); Assert.assertEquals("Error in test1: boardToString", "------------\n| 01 | tof |\n------------\n-------------\n| 02 | utti |\n-------------\n", actualBoard);
Playing the Game
When all of your methods are working you can test to see if you can run the SevenLittleWord.java file to play a round of the game. Here's a sample output.txt from my run of Tues Oct 23rd Daily puzzle.
Submission
This assignment has two parts that should be completed in order. By the first deadline you should submit TerminalUI.java
, Generator.java
(stubs that return the examples given above only), and GeneratorTest.java
(one test per method only). By the second deadline you must submit your completed code for all three TerminalUI.java
, Generator.java
, and GeneratorTest.java
through AutoLab.
Part A - Friday October 19, 11:00PM
Read this entire document and complete the code for TerminalUI.java
, the stubs for Generator.java
that return the examples above, and a version of GeneratorTest.java
that has at least one good test for each method. This submission cannot be late!. You must submit by the deadline to get any credit.
Part B - Friday October 26, 11:00PM
Upload your completed Generator.java
, GeneratorTest.java
, and your TerminalUI.java files through AutoLab.
- -15% before Saturday, 10⁄27 11:00 pm
- -30% before Sunday, 10⁄28 11:00 pm
- Not accepted after Sunday, 11:00 pm
You must implement the above in java, creating a file called TerminalUI.java
, Generator.java
and GeneratorTest.java
. Before uploading your files, be sure to complete carefully complete the steps below. If you are having trouble getting started, see the Hints section further below.
-
- Verify that your code is working. You should test it with several tests. Make sure you have complete code coverage from your JUnit tests.
- Make sure that all your variable names make sense and you are following coding conventions.
- Check that you have inserted the proper javadoc `@author` and `@version` comments in the appropriate header.
- Run Checkstyle and eliminate ALL warnings about your code.
Your submission will be graded using the following criteria:
Requirement | Points |
---|---|
PART A: TerminalUI.java | 10 |
PART A: Generator.java (stubs) | 5 |
PART A: GeneratorTest.java (100% coverage of stubs) | 10 |
PART A: Checkstyle | 5 |
PART B: Checkstyle | 5 |
PART B: Instructor grading based on style, code quality, comments. | 5 |
PART B: Loop with nested if-else statement (PromptNDisplayHints) | 5 |
PART B: While/do-while context loop (promptForString, promptForInt) | 10 |
PART B: Basic for context loop (clueToString) | 5 |
PART B: Pass arrays as method arguments and return values (wordSplicer) | 5 |
PART B: Manipulate, initialize, copy and compare elements of arrays of Strings (wordSplicer, randomizer) | 10 |
PART B: Generate random numbers based on an algorithm (randomizer) | 5 |
PART B: Use nested loops (boardToString) | 5 |
PART B: JUnit tests 100% coverage and passing | 15 |
Don't put off submission until the last possible minute! Any submission system may become bogged down when it receives a large number of submissions. You may have some unanticipated difficulties uploading your code. It is your responsibility to take these possibilities into account and submit early enough to ensure that the submission process is completed before the deadline. It is recommended that you submit once early, after you have a set of stubs completed, to make sure that you have all of the method and class definitions exactly right.
Hints
It would be wise to implement the code in the following order.
-
- Implement promptForInt in TerminalUI. Test it using your own main or the interactions pane in your IDE and make needed changes.
- Implement promptForString in TerminalUI. Test it using your own main or the interactions pane in your IDE and make needed changes.
- Test promptForInt and promptForString only using the TerminalUIDriver code by using a stub for promptNDisplayHints. Make needed changes.
- Implement and test promptNDisplayHints using the TerminalUIDriver. Make needed changes.
- Implement stubs only for GeneratorTest.java.
- Implement a single test at a time for each method in GeneratorTest.java, making sure each one compiles correctly with GeneratorTest.java
- Once you have 100% code coverage from your tests, submit to the submission system.
Going Further
Why did we use the colors above (input/output)?
Acknowledgments
This assignment was originally designed by Dee Weikle and Alvin Chao.