본문으로 건너뛰기

지뢰찾기, 바이브코딩으로 만들기 — 첫 클릭부터 다시 생각했다

지뢰찾기, 바이브코딩으로 만들기 — 고전게임 만들기 02

Snake를 만들고 나서 두 번째로 고른 게임은 지뢰찾기다. Snake가 움직이는 뱀을 제때 꺾는 게임이라면, 지뢰찾기는 멈춰 있는 숫자를 보고 다음 한 칸을 고르는 게임이다. 같은 고전게임이어도 만드는 과정은 꽤 다를 것 같았다.

이번에 궁금했던 것은 칸을 누르면 숫자가 나오는 화면보다 그 안쪽의 규칙이었다. 첫 클릭부터 지뢰가 나오면 어떻게 할지, 빈칸은 어디까지 함께 열어야 할지, 깃발을 전부 꽂으면 끝난 것으로 볼지. 게임을 부탁하려고 내용을 적다 보니 생각보다 정해야 할 것이 많았다.

이번에도 Claude Code의 Sonnet을 사용했다. 구독 한도 안에서 만들고 고치는 작업을 이어 가려는 선택이다. 게임은 PC에서 HTML 파일 하나를 열어 실행하는 방식으로 만들었다.

처음에는 9×9 한 판만 부탁했다

초급 크기인 9×9 칸에 지뢰 10개. 왼쪽 클릭으로 열고 오른쪽 클릭으로 깃발을 꽂는 것부터 시작했다. 난이도 선택이나 순위표까지 넣으면 확인할 부분이 늘어날 것 같아, 한 판이 제대로 돌아가는 데 집중했다.

외부 라이브러리 없이 지뢰찾기를 만들어 줘. 9×9 칸에 지뢰는 10개, 첫 클릭은 안전하게 해 줘. 주변에 지뢰가 없는 칸을 누르면 연결된 빈칸과 경계의 숫자도 함께 열어 줘. 지뢰가 아닌 칸을 모두 열면 승리하도록 해 줘.

실제로 첫 화면 가운데를 눌렀다. 지뢰는 나오지 않았다. 대신 숫자 2 하나만 열렸다.

첫 구현에서 가운데 숫자 2 하나만 열린 지뢰찾기 화면
첫 구현에서 가운데 칸을 누른 화면. 클릭한 칸은 안전했지만, 숫자 2 하나만 열렸다.

안전한 첫 클릭과 편하게 시작하는 첫 클릭

처음에는 첫 클릭이 안전하면 충분하다고 생각했다. 막상 숫자 하나만 놓인 판을 보니 주변 여덟 칸 중 어디를 눌러야 할지 알 수 없었다. 요청한 규칙대로 만들어졌는데도, 시작하는 느낌은 내가 원하던 것과 달랐다.

그래서 요청을 한 번 더 보냈다. 첫 칸뿐 아니라 그 주변 칸에도 지뢰를 놓지 말아 달라고 했다. 먼저 클릭을 받고 나서 지뢰를 배치하되, 클릭한 칸과 이웃 칸을 후보에서 빼는 방식이다. 첫 칸이 빈칸이 되면 주변 영역이 함께 열리면서 숫자를 비교할 공간이 생긴다.

첫 클릭 칸과 주변 여덟 칸을 지뢰 배치에서 제외해 줘. 첫 칸에서 빈 영역이 열리도록 하고, 지뢰 수는 10개로 유지해 줘.

첫 클릭 주변 보호를 추가해 빈 영역과 경계 숫자가 열린 화면
수정 후 첫 클릭 화면. 가운데 빈칸과 연결된 영역, 경계의 숫자들이 함께 열렸다.

이것을 첫 버전의 버그라고 부르기는 어렵다. 첫 버전도 “첫 클릭은 안전하게”라는 조건을 지켰다. 내가 원하는 시작 방식을 충분히 설명하지 않은 쪽에 가까웠다. 짧게 적은 요청 한 줄이 실제 화면에서는 꽤 큰 차이로 돌아왔다.

다만 시작 영역을 열어 준다고 해서 모든 판을 추측 없이 풀 수 있는 것은 아니다. 이번에는 논리만으로 풀리는 판을 따로 생성하는 기능까지 만들지는 않았다.

깃발은 우클릭 말고 버튼으로도

기본 조작은 우클릭이지만, 화면에 깃발 모드도 두기로 했다. 모드를 바꾸면 평소처럼 클릭해서 깃발을 꽂을 수 있다. 트랙패드에서 우클릭을 쓰기 번거롭거나 터치로 조작할 때를 생각한 선택이다.

깃발 모드를 선택하고 닫힌 칸에 깃발을 꽂은 화면
깃발 모드로 닫힌 칸에 표시한 화면. 깃발을 꽂으면 위쪽 카운터도 함께 줄어든다.

여기서 카운터의 의미도 분명히 할 필요가 있었다. 이 숫자는 실제로 맞힌 지뢰 수가 아니라 지뢰 10개에서 꽂은 깃발 수를 뺀 값이다. 엉뚱한 곳에 깃발을 꽂아도 줄어든다. 카운터가 0이 됐다는 이유만으로 승리 처리하면 안 된다.

승리 조건은 처음 정한 대로 유지했다. 지뢰가 아닌 71칸을 모두 여는 것이다. 깃발은 내 판단을 표시하는 도구이고, 정답을 확인해 주는 도구는 아니다.

지는 화면과 다시 시작도 확인했다

진행 화면만 확인하고 끝내지 않고, 지뢰를 눌렀을 때의 화면과 다시하기도 살폈다. 지뢰를 밟으면 판의 지뢰가 드러나고 시간이 멈춘다. 다시하기를 누르면 판과 표시가 초기화되어 다음 첫 클릭을 기다린다.

지뢰를 눌러 게임이 종료되고 지뢰 위치가 드러난 화면
실행 중 지뢰를 눌러 확인한 종료 화면. 밟은 지뢰와 나머지 지뢰 위치를 볼 수 있다.

화면에서 확인하기 어려운 부분은 따로 검사했다. 첫 클릭의 위치를 바꿔도 보호되는지, 모서리의 숫자가 반대쪽 칸까지 세지 않는지, 깃발을 꽂아 둔 안전한 칸이 자동으로 열리지 않는지 등을 확인했다. 최종 규칙 테스트 12개가 통과했다. 첫 칸과 주변 칸을 보호하는 조건은 시작 위치 81곳에 각각 20가지 배치를 넣어 확인했다.

내 PC에서 실행하기

완성본은 minesweeper.html 한 파일이다. 스타일과 게임 코드를 안에 묶었기 때문에 파일을 내려받은 뒤에는 외부 라이브러리나 인터넷 연결이 필요 없다.

지뢰찾기 소스와 실행 파일 보기

저장소에서 minesweeper.html을 열고 원본 파일 다운로드 버튼으로 저장한 뒤, PC의 브라우저로 열면 된다. 코드가 적힌 웹페이지를 다른 이름으로 저장하는 방식과는 다르다.

  • 칸 열기: 열기 모드에서 클릭
  • 깃발: 오른쪽 클릭 또는 깃발 모드에서 클릭
  • 키보드: 방향키로 이동, Enter·Space로 선택, F로 깃발 전환
  • 새 판: 다시하기

화면은 같은 파일을 PC 내부 미리보기에서 실행해 캡처했다. 게임 규칙과 브라우저 조작을 확인했으며, PC마다 다른 로컬 파일 열기 환경까지 모두 시험한 것은 아니다.

이번에는 요청을 고치는 일이 남았다

Snake에서는 빠른 방향 입력과 안내문 표시를 고쳤다. 지뢰찾기에서는 첫 클릭의 범위를 바꿨다. 이번에 가장 오래 생각한 부분은 “틀린 코드를 어떻게 고칠까”보다 “어떤 시작 화면을 원했던 걸까”였다.

첫 칸에 숫자 2가 뜬 화면을 보지 않았다면, 아마 첫 클릭이 안전하다는 것만 확인하고 넘어갔을 것이다. 직접 눌러 보고 나니 다음 요청이 훨씬 구체적이 됐다. 다음 차례는 벽돌깨기다. 공이 움직이는 화면에서는 또 어떤 조정이 필요할지 확인해 보려고 한다.

다음 이전