Skip to content

Homework 6: Scrabble Saver

Congratulations on your Scrabble Game prototype! It may be simple, but it's functional. With further proficiency in Java, we can enhance it even more! For instance, we could implement a two-dimensional array for the board, allowing words to be formed in horizontal, vertical, and diagonal directions. Additionally, incorporating a Graphical User Interface (GUI) would make the game more visually appealing, akin to commercial games.

In our upcoming HW6 assignment, rather than focusing on the board's two-dimensional array or creating a GUI, you'll leverage the file I/O skills you've recently acquired to improve Scrabble.

Upon exiting the game, the user will have the option to save the game's status locally. Then, when the user resumes playing next time, loading the saved game will be possible. Of course, starting a new game from scratch will always remain an option.

In this homework, your objective is to implement a ScrabbleUtility class that contains two static methods: one for saving the current state of the game, and another for loading a previously saved game.

Soft Submission Limit

You are limited to 10 Gradescope submissions for HW 6, after which, any additional submissions will incur a 2 pt penalty each.

You are required to submit tests for the ScrabbleUtility class with 100% coverage.

Important

You will need to create a hw6 folder in your CS159/src/hws folder. The ScrabbleUtility class and the ScrabbleUtilityTest class must be defined in the hws.hw6 package.

Please review the Grading Criteria at the end of this page before you start programming.

Submission

You will submit only two files: ScrabbleUtility.java, ScrabbleUtilityTest.java

Please do not submit any other files.

Learning Objectives

After completing this homework, you should be able to:

  • read from and write to the file system (i.e., file input and output)
  • write and test static methods

This assignment must be completed individually. Your work must comply with the JMU Honor Code. Authorized help is limited to general discussion on Piazza, the lab assistants assigned to CS 159, and the instructor. Copying code from someone else or giving code to someone else, including the use of generative AI, is prohibited and will be grounds for a reduced or failing grade in the course.

Getting Started

We've provided some files that you will need to complete this homework. First, follow the steps below to make sure you have downloaded all the files and put them in the correct location.

HW5 required files

You will need all files from HW5. If you haven't already, download Scrabble.jar and words.txt.

Importing Letter, Board, EnhancedHand

Since you will need to use Letter, Board, and EnhancedHand classes in ScrabbleUtility class, you must first import them.

Assuming that you have your Letter class from HW4 in the correct hw4 folder, and have the Board, and EnhancedHand classes from HW5 in the correct hw5 folder. You should be able to put proper import statements before the class declaration in ScrabbleUtility.java.

If you have not completed Letter.java, Board.java, or EnhancedHand.java, please contact your instructor.

PlayScrabble2.java

Download PlayScrabble2.java and put it in your CS159/hws/hw6 folder.

After you've successfully implemented the ScrabbleUtility from HW6, you can now enjoy an interactive game of Scrabble by running PlayScrabble2.java! Furthermore, you have the option to save your game progress before exiting and even load a previously saved game.

UML Diagram

Note that Letter, EnhancedHand, Board, and WordsUtility are included in this diagram for completeness. You do not need to implement these classes for this assignment. You should implement the two static methods in the ScrabbleUtility. Note that saveScrabble and readScrabble should throw FileNotFoundException but not handle it.

classDiagram
  class EnhancedHand {
    +MAX_SIZE: int = 8$
    -hand: Letter[]
    +EnhancedHand()
    +EnhancedHand(size: int)
    +EnhancedHand(otherHand: EnhancedHand)
    +getSize() int
    +getLetter(index: int) Letter
    +insert(letter: Letter, index: int)
    +remove(index: int) Letter
    +indexOf(letter: char) int
    +toString() String
  }

  class Letter {
    -letter: char
    -points: int
    +Letter(letter: char, points: int)
    +setLetter(letter: char)
    +setPoints(points: int)
    +getLetter() char
    +getPoints() int
    +equals(other: Object) boolean
    +toString() String

  }

  class Board {
    -entries: Letter[]
    -pointMult: int[]
    -words: ArrayList<String>
    +Board(multiplier: int[], wordsPath: String)
    +Board(board: Letter[], multiplier: int[], wordsPath: String)
    +setEntries(entries: Letter[])
    +getEntries() Letter[]
    +getLetter(index: int) Letter
    +getLetterScore(index: int) int
    +getPointMult(index: int) int
    +play(letter: Letter, index: int) boolean
    +readBoardWord() String
    +wordValidation(word: String) boolean
    +getBoardScore() int
    +toString() String
  }

  class WordsUtility {
    +readWords(filename: String) ArrayList<String>$
  }

  class ScrabbleUtility {
    +saveScrabble(fileName: String, board: Board, hand: EnhancedHand)$
    +readScrabble(fileName: String, board: Board, hand: EnhancedHand)$
  }

EnhancedHand -- Letter
Board -- Letter
Board -- WordsUtility

EnhancedHand -- ScrabbleUtility
Board -- ScrabbleUtility
ScrabbleUtility -- Letter

style Letter stroke:#f00,line:#f00,fill:#aaaaaa22
style Board stroke:#f00,line:#f00,fill:#aaaaaa22
style EnhancedHand stroke:#f00,line:#f00,fill:#aaaaaa22
style WordsUtility stroke:#f00,line:#f00,fill:#aaaaaa22

ScrabbleUtility.java

ScrabbleUtility is a utility class that can be used to read/write Board and EnhancedHand information from/to the file system. The file format is a simplified comma-separated-values (CSV) format, in which values are delimited by a comma, and a newline (\n) character is at the end of each line.

For example, if entries in a Board object contained letters like

[null, h:0, p:4, null, null, null, null, null]
and hand in an EnhancedHand object contained letters like
[e:0, l:1, null, z:3, null, d:3, s:4, o:1]
the CSV file would be as follows:
board:
-,h:0,p:4,-,-,-,-,-,
hand:
e:0,l:1,-,z:3,-,d:3,s:4,o:1,

Help Using a Scanner or a BufferedReader

If you choose to use a Scanner or a BufferedReader, you will read an entire record (including the newline character) using the readLine() method. You can then tokenize the record using the split() method in the String class (passing "," as the delimiter).

In addition to the specifications contained in the UML class diagram, this class must conform to the following specifications.

  1. All objects used for reading and writing must be closed when they are no longer needed.

  2. The readScrabble() method must read a file written by the saveScrabble() method and set up the Board object attribute and the EnhancedHand object attribute.

Unit Testing

You must write JUnit tests for the ScrabbleUtility class. Your tests must cover all statements and all branches in the ScrabbleUtility class you write.

“round trip” testing

To test the read methods in your ScrabbleUtility class, you should create a JUnit test that first executes the appropriate write method and then executes the appropriate read method. This type of testing is often referred to as "round trip" testing of input/output.

It's important to note that the write and read operations must be in the same JUnit test to ensure that the write happens before the read. You can and should have multiple tests of this kind, but each test must be independent of the others.

Grading Criteria

Your code will first be graded by Gradescope and then by the professor. The grade you receive from Gradescope is the maximum grade that you can receive on the assignment.

After the due date, the professor may manually review your code. At that time, points may be deducted for inelegant code, inappropriate variable names, bad comments, etc.

Your code must compile with the official tests and pass a Checkstyle audit for you to receive any points. For full credit, your code must pass all JUnit tests that you submit, and your JUnit tests must cover every line in your code.

Gradescope will provide you with hints but might not completely identify the defects in your submission. You are expected to test your own code before submitting.

Criterion Points Details
Compile 0 pts Success Required
CompileOfficialTests 0 pts Success Required
Style 0 pts Success Required
SelfTests 10 pts Partial Credit Possible
Coverage 20 pts Partial Credit Possible
OfficialTests 70 pts Partial Credit Possible