-
Notifications
You must be signed in to change notification settings - Fork 0
/
BFSearch.cs
71 lines (61 loc) · 2.37 KB
/
BFSearch.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.Tilemaps;
public class BFSearch : MonoBehaviour
{
[Header("Map information")]
[SerializeField] Tilemap ground;
[SerializeField] Sprite walkable;
[Header("Search object")]
[SerializeField] GameObject goal;
private Dictionary<Vector3Int, Vector3Int?> map;
// Start is called before the first frame update
void Start()
{
// Checks
if (ground == null || goal == null)
{
Debug.Log("Remember to assign variables.");
enabled = false;
}
if (ground.GetSprite(ground.WorldToCell(goal.transform.position)) != walkable)
{
Debug.Log("The end position should be on top of a walkable road");
enabled = false;
}
generateMap();
}
private void generateMap()
{
map = new Dictionary<Vector3Int, Vector3Int?>();
var frontier = new Queue<Vector3Int>();
var startCel = ground.WorldToCell(goal.transform.position);
frontier.Enqueue(startCel);
map.Add(startCel, null); // goal reached
while (frontier.Any())
{
var current = frontier.Dequeue();
foreach (var neighbour in getNeighbours(current))
{
if (!map.ContainsKey(neighbour))
{
frontier.Enqueue(neighbour);
map.Add(neighbour, current);
}
}
}
}
private IEnumerable<Vector3Int> getNeighbours(Vector3Int current)
{
if (current.x > ground.cellBounds.xMin && ground.GetSprite(current - new Vector3Int(1, 0, 0)) == walkable)
yield return current - new Vector3Int(1, 0, 0);
if (current.x < ground.cellBounds.xMax && ground.GetSprite(current + new Vector3Int(1, 0, 0)) == walkable)
yield return current + new Vector3Int(1, 0, 0);
if (current.y > ground.cellBounds.yMin && ground.GetSprite(current - new Vector3Int(0, 1, 0)) == walkable)
yield return current - new Vector3Int(0, 1, 0);
if (current.y < ground.cellBounds.yMax && ground.GetSprite(current + new Vector3Int(0, 1, 0)) == walkable)
yield return current + new Vector3Int(0, 1, 0);
}
public Vector3Int? GetNext(Vector3Int current) => map.ContainsKey(current) ? map[current] : null;
}