노노그램을 만드는 방법
여기의 모든 퍼즐은 평범한 그림으로 시작해서 논리만으로 풀 수 있는 격자로 완성됩니다. 그 사이에, 이미지를 래스터화하고, 결과가 실제로 풀 수 있는지 테스트하고, 풀 수 없는 것들을 버리는 자동화된 파이프라인을 거칩니다. 이 페이지는 그 과정을 정직하게 짚어 봅니다 — 실패하는 부분까지 포함해서요. 대부분의 작업은 좋은 퍼즐을 만드는 것이 아니라 나쁜 퍼즐을 걸러내는 데 있기 때문입니다.
1. 그림에서 시작한다
노노그램은 언제나 흑백 실루엣일 뿐입니다 — 음영도, 색상도, 내부 디테일도 없습니다. 그래서 첫 단계는 아주 작은 해상도에서도 형태가 또렷하게 읽히는 원본 이미지를 고르는 것입니다. 동물, 과일 한 조각, 별자리 기호, 생활용품 같은 것들이죠. 우리는 벡터 아트(SVG), 투명 PNG, 그리고 평범한 사진을 주제별 에셋 팩으로 정리해 작업하며, 여기에 앱 내 이미지 검색으로 가져온 이미지도 더합니다.
이 단계에서 중요한 것은 이미지가 얼마나 예쁜지가 아니라, 그 윤곽이 15×15 또는 20×20 격자로 짓눌려도 얼마나 잘 살아남는지입니다. 뚜렷하고 잘 분리된 형태는 통합니다. 작고 겹치는 부분이 많은 복잡한 장면은 거의 통하지 않으며, 그 이유는 아래에서 살펴봅니다.
2. 그림을 격자로 바꾸기
이미지는 실제 이미징 라이브러리(브라우저가 SVG를 위해 의존하는 것과 동일한 것)로 래스터화된 다음, 셀마다 하나의 흑 또는 백 값으로 축소됩니다. 그것을 하는 단 하나의 「올바른」 방법은 없으므로, 파이프라인은 여러 가지를 시도합니다. 이미지에 투명도가 있는 경우 그것을 단서로 삼거나, 단순한 밝기(어두움 = 채움)를 단서로 삼거나, 혹은 — 밝고 다채로운 피사체가 단색 배경 위에 있어 밝기만으로는 거의 분리되지 않는 경우 — 배경으로부터의 색 거리를 단서로 삼습니다. 흰 바탕 위의 밝은 주황색 여우는 밝기로는 거의 흰색이지만 색으로는 그와 크게 다릅니다. 색 거리 마스크가 그것을 깔끔하게 분리해 냅니다.
「채움」과 「빈칸」 사이의 경계는 Otsu's method를 사용해 자동으로 선택됩니다. 이는 이미지를 가장 깔끔하게 두 그룹으로 나누는 밝기 임곗값을 찾아내는 표준 기법입니다. 어떤 크기, 자르기, 임곗값이 가장 잘 읽힐지 미리 알 방법이 없기 때문에, 파이프라인은 이미지마다 많은 후보 격자를 생성하고 — 다양한 크기, 다양한 임곗값으로 — 각각을 채워진 내용에 맞게 자른 뒤, 형태를 격자의 비율에 맞춥니다. 그래서 폭이 넓은 왕관은 정사각형에 짓눌리는 대신 폭이 넓은 격자를 얻습니다.
3. 실제로 풀 수 있는지 확인하기
사람에게 괜찮아 보이는 이미지가 자동으로 유효한 퍼즐이 되는 것은 아닙니다. 진짜 노노그램은 행과 열 단서만으로 풀 수 있어야 하고 — 결정적으로 — 정확히 하나의 해를 가져야 합니다. 서로 다른 두 채움 패턴이 모두 모든 단서를 만족한다면, 그 퍼즐은 모호하고 불공정합니다. 순수한 논리를 따르는 풀이자가 「틀린」 그림에 올바르게 도달할 수도 있기 때문입니다.
그래서 모든 후보는 솔버에 넣어집니다. 솔버는 사람이 할 법한 것과 같은 행별 추론을 적용하고, 논리만으로는 막히는 지점에서는 완전한 해가 몇 개나 존재하는지 세기 위해 철저한 탐색으로 물러섭니다. 해가 0개(모순)이거나 1개를 초과(모호)하는 격자는 그 자리에서 거부됩니다. 이 유일성 검사는 파이프라인 전체에서 가장 중요한 관문입니다.
4. 추측이 아니라 논리임을 확실히 하기
해가 하나 있다고 해서 완전히 충분한 것은 아닙니다. 퍼즐은 기술적으로는 유일하지만 오직 시행착오로만 도달할 수 있을 수 있습니다 — 셀 하나를 채우고, 그것을 격자 깊숙이 따라가다가, 모순이 생기면 되돌아가는 식으로요. 그것은 푸는 것이 아니라 추측하는 것이며, 답답한 퍼즐을 만듭니다.
이를 잡아내기 위해, 우리는 각 퍼즐이 추론하기에 얼마나 어려운지를 분류합니다. 곧바른 행별 논리에서 풀려 나오는 퍼즐은 「단순」합니다. 잘 연구된 두 번째 단계의 연역(Batenburg and Kosters의 발표된 노노그램 난이도 연구에 기반)이 나머지 대부분을 아무런 추측 없이 처리합니다. 여전히 시행착오 없이는 해결할 수 없는 것은 추측이 필요한 것으로 표시되며 — 일상 카탈로그의 경우, 그런 것들은 공개되지 않고 한쪽으로 치워집니다.
5. 왜 많은 이미지가 끝내 채택되지 못하는가
풀이 작업에 앞서, 파이프라인은 이미지가 애초에 시도할 가치가 있는지도 두 가지 투박하지만 정직한 신호를 사용해 예측합니다. 하나는 분리 가능성입니다. 이미지가 애초에 두 색조로 얼마나 깔끔하게 나뉘는지 — 탁하고 대비가 낮은 원본은 어떤 크기에서든 나쁜 베팅입니다. 다른 하나는 디테일 대 해상도의 적합성입니다. 격자의 셀 수보다 훨씬 많은 미세한 특징을 가진 이미지는 그저 얼룩으로 뭉개져 버립니다.
우리 자신의 테스트에서 나온 구체적인 예입니다. 에펠탑의 실제 사진은 모든 풀이 가능성 검사를 통과한 40×40 후보를 만들어 냈습니다 — 유일한 해, 합리적인 채움 비율 — 하지만 꽉 찬 직사각형으로 렌더링되었습니다. 탑의 격자 디테일과 그 아래의 잡다한 것들이 하나의 구별 없는 블록으로 평평해진 것입니다. 기술적으로는 유효한 노노그램이지만, 시각적으로는 쓸모가 없습니다. 바로 그런 경우가 이 사전 검사들이, 그리고 사람의 눈길이 막아서기 위해 존재하는 것입니다. 한계를 분명히 해 두자면, 여기에는 비전 모델이 없습니다 — 파이프라인은 이미지에 *무엇이* 있는지 결코 인식하지 못하며, 그 형태가 얼마나 잘 변환되는지를 측정할 뿐입니다. 그래서 최종 결정은 여전히 사람의 몫입니다.
6. 평가, 그리고 마지막 사람의 눈길
모든 관문을 통과한 퍼즐은 풀이 단계와 형태 통계(격자가 얼마나 채워졌는지, 그림이 가장자리 밖으로 뻗어 나가는지 등)로부터 난이도 등급을 받으며, 이것이 그것들을 쉬움, 보통, 어려움 모음으로 분류합니다. 그다음 사람이 카탈로그로 향하는 것들을 우리 격자 편집기에서 열어, 그림이 정말로 의도한 대로 읽히는지 확인하고, 자동 검사가 통과시켰지만 통과시키지 말았어야 할 것을 조정하거나 폐기합니다.
이것은 의도적으로 화려하지 않은 과정이며, 바로 그 점이 핵심입니다. 자동화는 공정성 — 하나의 해, 논리로 풀 수 있음 — 을 보장하기 위해 존재하고, 그동안 사람은 컴퓨터가 판단할 수 없는 것, 즉 완성된 그림이 과연 좋은지를 지킵니다.
이것이 코드를 뺀 파이프라인의 전부입니다. 그것이 어떻게 만들어지는지 읽기보다 하나를 직접 풀어 보고 싶다면, 오늘의 퍼즐이 시작하기 좋은 곳입니다.
