Corrections, clarifications, and other announcements regarding this programming assignment will be found in this section:
Unlike the classic board game Battleship, which is purely guesswork between two players, the BattleSweeper game you're about to design and implement is a one-person logic puzzle. The player is given a grid of cells and the number of cells in each row and column which contain a ship (or a portion of a ship). With that information and a few revealed squares, it's possible to reason out the exact location of every ship on the board.
Objective: Find all of the ships in puzzle grid. Play starts after the user selects a puzzle from the Play a puzzle
menu item. Menu descriptions follow this section.
The play of a particular puzzle starts with the display of a grid of characters representing the intial board condition. Initially, most of the cells are unknown and marked with '?
' character. The numbers on the top and side of the grid tell you how many ship pieces are in that row or column. Ships are only aligned horizontally or vertically - no diagonal ships. Also, ships never touch each other, horizontally, vertically, nor diagonally.
The numbers on the top and right side of the board indicate how many ship pieces are in those columns and rows. The letters on the left and bottom of the board are for the user's reference while playing - the user will enter a row/column combination by typing in the letters that correspond to the cell they wish to access.
The contents of the cells will be as follows:
Let's walk through how you'd play the game after the user loads a puzzle and selects that puzzle to play.
Here's a sample initial board setup:
Since row d
and column i
both have 0 ship parts, they must be entirely water. Enter each row,column location and set to water. Once all locations in row d
and column i
have been set to water, the board looks like this:
Since row f
and column k
have only 1 ship part, which is already shown at f,k
, the rest of f
and k
must be water. After setting the remaining locations in row f
and column k
to water, the board looks like this:
Because ships cannot be adjacent diagonally, the cells e,j
and e,l
must be water. After setting those locations, the board looks like this:
Row a
and column j
each have three ship parts in them and only three unknown cells, so they must all be ships. After setting those locations to [s
]hip, the board looks like this showing S
where any ship part was set:
Row b
and column l
each have one ship part in them already, so the rest of b
and l
must be water.
At this point, the rest of the unknown cells must be ships, so we fill them in and the puzzle reveals itself as correctly solved!
Because implementing a single BattleSweeper puzzle does not require all of the programming skills we wish you to learn, you'll be implementing a program that can also read and write files and save information about the players who play the game.
At the start, your BattleSweep program will:
The main menu and user prompt should look like this:
=== BATTLESWEEPER MAIN MENU === 1. List player information 2. Load a new puzzle 3. Play a puzzle 4. Quit >
The > below the menu is a very simple user prompt. The user typed the number of their selection after the prompt. If they make an invalid choice, simply display the prompt again (no error message necessary).
=== BATTLESWEEPER PLAYERS === HBS: puzzle1 puzzle2 DEB: puzzle1 puzzle3 JIM: puzzle2 puzzle1 puzzle3 BEC: puzzle2This menu option screen is purely informational (and has no prompt), and is laid out as follows:
=== BATTLESWEEPER PLAYERS === IN1: <puzzle> <puzzle> ... IN2: <puzzle> <puzzle> ... IN3: <puzzle> <puzzle> ... ... IN4: <puzzle> <puzzle> ...
It is a list of the player information. For each player that solved a puzzle, the players' intitals, followed by a colon :
character, followed by a space-separated list of the names of the puzzles they have solved.
The players in this list should be in the order that they first solved a puzzle, and the puzzle list for each player should be in the order that the player first solved those puzzles. Note: if a player solves the same puzzle multiple times, it should only appear ONCE in the player's puzzle list.
If no players have solved any puzzles yet, just display the === BATTLESWEEPER PLAYERS ===
header.
=== BATTLESWEEPER PLAYERS ===
Once the player information has been displayed (or not), return to the main menu (don't wait for user input).
=== LOAD A PUZZLE === Enter a filename: puzzle4.txtThe user enters the name of a file with a valid puzzle data configuration. The user input shown is: puzzle4.txt . The program then attempts to load the file as a new puzzle. If the file is found and the puzzle configuration is read successfully, return to the main menu.
=== BATTLESWEEPER PUZZLES === 1. puzzle1 2. puzzle2 3. puzzle3 4. Go Back > 1Again, the > is your prompt and the 1 shows an example of the user's input. In this case, the game has three puzzles loaded, from files named puzzle1.txt, puzzle2.txt, and puzzle3.txt (so a puzzle's name is simply everything that comes before ".txt" in its filename).
=== BEFORE YOU GO! === Enter player history filename:If the user enters nothing (or a file name that can't be written to), exit the program without saving the current player information to a file. Otherwise, write the menu screen from option 1 to the file the user specifies, and then quit.
You've been doing menus since P1, so that all should be easy. The file loading will be a bit more challenging. For reference, let's use the file puzzle1.txt, which corresponds to the puzzle solving demonstrated in the Game Play section above and in the example below.
All puzzles are played on a 6x6 board. To keep things simple, the puzzle files have a very specific format (and all valid puzzle files will have this format, so don't worry about checking it): For example, puzzle1.txt contains the following:
puzzle1.txt File Example | Interpretation of the Puzzle File Format |
---|---|
a,g a,l f,k c,g c,h e,g e,h a,j b,j c,j 2 a,h f,k |
[ship location] [ship location] [ship location] [ship location] [ship location] [ship location] [ship location] [ship location] [ship location] [ship location] [how many cells are revealed] [revealed location] [revealed location] ... |
There will always be exactly six (6) ships but there may be any number of cells displayed to the user.
Do not make any assumptions about the ordering of the provided information outside of the type of information provided in a line (for example, we do not guarantee that the ships or revealed locations will be listed from upper left to lower right).
Once you've loaded a puzzle correctly, it should be available to the user for play the next time they choose Play a puzzle
from the main menu. Again, the initial board for puzzle1.txt should look like:
Prompt your player with Row,column or (q)uit: (Note: you may assume correct input at this point. If you wish to implement input checking for your own benefit, you may, but this behavior will not be tested). Once they've specified a location, ask whether they wish to place water or a ship at that location:
However, if your player tries to change one of the initially-revealed cells, don't let them and display the message: That location is fixed!
:
If your player tries to do something illogical, don't judge them! Let them make their own mistakes:
A puzzle should be considered complete when the user has entered a guess for all of the cells (that is, no ? remain). If the user has correctly solved the puzzle, you should display all the ships in their correct configurations and print Congratulations!:
Once the puzzle has been solved successfully, prompt the user for their initials (Enter your initials: ) and transform their input to UPPER CASE (if a word longer than three characters is input, use only the first three characters). If a player with that name does not exist, create a new player with that name and add this puzzle to their list of solved puzzles. If a player with that name does exist, add the current puzzle to the list of solved puzzles for that player (but only if that puzzle is not already included in their solved puzzle list).
Note that at any time during the game, the user can give up by entering q
. This should reveal the puzzle's solution and print Quitter.
instead of Congratulations!
, and return to the main menu without asking for the user's name.
If the grid is full so the puzzle is complete but the player has NOT solved the puzzle correctly, change any cells that the user incorrectly guessed to E, and print Oh no... and return to the main menu. The player must play the puzzle again to solve.
THIS OPTION WILL NOT BE TESTED. If you know a whole row or column is going to be water, it can be tedious to go through and change every cell to water individually. If you choose to, you may implement an option for the Row,column prompt that accepts a single character and then confirms with the user that they wish to convert the entire row or column to water:
We won't be testing this behavior, but it can make playing the game a bit more enjoyable :)
NOTE: Your main class must be named BattleSweeper.java.
The design of this program is entirely up to you, and we won't be providing any code skeletons. Your design should follow encapsulation principles (for example, don't have public instance variables - use accessor methods). However, if you're stuck on how you want to implement the program, maybe these suggested classes will get you started:
Player.java
Store information about the players using your program.
Puzzle.java
Store information about the puzzles your users can solve.
BattleSweeper.java
Must have a main method, but you may find some benefit to making this class instantiable. It could store information about the current state of the BattleSweeper programs.
Since we don't provide any skeleton, the documentation is entirely of your creation. Hint: Use the examples from Programs 3,2,1 to help you get started.
We suggest that you incrementally develop this program by following the milestones in the order listed below. This order will make it easy for you to check that each milestone is working properly before you move on to the next one. Don't move on to a new milestone until you can convince yourself that the current milestone is working correctly. The further along you get, the harder it will be to detect errors in code you developed early on.
BattleSweeper
. Add code to display main menu and accept user input to choose a menu option. Implement the quit option without worrying about the file output. sample-runs/milestone0.txt
sample-runs/milestone1.txt
(Note: after this sample run, your directory will contain a file called player_output.txt
with contents identical to this.)player_input.txt
sample-runs/milestone2.txt
(Note: this sample run uses the file puzzle4.txt
)sample-runs/milestone3.txt
(Note: this sample run uses the optional row-fill behavior. Those steps are equivalent to individually setting all remaining unknown cells in a row or column to water.)sample-runs/milestone4.txt
Before handing in your program, check that you've done the following:
Use the CS302 Forms Page to electronically submit and backup your work:
Submit these files:
As stated in the assignment goals, to receive full credit, you must have implemented and used AT LEAST TWO instantiable classes to complete this assignment.