Golang

 

 

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:

    1. Install Go if you haven’t already by visiting Go Downloads.
    2. Install the termbox-go package by running the following command in your terminal:
go get -u github.com/nsf/termbox-go
    1. Copy the provided code into a file, e.g., snake.go.
    2. Run the program using the command:
go run snake.go
  1. Enjoy playing the game in your terminal!
© 2025 Learn Programming. All rights reserved.

 

By Aditya Bhuyan

I work as a cloud specialist. In addition to being an architect and SRE specialist, I work as a cloud engineer and developer. I have assisted my clients in converting their antiquated programmes into contemporary microservices that operate on various cloud computing platforms such as AWS, GCP, Azure, or VMware Tanzu, as well as orchestration systems such as Docker Swarm or Kubernetes. For over twenty years, I have been employed in the IT sector as a Java developer, J2EE architect, scrum master, and instructor. I write about Cloud Native and Cloud often. Bangalore, India is where my family and I call home. I maintain my physical and mental fitness by doing a lot of yoga and meditation.

Leave a Reply

Your email address will not be published. Required fields are marked *

error

Enjoy this blog? Please spread the word :)