In this tutorial, we will guide you through the process of creating the classic Snake game using the Go programming language. Snake is a simple yet fun game where the player controls a snake to collect food while avoiding collisions with itself and the walls. The objective of this game is to grow the snake as long as possible without dying.
Objective
The main objective of this project is to teach you how to implement basic game logic, user input handling, and graphics using Go. By the end of this tutorial, you will have a fully functional Snake game that you can run in your terminal.
Code
Below is the Go code that implements the classic Snake game. You will need the github.com/nsf/termbox-go
package to handle terminal-based graphics.
package main import ( "fmt" "math/rand" "os" "os/exec" "time" "github.com/nsf/termbox-go" ) type Point struct { x, y int } type Snake struct { body []Point dir Point } var snake Snake var food Point var screenWidth, screenHeight int func init() { rand.Seed(time.Now().UnixNano()) } func setup() { var err error err = termbox.Init() if err != nil { fmt.Println("Error initializing termbox:", err) os.Exit(1) } screenWidth, screenHeight = termbox.Size() snake = Snake{ body: []Point{{x: screenWidth / 2, y: screenHeight / 2}}, dir: Point{x: 1, y: 0}, } spawnFood() } func draw() { termbox.Clear(termbox.ColorDefault, termbox.ColorDefault) for _, p := range snake.body { termbox.Set(p.x, p.y, termbox.ColorGreen, termbox.ColorDefault, '■') } termbox.Set(food.x, food.y, termbox.ColorRed, termbox.ColorDefault, '■') termbox.Flush() } func spawnFood() { food = Point{ x: rand.Intn(screenWidth), y: rand.Intn(screenHeight), } } func moveSnake() { head := snake.body[0] newHead := Point{ x: head.x + snake.dir.x, y: head.y + snake.dir.y, } // Check if snake hits the wall if newHead.x < 0 || newHead.x >= screenWidth || newHead.y < 0 || newHead.y >= screenHeight { gameOver() return } // Check if snake eats itself for _, p := range snake.body { if p == newHead { gameOver() return } } // Add new head to snake body snake.body = append([]Point{newHead}, snake.body...) // Check if snake eats food if newHead == food { spawnFood() // Spawn new food } else { snake.body = snake.body[:len(snake.body)-1] // Remove last segment if no food eaten } } func gameOver() { fmt.Println("Game Over!") termbox.Close() os.Exit(0) } func handleInput() { event := termbox.PollEvent() switch event.Type { case termbox.EventKey: switch event.Key { case termbox.KeyArrowUp: if snake.dir != (Point{x: 0, y: 1}) { snake.dir = Point{x: 0, y: -1} } case termbox.KeyArrowDown: if snake.dir != (Point{x: 0, y: -1}) { snake.dir = Point{x: 0, y: 1} } case termbox.KeyArrowLeft: if snake.dir != (Point{x: 1, y: 0}) { snake.dir = Point{x: -1, y: 0} } case termbox.KeyArrowRight: if snake.dir != (Point{x: -1, y: 0}) { snake.dir = Point{x: 1, y: 0} } case termbox.KeyEsc: gameOver() } } } func main() { setup() defer termbox.Close() for { handleInput() moveSnake() draw() time.Sleep(100 * time.Millisecond) } }
Explanation of the Program Structure
The program structure consists of several key parts:
- Initialization (init, setup): We initialize the termbox package, set up the snake’s initial position, and spawn the first food.
- Game Loop (main): The game runs in a loop where it continuously checks for user input, moves the snake, draws the screen, and checks for collisions.
- Handling Input (handleInput): The program listens for keyboard events (arrow keys) to control the snake’s movement and the escape key to end the game.
- Snake Movement (moveSnake): Each time the game loop runs, the snake’s head moves in the current direction. The snake grows when it eats food and shortens when it doesn’t.
- Game Over (gameOver): The game ends when the snake hits the wall or itself. The program then closes the game and exits.
How to Run the Program
To run the Snake game in Go, follow these steps:
-
- Install Go if you haven’t already by visiting Go Downloads.
- Install the termbox-go package by running the following command in your terminal:
go get -u github.com/nsf/termbox-go
-
- Copy the provided code into a file, e.g.,
snake.go
. - Run the program using the command:
- Copy the provided code into a file, e.g.,
go run snake.go
- Enjoy playing the game in your terminal!