Menu
CoddyTech

Not on the Snake

Lesson 9 of 14 in Coddy's Unity Game: Snake 3D course.

MoveFood() picks any cell, including the cells the snake covers. Food under the snake cannot be eaten until the snake moves off it, and the longer the snake, the more often that happens.

One fix is to pick again until the cell is free. It works on an empty board, but it takes more and more tries as the board fills, and with no free cell left it never ends. The steady fix makes a list of the free cells first and picks one of them: every free cell is equally likely, and one pick is always enough. A cinema seats a late guest the same way:

List<int> free = new List<int>();
for (int seat = 1; seat <= 40; seat++)
{
    if (!taken.Contains(seat)) free.Add(seat);
}
int pick = free[Random.Range(0, free.Count)];

Random.Range(0, free.Count) returns an index from 0 to the last one, since the maximum is left out. To build the list, the board asks the snake whether it covers a cell: a method on Snake that checks the head and every segment.

challenge icon

Challenge

Medium
  1. In Snake, write public bool Occupies(Vector3 cell): true when cell is the head's cell or the cell of a tail segment.
  2. In GameManager, add using System.Collections.Generic; and rewrite MoveFood(): loop x and z over every cell of the board, add each cell the snake does not occupy to a List<Vector3> free, and put the food on a random cell of that list.

Press Play, then press Check. The checks fill most of the board with snake and make sure the food still finds the free cells.

Try it yourself

using UnityEngine;

public class GameManager : MonoBehaviour
{
    public static GameManager Instance;

    public Snake snake;
    public GameObject foodPrefab;
    private Transform food;
    private int score;

    void Awake()
    {
        Instance = this;
    }

    void Start()
    {
        food = Instantiate(foodPrefab).transform;
        MoveFood();
    }

    public bool IsFood(Vector3 cell)
    {
        return cell == food.position;
    }

    public void Eat()
    {
        score++;
        MoveFood();
    }

    void MoveFood()
    {
        int x = Random.Range(-snake.edge, snake.edge + 1);
        int z = Random.Range(-snake.edge, snake.edge + 1);
        food.position = new Vector3(x, 0f, z);
    }
}
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Unity Game: Snake 3D