Snake
Overview
A. Goals
This is a closed-ended project that provides you the opportunity to apply everything you have learned in CIS 1100 to building a game of Snake. You are given a small bit of starter code that you can use to reach the first checkpoint for the assignment. After completing the first checkpoint, you will need to make choices to expand your codebase with additional methods, instance variables, and data structures. We highly recommend taking time to think through the structure of your project before you start coding past the first checkpoint.
Start early and reach out if you have any questions or concerns.
You may be tempted to use code directly from the internet or use such code as a base template. Please do not do so. We are adept at catching such cases and strict action will be taken. As discussed in lecture, LLMs can be helpful, if overly powerful, tools for helping you learn & program. Using LLMs like ChatGPT to generate code for you is explicitly not permitted in this assignment. Some uses that are permissable & might be helpful: asking ChatGPT to explain a high level Java concept to you, to explain compiler or runtime errors, or to explain/summarize code from a previous assignment or class example.
B. Project Structure & Checkpoints
In this assignment, you will implement the classic game of Snake. Your project must use object-oriented design. A basic skeleton for you to use is provided, but you will need to expand it eventually. You do not need to adhere to any fixed set of classes or methods, but be aware that exercising your ability to use & design objects is an explicit learning goal of the assignment. If you implement your entire project as static, with no object instances, you will lose significant points.
This is a challenging assignment that you will be completing during a very busy time of the semester; consequently, we want to make sure that you have a clear picture of what grade you can expect as you progress through the assignment. This will allow you to make informed choices about how best to budget your own time.
To that end, there are several checkpoints laid out in these instructions. Each states the grade that will be earned by successfully meeting the requirements for that checkpoint. You may choose to stop at any checkpoint, and it is strongly recommended that each time you successfully reach a checkpoint, you save a copy of your codebase at that time. That way, if anything breaks in your implementation, you have a guaranteed minimum grade to fall back on.
Please recall that you cannot drop this homework.
C. Snake
Please take some time to play an example implementation of the Snake game, like the one available here. Your game will not behave or look exactly like this one, but it will be similar.
Snake is a game played on a 2D board. After the game starts, the snake will always be moving in a cardinal direction. The player can change the direction in which the snake is moving by pressing the W, A, S, or D keys on the keyboard (corresponding to “up”, “left”, “down”, and “right”, respectively). The snake has a body comprising several segments. The first segment is the head, and the snake starts with a single segment. When the snake moves, the head moves one square in the direction the snake is moving, and the rest of the segments of the body move to occupy the space that the segment in front of them previously occupied. When the snake eats a piece of food, the snake grows by one segment. The game ends when the snake collides with itself or with a wall.
Planning
The structure of your solution is entirely up to you, but you will have to make a choice about how to represent the segments of the snake. Here are a few ideas about how you might proceed, and you should feel free to choose whichever of them seems most reasonable to you!
- Snake as array of segments
- Snake as list of segments
- Implement segments as Node-like structures, and implement snake as a chain of “segment nodes”.
- Choose not to make the snake consist of segments; instead, implement the game board as a 2D array with segments in specific cells.
Use these ideas as things to consider, but ultimately do whatever makes the most sense to you. This is a little bit of a leap of faith, but you can probably make it work independent of what structure you choose.
Checkpoint 1
The starter files on Codio are SnakeGame.java
, Board.java
, and Snake.java
. These files (copies of which can be found here) and the methods contained therein are the only ones that are needed to create a complete implementation of the first checkpoint. If you prefer to implement the project from the ground up on your own, that’s entirely acceptable as well—these starter files are intended to help you reach the first checkpoint more easily rather than to restrict you. Additionally, you may add methods to these classes and you may add any additional classes as you see fit. Probably you will find the first three classes sufficient for the first checkpoint, but you might find it helpful to write an additional method or two.
To meet the first checkpoint, your submission must meet all of the following requirements:
- When run, the program must display a window in which the game will be played.
- The game must be played on a reasonably sized board—at least 500 by 500 pixels.
- The snake should be initialized to be a single “segment” and should start the game somewhere visible on the board.
- The snake should start without moving—that is, the gameplay should not begin until the player presses a key.
- The snake should move in a cardinal direction when the player presses the corresponding key, and continue in that direction until the player presses a different key.
Throughout the assignment, you are welcome to leave the looks of the game very “barebones” or you may choose to make the game look nice. Either is fine, although submissions that have visible bugs in presentation (flickering shapes, inconsistent coloring, misaligned shapes, etc.) will lose points.
Things that are not required for this checkpoint, but will be addressed in future checkpoints:
- Handling “game over” states
- Any particular behavior for when the snake collides with a boundary of the board
- Any behaviors related to spawning food items or growing the snake
- Keeping score
- Any cosmetic features, such as colors or images
After this checkpoint, your game should look similar to this. This is just one valid implementation—it is not important that yours looks exactly the same in order to receive all of the points. The grading is based on the written items listed above.
(You have to click within the embedded game to get it in focus before pressing any keys.)
Submissions that meet all of these requirements will receive a completeness & correctness score of 10/40 points.
Checkpoint 2
To reach checkpoint 2, your program must meet the requirements for checkpoint 1. Points will not be awarded for any of the features in this checkpoint if you do not have the features from the previous checkpoint.
- After the game begins, a food item should appear somewhere on the board.
- The food item should be visually distinguished from the snake itself: different color, shape, or size.
- After the game begins, a readout of the player’s score should be visible somewhere along the perimeter of the board. At the start of the game, the player’s score will be 0. The score should be updated whenever the snake eats a food item.
- When the snake collides with the food item, two updates should happen:
- The food item should disappear and another item should immediately appear somewhere else on the board.
- The player scores an additional point, causing the score readout to update immediately.
The snake itself does not need to grow for this checkpoint.
After this checkpoint, your game should look similar to this.
(You have to click within the embedded game to get it in focus before pressing any keys.)
Submissions that meet all of these requirements will receive a completeness & correctness score of 15/40 points.
Checkpoint 3
This will likely be the most challenging checkpoint to complete.
To reach checkpoint 3, your program must meet the requirements for the previous checkpoints. Points will not be awarded for any of the features in this checkpoint if you do not have the features from the previous checkpoint.
- The snake should grow by one segment whenever it collides with a food item.
- The new segment should appear at the tail of the snake in the next frame drawn. Since the snake will have grown, the new tail will be in the same position that the old tail occupied in the frame when the food was consumed.
- The snake’s head should be visually distinguished from the rest of the snake’s body: using a different color, shape, or perhaps displaying a face.
- When the snake moves, the head moves one square in the direction the snake is moving, and the rest of the segments of the body move to occupy the space that the segment in front of them previously occupied.
- The snake should be prevented from reversing direction. For example, if the snake is moving left, the player should not be able to press the “D” key to make the snake turn around and move right.
When testing submissions for this checkpoint, we will not be testing for what happens if the snake collides with itself or with a wall. Those collisions will be tested in the next checkpoint.
After this checkpoint, your game should look similar to this.
(You have to click within the embedded game to get it in focus before pressing any keys.)
Submissions that meet all of these requirements will receive a completeness & correctness score of 25/40 points.
Checkpoint 4
To reach checkpoint 4, your program must meet all of the requirements for the previous checkpoints and must also meet all of the following requirements:
- The game should end if the snake ever collides with the boundaries of the board or with itself.
- When the game ends, the program should display a message indicating that the game is over.
- The message should include the player’s final score.
- The player should be able to restart the game when the game has ended by pressing a given key, at which point the game should reset to its initial state. Whichever key you choose is up to you, but make sure to make this clear while the game is running or report it in the README.
- It’s OK if the player can restart the game at any time, but the points are awarded for specifically restarting the game after a loss.
After this checkpoint, your game should look similar to this.
(You have to click within the embedded game to get it in focus before pressing any keys.)
Submissions that meet all of these requirements will receive a completeness & correctness score of 30/40 points.
Checkpoint 5
To earn the remaining ten points for completeness & correctness, you must choose to implement some combination of the remaining features. You cannot earn more than 10 additional points, meaning that there is no extra credit.
- Add a “hard mode”. In hard mode, the snake moves faster than in normal mode. The snake should move at least twice as fast in hard mode as in normal mode. The player should be able to toggle between normal and hard mode by pressing a key. The game should start in normal mode. (5 pts)
- Add bonus food items that are worth more points than regular food items. These should appear an random locations at random intervals. Eating one of these bonus food items should grow the snake by the regular length but add some extra number of points to the score. (5 pts)
- Add a title screen to the game that appears when the game is launched or restarted (3 pts).
- The player must press a key to start the game like normal, but the screen that the player sees at the start of the game must be different than just a “paused” snake game.
- Add a “high score” feature that keeps track of the highest score achieved in the current session. The high score should be displayed somewhere on the screen at all times. (2 pts)
- Add obstacles to the game board that the snake cannot pass through. These obstacles should be present somewhere other than on the edges of the board in order to earn points. (3 pts)
- Before the game starts, allow the user to press a key/button that removes the condition that the player loses when the snake collides with a wall. Instead, the Snake should “teleport” (like in Furious Fish), segment by segment, to the opposite side of the board. The player should still lose if the snake touches itself or another obstacle that you may have implemented. (2 pts)
- Allow the player to write their initials after each game over to save their score. Write these scores using
Out.java
so that this history is permanent and maintained between executions of the program. Either or both of the following extensions can be completed for points:- For 2 pts, allow the user to be able to press a key or navigate using a menu to see all saved scores in game. (2 pts)
- For 2 pts, display the top 5 scores (with the initials) on the title screen. (2 pts)
Submission
Submit all files necessary to run your game to Gradescope. You should also submit readme_snake.txt
in which you must write how to run your game and explain the features you may have selected for Checkpoint 5.