Big Program 1: Sokoban
In this assignment, you will create a text-based Sokoban (Wikipedia: Sokoban) program. Sokoban is a classic puzzle game from the early days of personal computers. You are a warehouse worker and you have to move boxes to particular locations in a warehouse. The boxes are heavy and you can only push them.
A sample run of the finished program (interleaved input and output): SampleFinal.txt
As shown in the sample run above, the worker (denoted by ‘@’) is shown in a warehouse with impassable walls (denoted by ‘#’). The worker must cover each goal (denoted by ‘.’) with boxes (denoted by ‘=’). The worker can only push the boxes… so you have to navigate the warehouse carefully or you will get stuck! When a box is placed on a goal, the symbol in the sample run is ‘*’. If the worker is standing on a goal, the symbol ‘+’ is used. The exact characters to use will be specified in the Config.java file. So, your program should always use the constant variable and not the literal character.
Grading Scheme: GradingBigPrograms.pdf – Be sure to read this fully.
Row-major order: In the design of this program, we will view the arrays as row-major order. For a 2-d array,
this means that the first dimension represents the rows and the second dimension represents the columns.
Files: Sokoban.java, Config.java and TestSokoban.java are provided.
- ● Sokoban.java — Contains all the methods (as stubs) necessary for all three milestones of this program.Detailed method headers are provided for you in the file. The implementation of each method must
meet the detailed descriptions in the method headers. Do not change the method headers!
- ● TestSokoban.java — Contains a framework for your test bench.
- ● Config.java — Whenever you need these values, use the constants defined in Config.java. The testingmay use different values for these constants. BP1 Team
Students who wish to may work with at most one pair programming partner on Big Program 1.
- Both students must read the Pair Programming Rules and Guidelines.
- Both students must individually fill out the TEAM FORM requesting the other as their partner.
A. To use the above form, you need to be logged into the google account that is associated with your UW Netid. If you see the message “Y ou need permission” when following the link above, please 1) direct your browser to google.com 2) click on the profile icon in the upper right corner of the screen and choose sign out, 3) then click “Sign In” and use the link “Sign in with a different account” link at the bottom of the following screen, 4) from there you can “Add an account” and use your netid-based wisc.edu email address to login to google. Doing all of this should allow you to subsequently access the Team Form linked to above. Please report any further problems on piazza for troubleshooting assistance.
- The TEAM FORM must be filled out before 6:00 pm on Thursday, Oct 25th (when Milestone 1 is due).
- Both students must submit the team code to their own zyBooks account for grading. Formilestone 3, from zyBooks, we will pick one partner’s copy of the program to human grade and assign
both partners the same grade.
- We suggest finding a partner at about your same programming knowledge and skill level.
- We recommend working closely together (Pair Programming), not dividing up by milestones or steps.The assignment is designed to be progressive, each step building the previous. If you skip a step, it
may be difficult to continue. Work closely together, discussing as you go.
Students are not required to work with another student on Big Program 1.
Project designed by Marc Renault.
Last update: 2018-10-08 1 of 7
Milestone 1: Basic Interface and Supporting Methods.
- Create a new project in Eclipse. (Sokoban would be a sensible choice for the project name.)
- Download Config.java, put in your project src folder and review the contents to become familiar with theconstants.
- Understand the data structure: Before you start coding make sure you understand the array datastructures in Config.java.
- Create a new file called MyLevels.java containing the class MyLevels (use Config.java as aguide).
- In the MyLevels class, define a LEVELS and a GOALS constant similar to Config.java. Topopulate the LEVELS array, you will use the constants defined in Config.java.
- Using your LEVELS and GOALS constants, create 3 new valid Sokoban (pass the checkLevelchecks) levels that are (in order) at least 3 by 3 with 1 goal, 6 by 6 with 2 goals and 9 by 9 with 3 goals. Since the arrays stored in LEVELS can be ragged, the minimum number of columns means that at least one row should contain that number of columns. At the minimum, the 9 by 9 should be a ragged array.
- Download Sokoban.java and TestSokoban.java and save them in your project src folder.
- Best practice: Start by writing the tests.
- Add at least 2 more tests to the testCheckLevel method. (Ideally, you would test every possible return value.)
- OPTIONAL: This is not required for the BP1 assignment, but ideally you would also create test methods for promptInt, p romptString,and promptChar. These methods require a Scanner object. To do the automated testing, you can create a Scanner object from a String.
- In this milestone, you will implement the methods: checkLevel, promptString, promptChar, and promptInt. The suggested approach is as follows:
- First implement checkLevel.
- Use the test bench to check your method.
- Once it passes your test bench, submit to zyBooks to see if you pass zyBooks test 1.
- Then, implement promptString, promptChar, and promptInt.
- First implement checkLevel.
- With the supporting methods written, you can write the basic main method with a play again loop. For Milestone 1, an algorithm for the main method is:
Print out “Welcome to Sokoban!”
Begin the play again loop- ● Call promptInt for the “Choose a level between 0 and maxLvl: ”, where maxLvl is the maximum index in Config.LEVELS. The minimum value should be 0 and the maximum value should be maxLvl.
- ● Check the level selected by the user using your checkLevel method.
- ● If the level is valid, print out “Sokoban Level lvl” , where lvl is the level selected by theuser.
- ● Prompt the user with “Play again? (y/n) “, using the promptChar method.Exit the loop if the value of promptChar is not a ‘y’
Print out “Thanks for playing!”
- Submit your Sokoban.java, T estSokoban.java and MyLevels.java files to zyBooks for feedback andgrading. We recommend you complete commenting and styling your code for each milestone as described in the Program Grading section of this document. Your highest scoring results prior to
Project designed by Marc Renault.
Last update: 2018-10-08 2 of 7
6:00pm or (11:59pm with a 10% deduction) Thursday, October 25th will be recorded as your grade for this weekly milestone.
Note: We may use different values in the Config.java for testing.
Milestone 1 Sample run: Milestone1.txt (interleaved input and output) [Milestone1In.txt, Milestone1Out.txt]
Project designed by Marc Renault.
Last update: 2018-10-08 3 of 7
Milestone 2: Printing and Using the Levels
- Best practice: Start by writing the tests.
- Add at least 1 more tests to the testInitBoard method.
- Using the testCheckLevel and testInitBoard methods as templates, update the testmethod stubs testCheckWin, testCalcDelta, and testCheckDelta by adding at least
1 test to each test method.
- In this milestone, you will implement the methods: initBoard, checkWin, calcDelta,checkDelta and printBoard. The suggested approach is as follows:
- First, implement printBoard.
- Then, implement initBoard.
- Use the test bench to check your method.
- Once it passes your test bench, submit to zyBooks to see if you pass zyBooks test 1.
- Then, implement checkWin, use the test bench to check your method, and submit to zyBooks to see if you pass zyBooks test 2.
- Then, implement calcDelta, and checkDelta, use the test bench to check your methods, and submit to zyBooks to see if you pass zyBooks tests 3 and 4.
- For Milestone 2, an algorithm for the main method is: Print out “Welcome to Sokoban!”
Begin the play again loop- ● Call promptInt for the “Choose a level between 0 and maxLvl: ”, where maxLvl is the maximum index in Config.LEVELS. The minimum value should be 0 and the maximum value should be maxLvl.
- ● Check the level selected by the user using your checkLevel method.
- ● If the level is valid:○ Initialize the board and worker position by calling initBoard.
○ print out “Sokoban Level lvl” , where lvl is the level selected by the user. ○ Begin the game loop:- Print the board using your printBoard method.
- Prompt the user with “: ”, using the promptString method.
- If the user inputs no value, then loop again.
- If the user inputs Config.QUIT_CHAR, then exit the loop.
- Otherwise, call calcDelta using the value entered by the user and exit the loop.
- ● Prompt the user with “Play again? (y/n) “, using the promptChar method. Exit the loop if the value of promptChar is not a ‘y’
Print out “Thanks for playing!”
- Submit your Sokoban.java and T estSokoban.java files to zyBooks for feedback and grading. We recommend you complete commenting and styling your code for each milestone as described in the Program Grading section of this document. Your highest scoring results prior to 6:00pm or (11:59pm with a 10% deduction) Thursday, November 1st will be recorded as your grade for this weekly milestone.Note: We may use different values in the Config.java for testing.
Milestone 2 Sample run: Milestone2.txt (interleaved input and output) [Milestone2In.txt, Milestone2Out.txt]
Project designed by Marc Renault.
Last update: 2018-10-08 4 of 7
Milestone 3: Playing the Game
1. Best practice: Start by writing the tests.
a. Using the testCheckLevel and testInitBoard methods as templates, update the test
method stubs testTogglePos, testShiftBox, testDoMove, and testProcessMove by adding
at least 1 test to each test method.
- In this milestone, you will implement the methods: togglePos, shiftBox, doMove, andprocessMove. The suggested approach is as follows:
- First, implement togglePos, test, then submit to zyBooks to see if you pass zyBooks test 1.
- Then, implement shiftBox, test, then submit to zyBooks to see if you pass zyBooks test 2.
- Then, implement doMove, test, then submit to zyBooks to see if you pass zyBooks test 3.
- Then, implement processMove, test, then submit to zyBooks to see if you pass zyBooks test4.
- With the supporting methods written, you can update the main method to play the game. For Milestone3, an algorithm for the main method is: Print out “Welcome to Sokoban!” Begin the play again loop
- ● Call promptInt for the “Choose a level between 0 and maxLvl: ”, where maxLvl is the maximum index in Config.LEVELS. The minimum value should be -1 and the maximum value should be maxLvl.
- ● If the user enters in -1, choose a level from Config.LEVELS uniformly at random.
- ● Check the level selected using your checkLevel method.
- ● If the level is invalid, print “Error loading level!” followed by a newline, followed by theerror message that corresponds to value returned by checkLevel: Let lvl b e the level selected:
Value |
Error Message |
0 |
Level lvl must be 0 or greater! |
-1 |
Error with Config.LEVELS |
-2 |
Error with Config.GOALS |
-3 |
Level lvl does not contain any boxes. |
-4 |
Level lvl does not have the same number of boxes as goals. |
-5 |
Level lvl has a goal location that is a wall. |
-6 |
Level lvl has 0 or more than 1 worker(s). |
-7 |
Level lvl contains duplicate goals. |
Any other value |
Unknown Error |
Project designed by Marc Renault.
Last update: 2018-10-08 5 of 7
● If the level is valid:
○ Initialize the board and worker position by calling initBoard.
○ print out “Sokoban Level lvl”, where lvl i s the level selected. ○ Begin the game loop and loop until checkWin is true:
■ ■ ■ ■ ■
Print the board using your printBoard method.
Prompt the user with “: ”, using the promptString method. If the user inputs no value, then loop again.
If the user inputs Config.QUIT_CHAR, then exit the loop. Otherwise:
● call calcDelta using the value entered by the user. ● If the calculated delta is valid:
- ○ Call processMove with that delta
- ○ Add the number of moves in the calculated delta to a counter
subpanelvariable.
user won the game, print “Congratulations! You won in xNum
○ If the
moves!”, where xNum is the number of moves counted during the game loop, followed by the board (using your printBoard method).
● Prompt the user with “Play again? (y/n) “, using the promptChar method. Exit the loop if the value of promptChar is not a ‘y’
Print out “Thanks for playing!”
4. Submit your Sokoban.java and T estSokoban.java files to zyBooks for feedback and grading. We recommend you complete commenting and styling your code for each milestone as described in the Program Grading section of this document. Your highest scoring results prior to 6:00pm or (11:59pm with a 10% deduction) Thursday, November 8th will be recorded as your grade for this weekly milestone and used for the human grading.
Note: We may use different values in the Config.java for testing.
Milestone 3 Sample run: SampleFinal.txt (interleaved input and output) [SampleFinalIn.txt, SampleFinalOut.txt]
Project designed by Marc Renault.
Last update: 2018-10-08 6 of 7
Appendix
Debugging Tips
- ● Write your tests first!
- ● Compile, run tests and run the program often! Think about doing this with each code change and eachcompleted method.
- ● Do your tests cover a breadth (ideally all) of possible scenarios?
- ● Do your tests check the boundary or edge cases?
- ● Do your tests cover valid, but unexpected, inputs?
- ● Make use of print statements!
- ● Have you gone through the tips on the CS Website: https://cs200-www.cs.wisc.edu/wp/help/#TipsExtensions
The are many ways your might consider improving this Sokoban program. If you are interested in pursuing these extensions or others that you might think of, please submit your fully completed Milestone 3 before attempting any extensions. The instructional staff would be happy to review your extensions with you or answer questions regarding extensions, but do not submit your extensions.
Change Log
● Initial version: 2018-10-08
Project designed by Marc Renault. Last update: 2018-10-08
7 of 7