private static List<Address> CastRay(int x0, int y0, int x1, int y1, Map map, List<string> types) { // Optimization: it would be preferable to calculate in // advance the size of "result" and to use a fixed-size array // instead of a list. List<Address> result = new List<Address>(); bool steep = false; if (Mathf.Abs(y1 - y0) > Mathf.Abs(x1 - x0)) steep = true; //if (steep) { // Swap(ref x0, ref y0); // Swap(ref x1, ref y1); //} //if (x0 > x1) { // Swap(ref x0, ref x1); // Swap(ref y0, ref y1); //} int deltax = Mathf.Abs(x1 - x0); int deltay = Mathf.Abs(y1 - y0); int error = 0; int ystep; int xstep; int x = x0; int y = y0; if (x0 < x1) xstep = 1; else xstep = -1; if (y0 < y1) ystep = 1; else ystep = -1; if (!steep) { for (int i = 0; i <= deltax; i++) { if (map.Contains(x, y) == false) return result; result.Add(new Address(x, y)); if (types.Contains(map.cellsOnMap[x, y].type)) return result; x += xstep; error += deltay; if (2 * error >= deltax) { y += ystep; error -= deltax; } } } else { for (int i = 0; i <= deltay; i++) { if (map.Contains(x, y) == false) return result; result.Add(new Address(x, y)); if (types.Contains(map.cellsOnMap[x, y].type)) return result; y += ystep; error += deltax; if (2 * error >= deltay) { x += xstep; error -= deltay; } } } return result; }
private List<Address> findVisibleCellsFlood(Map map, Address position, int range) { int arrSize = range * 2 + 1; int[,] arr = new int[arrSize, arrSize]; for (int i = 0; i < arrSize; i++) for (int j = 0; j < arrSize; j++) arr[i, j] = range + 1; //init array with high distance arr[range, range] = 0; // center cell is target Stack<Address> stack = new Stack<Address>(); stack.Push(new Address(range, range)); while (stack.Count != 0) { Address current = stack.Pop(); Address mapAddress = new Address(position.x + current.x - range, position.y + current.y - range); if (!map.Contains(mapAddress) || opaqueCells.Contains(map.cellsOnMap[mapAddress.x, mapAddress.y].type)) continue; int newDist = arr[current.x, current.y] + 1; if (current.x > 0 && newDist < arr[current.x - 1, current.y]) { stack.Push(new Address(current.x - 1, current.y)); arr[current.x - 1, current.y] = newDist; } if (current.x < arrSize - 1 && newDist < arr[current.x + 1, current.y]) { stack.Push(new Address(current.x + 1, current.y)); arr[current.x + 1, current.y] = newDist; } if (current.y > 0 && newDist < arr[current.x, current.y - 1]) { stack.Push(new Address(current.x, current.y - 1)); arr[current.x, current.y - 1] = newDist; } if (current.y < arrSize - 1 && newDist < arr[current.x, current.y + 1]) { stack.Push(new Address(current.x, current.y + 1)); arr[current.x, current.y + 1] = newDist; } } List<Address> result = new List<Address>(); for (int i = 0; i < arrSize; i++) { for (int j = 0; j < arrSize; j++) { Address mapAddress = new Address(position.x + i - range, position.y + j - range); if (map.Contains(mapAddress) && arr[i, j] <= range) result.Add(mapAddress); } } return result; }