Click here to Skip to main content
15,886,919 members
Please Sign up or sign in to vote.
1.00/5 (2 votes)
See more:
Problem A. (12 points) Getting Started

To get you started, we’ll give some pretty detailed instructions for the first few steps of the project: hopefully you can extrapolate from those steps to figure out how to proceed in parts B, C, and D as well.

Our first task is to set up classes to represent the entities that need to be manipulated for the game. One reasonable division of functionality is to have one class for the snake(s), and another overarching class for the game as a whole.

We’ll begin with the Game class. For now, all the Game class is going to do is draw the board and call a bunch of turtle functions that ensure that the turtle graphics are running as fast as possible. Copy-paste the following code into your hw13.py file:

Python
import turtle, random

class Game:
def __init__(self):

#Setup 700x700 pixel window
turtle.setup(700, 700)

#Bottom left of screen is (-40, -40), top right is (640, 640)
turtle.setworldcoordinates(-40, -40, 640, 640)
cv = turtle.getcanvas()
cv.adjustScrolls()

#Ensure turtle is running as fast as possible
turtle.hideturtle()
turtle.delay(0)
turtle.speed(0)

#Draw the board as a square from (0,0) to (600,600)
for i in range(4):
    turtle.forward(600)
    turtle.left(90)

Game()


When you run the program, it should produce a turtle graphics window that resembles the one shown below:

Next, we’re going to create a Snake class that represents one of the snakes involved in the game.

Snake.__init__(self, x, y, color) should take in three arguments aside from self: x and y are integer arguments representing the current position of the square forming the head of the Snake, and color represents the color of the Snake.

The constructor should create instance variables self.x, self.y, and self.color and initialize them each to the value from the appropriate parameter. It should also create self.segments, which should be set to an empty list. This list will eventually store the square segments that make up the snake, each of which will be a turtle object.

To produce each segment, create another method called grow(self). This takes in no arguments (other than self), and creates a new head segment for the snake at the current position - we’ll call this each time the snake grows.

grow should do the following:

(The hyperlinks below link to the Python documentation for the turtle module - if you’re unsure what the documentation is saying, ask your TAs.)

Create a turtle object using the constructor turtle.Turtle(). Assign this to some variable (say, head, since this will represent the head of the Snake).

Set the turtle object’s speed to 0. You must use the turtle object you created in the last step - if you typed out turtle.speed(0), you’re not using the turtle object.

Set the turtle object’s fill color to self.color.

Set the turtle object’s shape to 'square'

Set the turtle object’s size to 1.5 times normal in both width and length

Set the turtle object’s pen state to up.

Set the turtle object’s position to self.x, self.y

Append the turtle object to the end of the self.segments list.

You should put a call to self.grow() at the end of __init__ so that the snake starts out with one segment.

To test the Snake class, create a Snake object called self.player (representing the snake that the player controls) at the end of Game.__init__, with x = 315, y = 315, color = 'green'. You should see something like this:

Next, we’ll get the snake to start moving. To start, we’ll create a game loop - a function that calls itself at a set interval to keep the game moving. Create a method gameloop(self) within the Game class that does nothing but print out "In gameloop", and then calls turtle.ontimer(self.gameloop, 200).

If you add a call to self.gameloop() at the end of the __init__ method, you should see "In gameloop" print out roughly once every 200 ms.



Now, create a method move(self) in the Snake class that increases self.x by 30, and then moves the head of the snake (that is, the turtle object at index -1 of self.segments) to the updated position self.x, self.y.

Change Game.gameloop to call the move method on the player’s Snake object instead of printing out “In gameloop” every 200 ms. You should see the green square start to move 30 units to the right every 200 ms or so, until it eventually leaves the screen.

The last thing we’ll go over in detail is how to get the snake to change directions. First, we’ll need to add two instance variables to Snake.__init__ to represent the snake’s current velocity. Call these self.vx and self.vy, and initialize them to 30 and 0, respectively. Now, alter the move method so that rather than always adding 30 to self.x, we increase self.x by self.vx, and self.y by self.vy at each step.

This shouldn’t actually change anything just yet, since self.vx is set to 30 and self.vy is set to 0, so it should still just start moving right by 30 pixels every 200 ms or so.

Add a method called go_down(self) to the Snake class. All this method should do is set self.vx to 0 and self.vy to -30. Try calling this method at the end of Snake.__init__ - your snake should start moving down initially rather than to the right.



Once you’re certain that the go_down method works as intended, remove the call from the end of Snake.__init__ - we do want the snake to initially start by moving right, but we want it to start moving down when the user presses the down arrow key.

To do this, add the following three lines of code to the end of Game.__init__:
Python
turtle.onkeypress(self.player.go_down, 'Down')
turtle.listen()
turtle.mainloop()


This binds the go_down method to run on the self.player object every time the down arrow key is pressed, and then sets up the turtle graphics window to listen for keyboard input. Note that on some systems you may need to click on the turtle graphics window before it starts paying attention to your key presses.

Your snake should now initially move right but start moving down if the down arrow key is pressed.

Follow the same process to bind the left, up, and right arrow keys so that you can move the snake in all four directions (you don’t need to use .listen / .mainloop again, just .onkeypress).

For the remaining parts of the assignment, we’ll provide minimal guidance - you need to implement the required features but you can choose how to approach the task.

Problem B. (12 points) Food

Implement a red, circular food pellet that’s placed in a random position aligned with the grid. If the snake’s head moves into the same space as the food pellet, the snake should grow by one segment, and a new food pellet should appear in a random grid-aligned position. You will need to adjust the move method so that when the snake grows, each segment follows the head.

Hints:

15 + 30*random.randint(0,19) will select a random grid-aligned x or y-coordinate for the food pellet (we need to add 15 because we want the object to be in the middle of the grid space).

It may be useful to create a separate class for the food pellet and make a method that causes it to move to a random grid-aligned position - this way you can call that method when it’s first created, and each time the snake eats it.

You may want to change Snake.move to take in the food pellet as an additional parameter so that you have the ability to check whether the snake is going to hit it.

There are two cases to handle for moving the snake:

If the snake would move into a spot that contains food and grow, just add a new head segment and don’t move any of the existing segments.

Otherwise, loop through every segment in the list except the last one (the head), and move it into the position of the segment after it. Then, move the head to the new self.x and self.y as before.

Problem C. (6 points) Game Over

The game should end if either of the following two things occur:

The player snake goes outside of the bounding box. (Remember, this is a square that spans from (0, 0) in the lower left, to (600, 600) in the upper right).

The player snake runs into itself (the head of the snake is in the same space as one of the other segments).

If this occurs, the snake should stop moving and the words “Game Over” should be written somewhere on screen. You can use turtle.write to accomplish this.

Hints:

To stop the game, you need to prevent Game.gameloop from calling itself again.

You may want some method in the Snake class that checks for either type of collision and returns True if a collision occurred, or False otherwise. You can then change the gameloop method to only call itself using ontimer if no collision occurred.

What I have tried:

This is the beginning of the code
Python
import turtle, random

class Game:
def __init__(self):

#Setup 700x700 pixel window
turtle.setup(700, 700)

#Bottom left of screen is (-40, -40), top right is (640, 640)
turtle.setworldcoordinates(-40, -40, 640, 640)
cv = turtle.getcanvas()
cv.adjustScrolls()

#Ensure turtle is running as fast as possible
turtle.hideturtle()
turtle.delay(0)
turtle.speed(0)

#Draw the board as a square from (0,0) to (600,600)
for i in range(4):
    turtle.forward(600)
    turtle.left(90)

Game()
Posted
Updated 27-Jul-23 17:52pm
v2
Comments
Richard MacCutchan 27-Jul-23 12:41pm    
You still have a lot of work to do.
Dave Kreskowiak 27-Jul-23 14:06pm    
You have described no problem you're having, nor any of the code YOU wrote. You only posted your homework assignment.

Are you saying you want someone to do your work for you?

While we are more than willing to help those that are stuck, that doesn't mean that we are here to do it all for you! We can't do all the work, you are either getting paid for this, or it's part of your grades and it wouldn't be at all fair for us to do it all for you.

So we need you to do the work, and we will help you when you get stuck. That doesn't mean we will give you a step by step solution you can hand in!
Start by explaining where you are at the moment, and what the next step in the process is. Then tell us what you have tried to get that next step working, and what happened when you did.

Just posting your assignment isn't going to get you anywhere.

If you are having problems getting started at all, then this may help: How to Write Code to Solve a Problem, A Beginner's Guide[^]
 
Share this answer
 
The assignment is describing what you have to do step-by-step. There is little anyone can tell you beyond that without actually doing the work for you.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900