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;
		}