비전공자의 Python

[퍼즐풀이AI프로젝트] 2.퍼즐 생성

과금 2021. 12. 20. 20:40

이전 글에서 소개한 퍼즐 게임을 즐기던 중

퍼즐을 풀어가는 내 추론 과정에서 일련의 규칙성이 불현듯 느껴졌다.

먼저 이걸 체크하고 그다음 저걸 체크하고 또 그다음... 같은 식

 

그렇다면 사람이 직접 풀이하는 순서를 그대로 알고리즘으로 옮기기만 하면 하나의 AI가 뚝딱 만들어지는 것이 아닌가.

하는 생각에 프로젝트의 착상에 들어갔다.

 

 

먼저 퍼즐을 풀려면 퍼즐이 있어야겠지.

게임에서 그대로 옮겨오는 방법이 있겠지만 너무 손이 많이 갈 테니 일단 패스.

 

해서 퍼즐을 직접 작성하게 되었다.

 

퍼즐 작성 순서를 아래처럼 계획해봤다.

 

1. 퍼즐의 크기를 정하고

2. 크기를 사용하여 2차원 배열을 만들고

3. 배열에 무작위로 나무를 배치한 후

4. 나무 옆에 알맞은 텐트를 배열

5. 각 행과 열의 텐트 숫자를 세어 따로 기입

6. 텐트를 감추고 나무와 각 줄의 숫자만 기입하면 완성

 

근데 계획을 짜고 보니 4번이 이상하다는 생각이 들었다.

퍼즐을 풀기 위해 퍼즐을 만드는 중인데

그 퍼즐을 완성하기 위해 다시 퍼즐을 풀어야 한다는 모순.

 

해서 위 방법은 때려치우고

더 쉬워 보이는 방법으로 방향을 바꿨다.

 

1~2. 위와 동일

3. 무작위로 텐트를 배치해서

4. 텐트 옆에 나무를 하나씩 추가

5~6. 위와 동일

 

이 방법이면 무난하게 가능할 듯싶어 코드 작성에 착수했다.

 

먼저 1. 퍼즐 크기 결정

게임에서는 무조건 가로 세로 크기가 동일한 정사각형의 형태가 사용되지만

굳이 같을 필요는 없을 듯싶다.

따로따로 정할 수 있게 변수를 정하고

 

다음으로 2. 배열 작성

2차원 배열이나 행렬이나 거기서 거기다 보니

이 부분에서 NumPy를 사용하면 더 관리가 수월하지 않을까 하는 생각은 들었지만

사용해본 적이 없어서 패스.

그냥 for 문으로 2중 배열을 만들었다.

 

그리고 3. 텐트 배치

여기부터 복잡해진다.

첫 텐트는 random.randint 를 써서 아무 데나 배치하면 되지만

두 번째 텐트부터 이전 텐트와 접촉은 없는지 항시 체크해야 한다.

특정 좌표를 넘기면 주변 8개 구역에 다른 텐트가 있는지 체크하는 함수를 만들어서 대응했다.

 

단순히 x, y를 넘기면 x±1, y±1 범위를 탐색하게 짰는데

나중에 보니 이 부분에서 종종 오류가 발생했다.

가장자리 좌표 0을 넘기면 -1이 반환되는 바람에 반대편 가장자리가 탐색되던 탓.

반환할 좌표의 범위를 체크하는 구문을 나중에야 추가해 해결했다.

 

또 배치하는 텐트의 숫자를 미리 정해두고 완료될 때까지 루프를 돌리는 구문을 짰더니

간혹 무한루프에 빠지는 일이 발생했다.

밀집하게 배치하면 들어갈 공간이 충분한데도 듬성듬성 배치된 탓에 더 이상 배치가 불가능한 경우가 발생한 것.

이것은 텐트가 배치되면 주변 8 타일의 문자를 임시로 다른 것으로 치환해버린 후

원래의 문자가 더 이상 남지 않게 될 때까지만 반복하도록 루프 종료 조건을 추가해 해결했다.

 

다음 4. 나무 추가

텐트 배치를 끝마친 후에 나무를 추가하려다 보니

처리가 끝난 텐트와 그렇지 않은 것의 구분이라거나

인접한 다른 텐트에서 나무가 위치할 자리를 선점해버리면 더 이상 배치가 불가능해지는 문제 등이 우려되어

해당 루틴을 짜는 일은 포기했다.

 

대신 위 3번 과정에서 텐트를 배치한 직후 바로 인접 4자리 중 하나를 골라 나무를 추가하는 쪽으로 선회했다.

더불어 나무를 추가할 자리가 남지 않았을 경우도 예외조항에 추가했다.

 

그리고 5. 텐트 숫자 계산

for 반복문으로 각 행과 열을 따로 돌려서 텐트의 숫자만 확인했다.

가로 방향과 세로 방향의 연산을 단 하나의 공통된 함수로 처리하고 싶었지만

도저히 방법을 찾을 수 없어 결국 포기했다.

 

마지막 6. 텐트 비표시와 결과 출력

이건 너무 쉬운 문제라 딱히 코멘트가 필요 없다.

 

정답 (T 나무, C 텐트)
완성된 퍼즐 문제

완성.

작업 기간: 11월 하순 ~ 11월 하순

 

 

지금은 어느 정도 충격을 털고 티스토리에 복귀하긴 했지만

게임 관련 글만 게시하던 다른 블로그에서 15년 전 작성했던 공략 글이

얼마 지나지도 않아서 저작자 정보만 사라진 채 끝없이 퍼져나간 기억을 잊을 순 없는 탓에

전체 코드는 공개하지 않으련다.