{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "## Snake Game using turtle module in python" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- This is a simple snake game using turtle module in python. Important python modules used in this project are turtle, random, tkinter, and time.\n", "- The snake game is a single-player game. The objective of the game is to feed the snake with food that randomly appears on the screen. The snake grows in length as it eats the food. The game ends when the snake either collides with the wall or with itself.\n", "\n", "## How to play the game\n", "\n", "- The snake can be controlled using the arrow keys on the keyboard.\n", "- The game can be restarted by pressing the enter key.\n", "- The game can be exited by clicking on the screen." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "> Below is the snapshot of the game.\n", "\n", "![Snake Game](game_demo.png)" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "# define Food\n", "\n", "from turtle import Turtle\n", "import random\n", "\n", "class Food(Turtle):\n", " \"\"\"\n", " The Food class represents the food in the snake game. It inherits from the Turtle class.\n", " \"\"\"\n", "\n", " def __init__(self):\n", " \"\"\"\n", " Initialize a new Food object. The food is represented as a green circle.\n", " \"\"\"\n", " super().__init__()\n", " self.shape(\"circle\")\n", " self.penup()\n", " self.shapesize(stretch_len=0.5, stretch_wid=0.5)\n", " self.color(\"green\")\n", " self.speed(\"fastest\")\n", " self.refresh()\n", "\n", " def refresh(self):\n", " \"\"\"\n", " Move the food to a new random location within the game boundaries.\n", " \"\"\"\n", " random_x = random.randint(-280, 280)\n", " random_y = random.randint(-280, 280)\n", " self.goto(random_x, random_y)\n" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "# define scoreboard\n", "\n", "from turtle import Turtle\n", "ALIGNMENT = \"center\"\n", "FONT = (\"Courier\", 24, \"normal\")\n", "\n", "\n", "class Scoreboard(Turtle):\n", " \"\"\"\n", " The Scoreboard class represents the scoreboard in the snake game. It inherits from the Turtle class.\n", " \"\"\"\n", "\n", " def __init__(self):\n", " \"\"\"\n", " Initialize a new Scoreboard object. The scoreboard starts with a score of 0 and is displayed at the top of the screen.\n", " \"\"\"\n", " super().__init__()\n", " self.score = 0\n", " self.color(\"white\")\n", " self.penup()\n", " self.goto(0, 270)\n", " self.hideturtle()\n", " self.update_scoreboard()\n", "\n", " def update_scoreboard(self):\n", " \"\"\"\n", " Update the display of the scoreboard to show the current score.\n", " \"\"\"\n", " self.write(f\"Current Score: {self.score}\", align=ALIGNMENT, font=FONT)\n", "\n", " def game_over(self, message):\n", " \"\"\"\n", " Display a \"GAME OVER\" message at the center of the screen.\n", " \"\"\"\n", " self.goto(0, 0)\n", " self.write(\"GAME OVER!\" + f\" You {message}\", align=ALIGNMENT, font=FONT)\n", "\n", " def increase_score(self):\n", " \"\"\"\n", " Increase the score by 1 and update the scoreboard to reflect the new score.\n", " \"\"\"\n", " self.score += 1\n", " self.clear()\n", " self.update_scoreboard()\n" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "## snake properties\n", "\n", "from turtle import Turtle\n", "STARTING_POSITIONS = [(0, 0), (-20, 0), (-40, 0)]\n", "MOVE_DISTANCE = 10\n", "UP = 90\n", "DOWN = 270\n", "LEFT = 180\n", "RIGHT = 0\n", "\n", "def reset_game():\n", " \"\"\"\n", " Reset the game by creating new instances of Snake, Food, and Scoreboard.\n", " \"\"\"\n", " print(\"reset\")\n", " snake = Snake()\n", " food = Food()\n", " scoreboard = Scoreboard()\n", " \n", " return snake, food, scoreboard\n", "\n", "class Snake:\n", " \"\"\"\n", " The Snake class represents the snake in the snake game.\n", " \"\"\"\n", "\n", " def __init__(self):\n", " \"\"\"\n", " Initialize a new Snake object. The snake starts with a few segments and a head.\n", " \"\"\"\n", " self.segments = []\n", " self.create_snake()\n", " self.head = self.segments[0]\n", "\n", " def create_snake(self):\n", " \"\"\"\n", " Create the initial snake at the starting positions.\n", " \"\"\"\n", " for position in STARTING_POSITIONS:\n", " self.add_segment(position)\n", "\n", " def add_segment(self, position):\n", " \"\"\"\n", " Add a new segment to the snake at the given position.\n", " \"\"\"\n", " new_segment = Turtle(\"square\")\n", " new_segment.color(\"white\")\n", " new_segment.penup()\n", " new_segment.goto(position)\n", " self.segments.append(new_segment)\n", "\n", " def extend(self):\n", " \"\"\"\n", " Extend the snake by adding a new segment at the position of the last segment.\n", " \"\"\"\n", " self.add_segment(self.segments[-1].position())\n", "\n", " def move(self):\n", " \"\"\"\n", " Move the snake forward by moving each segment to the position of the previous segment.\n", " \"\"\"\n", " for seg_num in range(len(self.segments) - 1, 0, -1):\n", " new_x = self.segments[seg_num - 1].xcor()\n", " new_y = self.segments[seg_num - 1].ycor()\n", " self.segments[seg_num].goto(new_x, new_y)\n", " self.head.forward(MOVE_DISTANCE)\n", "\n", " def up(self):\n", " \"\"\"\n", " Change the heading of the snake's head to up, unless it's currently heading down.\n", " \"\"\"\n", " if self.head.heading() != DOWN:\n", " self.head.setheading(UP)\n", "\n", " def down(self):\n", " \"\"\"\n", " Change the heading of the snake's head to down, unless it's currently heading up.\n", " \"\"\"\n", " if self.head.heading() != UP:\n", " self.head.setheading(DOWN)\n", "\n", " def left(self):\n", " \"\"\"\n", " Change the heading of the snake's head to left, unless it's currently heading right.\n", " \"\"\"\n", " if self.head.heading() != RIGHT:\n", " self.head.setheading(LEFT)\n", "\n", " def right(self):\n", " \"\"\"\n", " Change the heading of the snake's head to right, unless it's currently heading left.\n", " \"\"\"\n", " if self.head.heading() != LEFT:\n", " self.head.setheading(RIGHT)\n", "\n", " def reset(self):\n", " \"\"\"\n", " Reset the snake by creating new instances of Snake, Food, and Scoreboard.\n", " \"\"\"\n", " # for seg in self.segments:\n", " # seg.goto(1000, 1000)\n", " print(\"reset\")\n", " snake, food, scoreboard = reset_game()\n", " return snake, food, scoreboard" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "hit wall\n", "press enter to restart\n" ] } ], "source": [ "## run game\n", "\n", "from turtle import Screen\n", "import time\n", "\n", "# Set up the screen for the game\n", "screen = Screen()\n", "screen.setup(width=600, height=600) # Set the screen size to 600x600\n", "screen.bgcolor(\"black\") # Set the background color to black\n", "screen.title(\"Snake Game\") # Set the title of the screen to \"Snake Game\"\n", "screen.tracer(0) # Turn off the screen updates\n", "\n", "# Create the snake, food, and scoreboard\n", "snake = Snake()\n", "food = Food()\n", "scoreboard = Scoreboard()\n", "\n", "# Listen for key presses\n", "screen.listen()\n", "screen.onkey(snake.up, \"Up\") # Move the snake up when the \"Up\" key is pressed\n", "screen.onkey(snake.down, \"Down\") # Move the snake down when the \"Down\" key is pressed\n", "screen.onkey(snake.left, \"Left\") # Move the snake left when the \"Left\" key is pressed\n", "screen.onkey(snake.right, \"Right\") # Move the snake right when the \"Right\" key is pressed\n", "\n", "# Pause for 2 seconds before starting the game\n", "time.sleep(2)\n", "\n", "# Start the game\n", "game_is_on = True\n", "while game_is_on:\n", " screen.update() # Update the screen\n", " time.sleep(0.1) # Pause for 0.1 seconds\n", " snake.move() # Move the snake\n", "\n", " # Detect collision with food\n", " if snake.head.distance(food) < 15:\n", " food.refresh() # Move the food to a new location\n", " snake.extend() # Extend the snake\n", " scoreboard.increase_score() # Increase the score\n", "\n", " # Detect collision with wall\n", " if snake.head.xcor() > 280 or snake.head.xcor() < -280 or snake.head.ycor() > 280 or snake.head.ycor() < -280:\n", " game_is_on = False # End the game\n", " print(\"hit wall\")\n", " scoreboard.game_over(message='Hit wall') # Display the game over message\n", "\n", " # Detect collision with tail\n", " for segment in snake.segments:\n", " if segment == snake.head:\n", " pass # Ignore the head segment\n", " elif snake.head.distance(segment) < 1:\n", " game_is_on = False # End the game\n", " print(\"hit tail\")\n", " scoreboard.game_over(message='Hit self') # Display the game over message\n", "\n", " # Restart game with enter key\n", " if game_is_on == False:\n", " print(\"press enter to restart\")\n", " screen.onkey(snake.reset, \"Return\") # Reset the game when the \"Return\" key is pressed\n", "\n", "# Exit the game when the screen is clicked\n", "screen.exitonclick()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.11.7" } }, "nbformat": 4, "nbformat_minor": 2 }