그리드의 타일 세트가 닫힌 모양을 형성하는지 확인


10

그리드에 타일 세트가 주어지면 다음을 결정하고 싶습니다.

  • 타일이 동봉 된 도형을 만드는 경우
  • 보드의 측면을 그림의 가장자리로 계산할 때 타일이 동봉 된 그림을 만드는 경우
  • 앞의 두 문장 중 하나가 참이면 추가 타일이 동봉 된 그림 안에 들어가 초기 타일이됩니다.

플레이어는 한 타일을 아래로 누른 다음 손가락을 다른 타일로 드래그하여 동일한 색상의 타일 체인을 만듭니다. 다음 타일이 유효한지 확인하면서 확인하겠습니다. 전의. 플레이어가 빨간색 타일에서 시작하면 다음 유효한 이동은 인접한 빨간색 타일로 이동하는 것입니다 (대각선 계산). 사용자가 손가락을 들어 올리면 위의 3 가지 항목을 확인할 수 있어야합니다.

그래서 처음에 생각한 것은 내가 갈 때마다 체인 의 유효성을 확인했기 때문에 플레이어가 손가락을 들었을 때 첫 번째 타일과 마지막 타일이 인접했는지 확인할 수 있다는 것입니다. (나는 이미 그들이 같은 색임을 알고 있습니다.) 그들이 인접 해 있다면 나는 뭉친 그림을 만들었고, 내가 큰 것을 놓치고 있는지 확인하기 위해 여기에 왔습니다. 내 직감이 옳았다는 논리적 인 / 수학적 증거 (혹은 틀린 것을 증명하는 예)

그러나 항목 번호 2를 생각할 때입니다. 또한 보드의 가장자리를 동봉 된 그림의 측면으로 사용하는 체인도 고려해야합니다. 이 경우 체인의 첫 번째 항목과 마지막 항목은 인접 하지 않지만 여전히 동봉 된 그림이 있습니다. 이제 저는 다시 제곱으로 돌아 왔습니다.

이 그리드 좌표 체인으로 동봉 된 그림을 만들지 여부를 파악하려면 어떻게해야합니까? 그리고 동봉 된 그림 있다는 것을 알고 나면 경계 안에있는 모든 타일의 추가 목록을 얻는 가장 좋은 방법은 무엇입니까?

여기에 이미지 설명을 입력하십시오

여기에 이미지 설명을 입력하십시오

위에서 나는이 테스트의 4 가지 가능한 결과가 될 수있는 것에 대한 그림을 그렸습니다.

  1. 체인은 동봉 된 도형을 만들지 않습니다.

  2. 체인은 동봉 된 그림을 만듭니다.

  3. 보드의 측면을 그림의 가장자리 (또는 둘 이상의 가장자리)로 계산하면 체인이 동봉 된 그림을 만듭니다.

  4. 체인은 동봉 된 그림을 만들지 만 생성 된 그림의 일부가 아닌 추가 데이터 포인트 (사용자가 체인의 일부로 올바르게 선택 함)가 있습니다.

케이스 4는 가장 까다 롭습니다. "추가"체인 링크를 추출하여 동봉 된 그림과 그 안에 포함 된 조각을 찾아야하기 때문입니다.

그래서 ... 누구든지이 문제를 해결하는 좋은 방법을 알고 있습니까? 나는이 시점에서 서클에 들어가고 또 다른 눈을 사용할 수 있습니다.


1
그림 8 또는 오각형 과 같은 교차 경로는 어떻습니까? 0이 아니거나 홀수 홀수 규칙을 가정 합니까?
Anko

사례 4는 사례 3과 통합 할 수도 있습니다. 추가 정보와 함께 보드 측면을 사용하여 동봉
ChargingPun

보드의 중앙에서 위쪽 가장자리에서 아래쪽으로 세로 선이 있으면 보드의 어느 쪽이 '밀폐'되어 있습니까?
Steven Stadnicki

지금은 가장 작은 공간이 닫힌다고 가정해야한다고 생각합니다. OP가 달리 지정하지 않는 한.
Tom 'Blue'Piddock

답변:


3

1. 타일 루프 감지

문제는 그래프에서 사이클 (루프)을 감지하는 것과 비슷해 보입니다 ( 여기 또는 여기 참조) .

  • V해당 그래프 의 노드 집합은 G=(V, E)타일입니다.
  • e = (v1, v2)타일이 직접 또는 대각선 이웃 인 경우 두 개의 서로 다른 노드 사이에 모서리 가 있습니다.

2. 화면 테두리 처리

화면 테두리는 가상 타일로 구성되어 있으며 보이는 타일의 화면 주위에 하나의 타일 너비의 테두리를 형성합니다.

화면 테두리의 사양 부분에 따르면 닫힌 루프의 암시 적 부분을 형성합니다. 폐 루프를 탐지하기 위해서는 이 규칙을 통해 연결을 유지 하여 그래프 G를 그래프 로 확장하면 충분합니다 G'.

  • 두 개의 타일이 각각 화면 경계 근처에 직접 배치되어 있으면 두 개의 다른 노드 사이에 다른 모서리가 있습니다.

따라서 (0,0) 및 (1,0)의 타일은 "테두리 타일"(-1,0), (-1, -1), (0, -1)과 함께 닫힌 루프의 일부가됩니다. , (1, -1).

3. 루프 영역의 내부

사용자 Arthur Wulf White가 제안한 것과 비슷한 방향으로 나아갈 것입니다 .

타일 ​​세트를 제한하면 루프 타일의 경계 상자로 검사해야합니다.

그런 다음 플러드 필을 사용하여 닫힌 루프의 외부 또는 내부에있는 경계 상자 내의 모든 타일을 선택합니다. 두 경우 중 하나 일 수 있습니다. 나중에 찾아야 할 것.

경계 상자를 각 방향으로 한 타일 씩 연장하는 것도 좋은 생각이 될 수 있습니다. extbb따라서 외부 타일로 플러드 필을 시작한 경우 연결된 외부 점 세트로 끝납니다.

플러드 필 영역이 있으면 경계 상자도 계산합니다 ffbb. 외부 타일로 시작한 경우 확장 루프 경계 상자와 동일해야합니다.

ffbb == extbb

내부 타일로 시작한 경우 루프 타일이 두 경계 상자 사이에 끼워져 있어야하기 때문에 분명히 작은 경계 상자를 만들어야합니다.

ffbb < extbb

플러드 채우기의 초기 시작 타일 extbb은 프리 타일 인 타일 일 수 있습니다. 무작위로 하나를 선택하는 것이 가장 좋은 방법 일 수 있습니다.

내부가 외부보다 작은 것을 미리 알고 싶다면 많은 영역 (카운터 예 : C 모양 영역)의 내부에있는 루프 포인트의 질량 중심 주위에서 시작합니다 extbb. 그렇지 않으면의 경계에서 시작합니다 . 그러나 나는 이것을 어떻게 평가할 지 모른다.

최종 비고

일반적으로 일부 타일에서 시작하여 방문 타일 목록을 유지하면주기를 감지하는 데 충분하지만 화면 경계 조건이 더 복잡한 그래프를 생성 할 수 있으므로 그래프 알고리즘으로 안전해야합니다. .

아래는 내부가 연결되지 않은 예입니다. 반면에 사이클 감지는이 경우 두 개의 루프를 찾아야합니다. 하나는 폐기되어야합니다.

어떤 경우


1

다음을 통해이 문제를 해결할 수 있습니다.

  1. 해당 모양의 경계 상자를 찾습니다.
  2. 각 방향으로 1 씩 증가합니다.
  3. 새로운 약간 확대 된 경계 상자의 프레임을 반복하고 플러드 필을 적용합니다.
  4. 해당 체인에없는 플러드 필로 표시하지 않은 타일이 있으면 해당 타일로 둘러싸입니다. 모양보다 닫힌 타일이있는 경우 귀하의 정의에 따라 닫힌 그림이라고 가정합니다.

체인의 모든 타일을 통해 하나의 반복,을 찾아 그들의하려면 minX, minY, maxX그리고 maxY그것은 당신의 경계 상자 또는 AABB이다.

둘은 사소하다.

프레임을 반복하는 것은 간단합니다. 그리드 외부로 넘치지 않도록하십시오. Wikipedia 에서 홍수를 채우는 방법을 배울 수 있습니다 .

숫자 4의 경우 체인에 인접한 타일 만 확인하여 시작할 수 있습니다. 더 많은 타일을 찾도록 표시되지 않은 타일을 플러딩 할 수 있습니다.


0

사용자가 이미 선택한 타일을 선택하자마자 체인이 종료된다고 가정하면 직감이 맞습니다. 이 경우 일반적으로 모양은 사진에서 올가미처럼 보입니다 (4). 계속 스 와이프하면 많은 루프를 그릴 수 있으며 상황이 더 복잡해집니다. 당신이하고 싶은 것은 다각형 포인트 질문에 대답하는 것입니다.

먼저 문제를 정의해야합니다. 상황이 (2)처럼 보인다고 가정합니다. 즉, 꼬리가 벗겨지고 끝이 시작 부분으로 다시 연결되므로 각 타일은 체인에 정확히 하나의 "전임자"와 정확히 하나의 "후임자"가 있습니다. (타일 X의 후속 작업은 항상 타일 X 임). 또한, "성공자"를 충분히 오랫동안 따라 가면 결국 시작한 곳으로 돌아갑니다. Gurgadurgen의 제안을 사용하여 루프가 실제로 어느 시점에서 스스로 다시 돌아가는지 감지 할 수 있습니다. 입력 할 때 사용자의 입력을 종료한다고 가정하면, 일련의 일련의 노드처럼 보일 것이고 그 뒤에 루프가있을 것입니다. 루프에서 줄을 벗길 수 있습니다.

이제 각 행에 대해 다음을 수행하십시오.

  1. 왼쪽 가장자리에서 시작하여 각 타일의 부울을 추적하여 IN인지 OUT인지 알려줍니다. 시작하다.
  2. 현재 타일이 체인의 일부인 경우 후속 및 이전 버전 (인접해야 함)을 모두보십시오. 둘 중 하나가 엄격하게 위 (즉, 현재 타일의 북, 북동 또는 북서)이면 현재 타일의 상태를 왼쪽의 타일 반대쪽으로 설정하십시오. 그렇지 않으면 왼쪽 타일과 동일하게 설정하십시오. 고토 4.
  3. 현재 타일이 체인의 일부가 아닌 경우 제목 상태를 왼쪽으로 설정하십시오. 고토 4.
  4. 오른쪽의 타일은 현재 타일입니다. 고토 2.

이제 IN에있는 모든 타일을 가져 와서 테두리에 타일을 추가하고 (앞에서 벗겨 낸 꼬리를 포함하여 선택), 해당 지역을 호출하십시오.

사용자가 테두리를 사용할 수있게하려면 보드에서이를 정의하지 않고 IN / OUT이 아니라 두 부분으로 나눕니다. 예를 들어 더 작은 영역을 선택하거나 사용자에게 두 개의 인접한면 (즉, 왼쪽 / 아래쪽을 사용하지만 위쪽 / 아래쪽 또는 왼쪽 / 오른쪽을 사용하지 않아야 함)을 사용하도록 요구할 수 있습니다.

최적화는 경계가있는 행만 수행해야한다는 것입니다 (측면을 사용할 수없는 경우). 나는 보드가 작아서 모든 타일을 반복하고 매우 간단한 계산을 수행하는 것이 가장 약한 모바일 시스템에서도 문제가되지 않는다고 가정합니다. (결국 훨씬 복잡한 작업으로 렌더링해야합니다).

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.