Int2?BFS(System.Func <Int2, bool> validEndpoint, int maxDistance = int.MaxValue) { Queue <Int2> queue = new Queue <Int2>(); Dictionary <Int2, Int2> parents = new Dictionary <Int2, Int2>(); Dictionary <Int2, int> depth = new Dictionary <Int2, int>(); Int2 startPoint = state.playerPos; queue.Enqueue(startPoint); depth[startPoint] = 0; while (queue.Count > 0) { var p = queue.Dequeue(); var ourDepth = depth[p]; if (state.GetState(p) == Game.CellState.Occupied) { continue; } Game.SeenEntity unitAtTile; if (state.maps[state.currentMap].units.TryGetValue(p, out unitAtTile)) { if (unitAtTile.frame > state.frame - 100 && unitAtTile.entity.health > state.player.health) { continue; } } if (validEndpoint(p)) { List <Int2> path = new List <Int2>(); while (p != startPoint) { path.Add(p); Debug.DrawLine(new Vector2(p.x, p.y), new Vector2(parents[p].x, parents[p].y), Color.red, 0.5f); p = parents[p]; } if (path.Count > 0) { return(path[path.Count - 1]); } break; } if (!state.HasAnyInfoAbout(p)) { continue; } if (ourDepth >= maxDistance) { continue; } for (int i = 0; i < 4; i++) { var other = p + Game.Direction2delta[i]; if (!parents.ContainsKey(other)) { parents[other] = p; depth[other] = ourDepth + 1; queue.Enqueue(other); } } } return(null); }