Пример #1
0
	/// <summary>
	/// 블록 내의 모퉁이에 적의 발생 위치를 랜덤하게 생성한다.
	/// </summary>
	/// <param name="block">대상 블록</param>
	public void CreateSpawnPointAtCornnerAtRandom(ChipType[,] block)
	{
		// 플로어 수를 카운트.
		int candidate = 0; // 스폰 포인트가 될 수 있는 플로어 수.
		for (int bh = 1; bh < block.GetLength(0); ++bh)
		{
			for (int bw = 1; bw < block.GetLength(1); ++bw)
			{
				if (block[bh, bw] != ChipType.Floor || !IsCornner(block, bh, bw))
					continue;
				
				++candidate;
			}
		}
		
		if (candidate == 0)
			return;
		
		// 플로어를 랜덤 선택.
		double r = random.NextDouble();
		double total = 0.0;
		for (int bh = 1; bh < block.GetLength(0); ++bh)
		{
			for (int bw = 1; bw < block.GetLength(1); ++bw)
			{
				if (block[bh, bw] != ChipType.Floor || !IsCornner(block, bh, bw))
					continue;
				total += 1.0/candidate;
				if (r < total)
				{
					block[bh, bw] = ChipType.Spawn;
					return;
				}
			}
		}
	}
Пример #2
0
	/// <summary>
	/// 지정한 블록 간의 거리( )를 구한다.
	/// </summary>
	/// <param name="from_fh">블록 위치</param>
	/// <param name="from_fw">블록 위치</param>
	/// <param name="to_fh">블록 위치</param>
	/// <param name="to_fw">블록 위치</param>
	/// <returns>거리</returns>
	public int GetDistanceBetweenTwoBlock(ChipType[,][,] field, int from_fh, int from_fw, int to_fh, int to_fw)
	{
		// 일단 미로를 무시한 거리를 반환.
		// return Math.Abs(from_fh - to_fh) + Math.Abs(from_fw - to_fw);
		
		var h = field.GetLength(0);
		var w = field.GetLength(1);
		
		int[,] doorInfo = new int[h, w];
		for (int i = 0; i < h; ++i)
		{
			for (int j = 0; j < w; ++j)
			{
				var d = 0;
				var b = field[i, j];
				var bh = b.GetLength(0);
				var bw = b.GetLength(1);
				var bhc = (bh / 2) % 2 == 0 ? bh/2-1 : bh/2;
				var bwc = (bw / 2) % 2 == 0 ? bw/2+1 : bw/2;
				
				if (b[bhc, 0] == ChipType.Door)
					d |= Direction.Left;
				
				if (b[bhc, bw-1] == ChipType.Door)
					d |= Direction.Right;
				
				if (b[0, bwc] == ChipType.Door)
					d |= Direction.Top;
				
				if (b[bh-1, bwc] == ChipType.Door)
					d |= Direction.Bottom;
				
				doorInfo[i, j] = d;
			}
		}
		
		// DFS
		var distance = int.MaxValue;
		var closed = new bool[h, w];
		var open = new Queue<KeyValuePair<int, int>>();
		var d_buffer = new Queue<int>();
		open.Enqueue(new KeyValuePair<int,int>(from_fh, from_fw));
		d_buffer.Enqueue(0);
		
		Func<int, int, bool> RangeTest = (i, j) => {
			if (i < 0 || j < 0 || i >= h || j >= w)
			return false;
			return true;
		};
		
		while (open.Count != 0)
		{
			var pos = open.Dequeue();
			var i = pos.Key;
			var j = pos.Value;
			var d = d_buffer.Dequeue();
			
			if (closed[i, j])
				continue;
			
			if ((i == to_fh && j == to_fw) && distance > d)
			{
				distance = d;
				continue;
			}
			
			if (HasTargetDoor(doorInfo[i, j], Direction.Top) && RangeTest(i-1, j))
			{
				open.Enqueue(new KeyValuePair<int, int>(i-1, j));
				d_buffer.Enqueue(d+1);
			}
			
			if (HasTargetDoor(doorInfo[i, j], Direction.Bottom) && RangeTest(i+1, j))
			{
				open.Enqueue(new KeyValuePair<int, int>(i+1, j));
				d_buffer.Enqueue(d+1);
			}
			
			if (HasTargetDoor(doorInfo[i, j], Direction.Left) && RangeTest(i, j-1))
			{
				open.Enqueue(new KeyValuePair<int, int>(i, j-1));
				d_buffer.Enqueue(d+1);
			}
			
			if (HasTargetDoor(doorInfo[i, j], Direction.Right) && RangeTest(i, j+1))
			{
				open.Enqueue(new KeyValuePair<int, int>(i, j+1));
				d_buffer.Enqueue(d+1);
			}
			
			closed[i, j] = true;
		}
		
		return distance;
	}
Пример #3
0
	public void DebugPrint(ChipType[,] block)
	{
		for (int h = 0; h < block.GetLength(0); ++h)
		{
			for (int w = 0; w < block.GetLength(1); ++w)
			{
				switch (block[h, w]) 
				{
				case ChipType.Wall:
					Console.Write("@");
					break;
				case ChipType.Floor:
					Console.Write(" ");
					break;
				case ChipType.BottomKey:
					Console.Write("b");
					break;
				case ChipType.TopKey:
					Console.Write("t");
					break;
				case ChipType.RightKey:
					Console.Write("r");
					break;
				case ChipType.LeftKey:
					Console.Write("l");
					break;
				case ChipType.Door:
					Console.Write("d");
					break;
				case ChipType.BossKey:
					Console.Write("B");
					break;
				default:
					throw new Exception("그런 블록은 없어요");
				}
			}
			Console.WriteLine(string.Empty);
		}
	}
Пример #4
0
	private void CreateKey(ref ChipType[,] block, int door)
	{
		// 플로어 수 카운트
		int nofFloor = 0;
		for (int h = 1; h < block.GetLength(0)-1; ++h)
		{
			for (int w = 1; w < block.GetLength(1)-1; ++w)
			{
				if (block[h, w] == ChipType.Floor)
					++nofFloor;
			}
		}
		
		// 열쇠 설치
		for (int i = 0; i < 4; ++i)
		{
			ChipType key;
			if (i == 0) {
				key = ChipType.RightKey;
				if ((door & Direction.Right) == 0)
					continue;
			}
			else if (i == 1)
			{
				key = ChipType.LeftKey;
				if ((door & Direction.Left) == 0)
					continue;
			}
			else if (i == 2)
			{
				key = ChipType.BottomKey;
				if ((door & Direction.Bottom) == 0)
					continue;
			}
			else
			{
				key = ChipType.TopKey;     
				if ((door & Direction.Top) == 0)
					continue;
			}
			
			double total = 0.0;
			double p = random.NextDouble();
			for (int h = 1; h < block.GetLength(0)-1; ++h)
			{
				for (int w = 1; w < block.GetLength(1)-1; ++w)
				{
					total += 1.0 / nofFloor;
					if (block[h,w] != ChipType.Floor || p > total)
						continue;
					
					block[h, w] = key;
					--nofFloor;
					h = block.GetLength(0);
					break;
				}
			}
		}
	}
Пример #5
0
	private void CreateDoor(ref ChipType[,] block, int door, bool is_room)
	{
		int hd = 0;
		int wd = 0;
		if (((block.GetLength(0)-2) / 2) % 2 == 1)
			hd = 1;
		if (((block.GetLength(1)-2) / 2) % 2 == 1)
			wd = 1;
		
		ChipType doorChip = ChipType.Door;
		
		if ((door & Direction.Left) != 0)
		{
			if(is_room) {

				block[block.GetLength(0)/2-hd, 0] = ChipType.Wall;
				block[block.GetLength(0)/2-hd, 1] = doorChip;

			} else {

				block[block.GetLength(0)/2-hd, 0] = doorChip;
				block[block.GetLength(0)/2-hd, 1] = ChipType.Floor;
			}
		}
		
		if ((door & Direction.Right) != 0)
		{
			if(is_room) {

				block[block.GetLength(0)/2-hd, block.GetLength(1)-1] = ChipType.Wall;
				block[block.GetLength(0)/2-hd, block.GetLength(1)-2] = doorChip;

			} else {

				block[block.GetLength(0)/2-hd, block.GetLength(1)-1] = doorChip;
				block[block.GetLength(0)/2-hd, block.GetLength(1)-2] = ChipType.Floor;
			}
		}
		
		if ((door & Direction.Top) != 0)
		{
			if(is_room) {

				block[0, block.GetLength(1)/2+wd] = ChipType.Wall;
				block[1, block.GetLength(1)/2+wd] = doorChip;

			} else {

				block[0, block.GetLength(1)/2+wd] = doorChip;
				block[1, block.GetLength(1)/2+wd] = ChipType.Floor;
			}
		}
		
		if ((door & Direction.Bottom) != 0)
		{
			if(is_room) {

				block[block.GetLength(0)-1, block.GetLength(1)/2+wd] = ChipType.Wall;
				block[block.GetLength(0)-2, block.GetLength(1)/2+wd] = doorChip;

			} else {

				block[block.GetLength(0)-1, block.GetLength(1)/2+wd] = doorChip;
				block[block.GetLength(0)-2, block.GetLength(1)/2+wd] = ChipType.Floor;
			}
		}
	}
Пример #6
0
	/// <summary>
	/// Block을 만든다.
	/// </summary>
	/// <param name="emptyBlock"></param>
	/// <returns></returns>
	private void CreateWall(ref ChipType[,] emptyBlock)
	{
		int height = emptyBlock.GetLength(0);
		int width = emptyBlock.GetLength(1);
		
		for (int h = 2; h < height-1; h+=2)
		{
			for (int w = 2; w < width-1; w+=2)
			{
				int randMax = 3;
				var next = random.Next(randMax);
				if (next == 0) // 오른쪽 방향
					emptyBlock[h,w+1] = ChipType.Wall; 
				else if (next == 1) // 왼쪽 방향
					emptyBlock[h,w-1] = ChipType.Wall;
				else if (next == 2) // 아래 방향
					emptyBlock[h+1,w] = ChipType.Wall;
			}
		}
	}
Пример #7
0
    private void CreateDoor(ref ChipType[,] block, int door)
    {
        int hd = 0;
        int wd = 0;
        if (((block.GetLength(0)-2) / 2) % 2 == 1)
            hd = 1;
        if (((block.GetLength(1)-2) / 2) % 2 == 1)
            wd = 1;

        if ((door & Direction.Left) != 0)
        {
            block[block.GetLength(0)/2-hd, 0] = ChipType.Door;
            block[block.GetLength(0)/2-hd, 1] = ChipType.Floor;
        }

        if ((door & Direction.Right) != 0)
        {
            block[block.GetLength(0)/2-hd, block.GetLength(1)-1] = ChipType.Door;
            block[block.GetLength(0)/2-hd, block.GetLength(1)-2] = ChipType.Floor;
        }

        if ((door & Direction.Top) != 0)
        {
            block[0, block.GetLength(1)/2+wd] = ChipType.Door;
            block[1, block.GetLength(1)/2+wd] = ChipType.Floor;
        }

        if ((door & Direction.Bottom) != 0)
        {
            block[block.GetLength(0)-1, block.GetLength(1)/2+wd] = ChipType.Door;
            block[block.GetLength(0)-2, block.GetLength(1)/2+wd] = ChipType.Floor;
        }
    }