Menu
CoddyTech

ヘビの体の上には置かない

Coddyの「Unityゲーム:3Dスネーク」コースのレッスン 9/14。

MoveFood()は、ヘビが占めているセルも含めて、任意のセルを選びます。ヘビの下にある食べ物は、ヘビがそこから移動するまで食べられません。ヘビが長くなるほど、そのようなことが起きる頻度も高くなります。

ひとつの修正方法は、セルが空くまで選び直すことです。空の盤面ではうまくいきますが、盤面が埋まるにつれて試行回数が増え、空きセルがなくなると終わりません。確実な修正方法は、まず空いているセルのリストを作り、その中からひとつ選ぶことです。これなら、どの空きセルも同じ確率で選ばれ、選択は必ず一度で済みます。映画館で遅れて来た客に席を割り当てるのも同じ方法です。

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)は、最大値を含まないため、0から最後のインデックスまでの値を返します。リストを作るには、盤面がヘビにそのセルを占めているかどうかを尋ねます。つまり、頭とすべての体節を確認するSnakeのメソッドを使います。

challenge icon

チャレンジ

中級

食べ物はヘビの上には決して現れません。

  1. Snakeで、頭のセルまたは尻尾の各セグメントのセルに対してtrueを返すpublic bool Occupies(Vector3 cell)を書きます。
  2. GameManagerのMoveFood()で、xとzを-snake.edgeからsnake.edgeまでループし、!snake.Occupies(cell)となる各セルをList<Vector3> freeに追加して、free[Random.Range(0, free.Count)]に食べ物を配置します。

「プレイ」を押して、ヘビを長く伸ばしましょう。食べ物は必ず空いているセルに現れます。その後、「確認」を押します。

自分で試してみよう

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 icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

Unityゲーム:3Dスネークのすべてのレッスン

自分で練習してみよう: Unityプレイグラウンド