Dos negras por región, parejas sin fronteras
Las reglas de Norinori
El tablero está dividido en regiones. Cada región debe contener exactamente dos casillas negras. Además, las negras aparecen formando parejas ortogonales: cada casilla negra debe tocar por un lado a exactamente otra negra. La pareja puede atravesar la frontera entre regiones.
La combinación es engañosa. Las restricciones locales parecen sencillas, pero la regla de emparejamiento conecta decisiones que pueden estar a varios pasos de distancia.
Un puzzle original de Nikoli
Nikoli incluye Norinori entre sus puzzles de sombreado y resume sus dos reglas esenciales: colocar bloques negros de dos en dos y conseguir que cada área delimitada contenga dos casillas negras. Es un ejemplo de cómo pocas reglas pueden producir profundidad cuando interactúan entre fronteras distintas.
El primer generador parecía correcto
Nuestra primera aproximación partía de una disposición válida de casillas negras y generaba regiones alrededor. A simple vista, los tableros cumplían las reglas y se podían resolver.
Después añadimos un selfTest() que pedía al solver contar soluciones. Aparecieron alternativas. El tablero tenía una solución conocida, pero no una solución única.
Conocer una respuesta no demuestra que hayas construido una pregunta bien definida.
Bloquear la PR era la decisión de producto
Podíamos haber relajado la prueba, aceptar la implementación y declarar el generador terminado. Habríamos conseguido más variedad a costa de algo que el jugador no puede verificar hasta muy tarde: la confianza de que existe una deducción única.
Preferimos bloquearla. CI no estaba frenando el desarrollo; estaba defendiendo una propiedad del producto.
El segundo intento también falló
Cambiamos la estrategia: primero crear regiones y después buscar una solución. Seguía pareciendo razonable, pero las particiones aleatorias producían demasiadas configuraciones equivalentes. De nuevo no podíamos demostrar unicidad de forma consistente.
Una retirada deliberada
En lugar de rebajar el estándar, cambiamos el alcance. Localizamos una instancia abierta y conocida del ecosistema pzprjs, reconstruimos nuestra representación nativa y usamos el solver para verificar variantes por rotación y reflexión.
El resultado tiene menos variedad que el generador que queríamos, pero es correcto y reproducible. Eso nos parece un estado intermedio mucho más honesto.
Por qué la unicidad es difícil aquí
Las regiones imponen conteos, pero una pareja puede cruzar sus fronteras. Eso crea simetrías y alternativas que no son evidentes mirando cada zona de forma aislada. Un cambio local puede conservar todos los conteos y reorganizar parejas en otra parte.
Un futuro generador necesita diseñar las regiones precisamente para romper esas simetrías, no esperar que desaparezcan por azar.
- partir de estructuras de parejas controladas;
- crear regiones que añadan información útil;
- contar soluciones después de cada transformación;
- rechazar candidatos ambiguos pronto;
- medir dificultad además de corrección.
Cómo empezar a resolver
Busca regiones pequeñas o estrechas: al tener que contener exactamente dos negras, suelen limitar rápido las posibilidades. Después vigila la regla de pareja. Una negra no puede terminar conectada con tres negras ni quedarse aislada.
Es útil pensar en dominós. No colocas «negras sueltas»: intentas decidir qué parejas pueden existir y cómo cada una consume casillas de las regiones que toca.
La lección se ha extendido a otros motores
Norinori reforzó una práctica que ahora aplicamos de forma más general: el generador propone y un solver independiente verifica. También nos enseñó que un fallo de self-test puede revelar un defecto conceptual, no solo una implementación rota.
Eso ha influido en cómo pensamos Nonogram, LITS, Logic Grid y otros juegos procedurales.
Juegos relacionados
Si te gusta Norinori, prueba LITS, donde cada región aloja un tetrominó; Heyawake, que combina regiones y sombreado; Nurikabe, con componentes blancos y una pared negra conectada; o Star Battle, donde las regiones se cruzan con restricciones de filas y columnas.
Fuente principal
Estado actual: motor verificado, juego todavía coming-soon
Norinori tiene un engine nativo 5×5, un solver independiente y ocho variantes canónicas obtenidas por transformaciones. El manifiesto, sin embargo, sigue marcado como coming-soon. Esta entrada documenta el motor y sus pruebas sin confundirlas con disponibilidad pública.
Dos reglas simples producen una restricción global
Cada región debe contener exactamente dos casillas negras. Además, cada casilla negra debe tocar ortogonalmente exactamente a otra negra, formando dominós aislados. Una pareja puede cruzar fronteras de región, de modo que las dos reglas no se resuelven por separado: se cruzan constantemente.
La pareja es la unidad estratégica real
Marcar una negra aislada no basta. Desde el momento en que aparece, necesitamos saber con qué vecina podría formar su único contacto ortogonal. Si dos opciones sobreviven, ambas condicionan regiones distintas. Pensar en dominós reduce errores y acerca la estrategia humana al modelo del solver.
Las regiones controlan cantidad, no pertenencia de la pareja
Una región exige dos negras, pero no dice que esas dos formen pareja entre sí. Cada una puede emparejarse con una casilla situada en otra región. Esa libertad crea dependencias que hacen al puzzle más interesante y también más difícil de generar sin ambigüedad.
El primer generador procedural no superó unicidad
La historia del proyecto ya registraba intentos de construir solución y regiones de forma procedural. Los tableros podían parecer correctos y tener una solución conocida, pero el solver encontraba alternativas. Ese fallo convirtió unicidad en un gate explícito en lugar de una suposición.
Conocer una solución no demuestra una pregunta bien definida
Este principio se repite en Blupoli. Una construcción completa es solo un testigo de existencia. Si el producto pretende una solución única, necesita contar alternativas o demostrar una propiedad equivalente.
La retirada a fixtures verificables fue una decisión de calidad
En lugar de publicar generación infinita dudosa, el motor actual utiliza una base canónica y obtiene ocho variantes por rotaciones y reflexiones. Cada una pasa el solver. La variedad es menor, pero la propiedad importante está demostrada.
Ocho variantes no significan ocho puzzles lógicamente distintos en profundidad
Transformar una instancia preserva estructura. Cambia orientación y disposición visual, pero no crea una nueva distribución de dificultad. Por eso no debemos vender las transformaciones como si fueran ocho niveles independientes calibrados.
El self-test exige exactamente una solución
Para cada variante, llama al solver con límite dos y falla si recibe una cantidad distinta de uno. También valida que la solución encontrada cumpla las reglas completas. Es una garantía clara y directamente conectada con el contenido actual.
El contador con corte en dos ahorra trabajo
Si aparece una segunda solución, el candidato ya no sirve para una promesa de unicidad. No necesitamos saber si existen tres o trescientas. Detener búsqueda en dos alinea coste computacional con la decisión de producto.
El solver necesita podar por región y por emparejamiento
Una región con demasiadas negras es contradicción inmediata. También lo es una negra con más de una vecina negra o una casilla negra que ya no puede encontrar pareja. Combinar estos límites locales reduce el espacio antes de ramificar.
Las casillas blancas también contienen información
Declarar una celda blanca elimina posibles parejas y puede forzar la única vecina disponible de otra negra. Como en muchos puzzles de sombreado, el estado negativo no es ausencia de decisión: forma parte de la deducción.
Las regiones pequeñas son buenos puntos de entrada
Una región estrecha o con pocas combinaciones posibles puede fijar rápidamente dónde deben ir sus dos negras. Después, la regla de pareja transporta esa información a regiones vecinas.
Una negra con una única pareja posible fuerza dos cosas a la vez
Fija su compañera y, al mismo tiempo, prohíbe otras vecinas negras alrededor de ambas. Esa propagación puede cerrar cuotas regionales y producir una cadena. El puzzle se vuelve interesante cuando las dos reglas se alternan.
Dos dominós distintos no pueden tocarse ortogonalmente
La formulación del manifiesto deja claro que las parejas son aisladas entre sí por contacto ortogonal, aunque el contacto diagonal está permitido. Esa regla debe existir en validator, solver, tutorial y copy con exactamente la misma semántica.
El validator y el solver deberían compartir contrato, no implementación ciega
Un validator de solución completa puede comprobar conteos regionales y grado ortogonal de cada negra. El solver usa esas mismas reglas para podar estados parciales. Tests con fixtures terminados pueden asegurar que ambos caminos están de acuerdo.
La dificultad actual no está calibrada como un generador abierto
Con un conjunto pequeño de variantes transformadas, no tiene sentido afirmar niveles de dificultad ricos si no los hemos medido. Antes de añadir etiquetas, conviene instrumentar pasos de propagación, branches y posiciones forzadas.
Un futuro generador debería romper simetrías deliberadamente
Los intentos aleatorios fallaron porque las regiones permitían reorganizar parejas sin violar conteos. Una estrategia mejor puede partir de dominós controlados y diseñar fronteras que aporten información específica para eliminar alternativas.
Generar regiones después de parejas puede ser una línea de trabajo
Si conocemos una estructura de dominós, podemos construir regiones que contengan exactamente dos negras pero que restrinjan suficientemente las sustituciones. Cada modificación debería pasar el contador antes de aceptarse.
Otra opción es empezar por regiones con dominios pequeños
En lugar de particiones arbitrarias, podemos usar patrones de regiones cuya geometría limite las ubicaciones de dos negras. Combinar bloques diseñados y luego variar conexiones puede producir diversidad sin abrir tanto el espacio de soluciones.
El solver debe convertirse en parte del generador
No basta con ejecutarlo al final. Si una operación de mutación introduce ambigüedad, detectarla pronto permite revertir y seguir. El contador puede guiar clue removal o cambios de fronteras igual que en otros generadores.
La reproducibilidad será imprescindible en cualquier generación futura
Una seed debe reconstruir regiones y decisiones del generador. Cuando aparezca un caso ambiguo o lento, QA necesita repetirlo exactamente y convertirlo en regresión.
La latencia de unicidad necesita presupuesto
Un generador que prueba muchas particiones puede gastar tiempo rápidamente. La búsqueda debería tener deadline y salida segura. Si no consigue demostrar unicidad a tiempo, el candidato se rechaza; el producto no debe interpretar timeout como éxito.
Timeout, ambigüedad y contradicción son resultados diferentes
Separarlos mejora diagnóstico. Ambigüedad indica una estructura demasiado débil; contradicción una estructura imposible; timeout un coste excesivo. Mezclar los tres haría más difícil mejorar el generador.
El onboarding puede enseñar la pareja antes que la región
Una mini escena eficaz puede mostrar una negra y preguntar dónde puede estar su única compañera. El siguiente paso introduce la cuota de dos por región. Enseñar las reglas por capas hace visible por qué luego interactúan.
Los hints pueden señalar una regla forzada
Una pista puede decir que cierta región ya tiene dos negras y el resto debe ser blanco, o que una negra conserva una única pareja posible. Son explicaciones derivadas del dominio, no respuestas arbitrarias.
La UI necesita distinguir región, sombreado y pareja
Las fronteras regionales deben ser legibles sin competir con el sombreado. Además, cuando dos negras forman pareja puede ser útil un feedback sutil, pero no debería introducir una conexión que parezca una regla nueva.
Responsive tiene que preservar fronteras gruesas
En un 5×5 la cuadrícula es compacta, pero en móvil las fronteras de región y targets táctiles deben seguir claros. Reducir todo proporcionalmente puede hacer que líneas importantes desaparezcan.
El teclado puede mapear negro, blanco y desconocido
Una interacción de tres estados se beneficia de teclas claras y foco visible. Cualquier atajo debe tener equivalente en controles accesibles y etiquetas comprensibles.
Persistencia debe conservar regiones y marcas
Un save necesita la variante o regiones materializadas y el estado de cada celda. Si en el futuro cambia la lista de variantes, un identificador versionado evita que una partida antigua cargue con otra geometría.
Los resultados pueden identificar la variante
Tiempo o errores solo son comparables cuando sabemos qué instancia se jugó. Con ocho transformaciones, un código de variante permite reintentos y soporte sin exponer la solución.
Retry debe conservar la misma geometría
Reintentar es útil para aprender una lógica concreta; nueva partida puede escoger otra transformación. La diferencia debería ser explícita en UI y resultados.
Las transformaciones deben conservar semántica
Rotar o reflejar regiones requiere transformar todas las referencias de forma consistente. El self-test de las ocho variantes actúa también como protección frente a errores de índices o coordenadas.
La base canónica merece provenance
Si procede de una instancia pública o de un fixture interno, el repositorio debería documentar su origen y licencia cuando sea relevante. La transformación técnica no elimina la responsabilidad de mantener contexto sobre el contenido base.
La taxonomía puede describir sombreado, regiones y emparejamiento
Esas son acciones observables y suficientes para descubrimiento. No necesitamos prometer beneficios cognitivos. El criterio coincide con la taxonomía responsable de Blupoli.
Los visuales de esta revisión explican las dos capas
La infografía muestra regiones que exigen dos negras y dominós que pueden atravesar sus fronteras. Esa relación es el corazón del puzzle y del algoritmo, más útil que una captura decorativa.
Qué falta para considerar Norinori terminado
El contenido actual tiene una garantía de unicidad fuerte para sus ocho variantes. Falta cerrar la experiencia: onboarding, responsive, accesibilidad, persistencia, resultados y quizá una estrategia de variedad mayor que mantenga el mismo estándar.
La lección principal es preferir menos contenido demostrado
Norinori documenta una decisión importante del proyecto: cuando la generación infinita no podía demostrar unicidad, elegimos un conjunto pequeño verificable. Escalar después desde una base fiable es mejor que publicar ambigüedad disfrazada de variedad.
El solver debería elegir primero estados muy restringidos
Cuando varias casillas siguen desconocidas, ramificar sobre cualquiera funciona pero puede ser caro. Elegir una celda cuya región esté casi completa o cuya posibilidad de pareja sea mínima tiende a descubrir contradicciones antes. El principio “most constrained first” es especialmente natural aquí porque región y vecindad ofrecen límites fuertes.
Las cuotas regionales producen límites inferiores y superiores
En cada estado parcial sabemos cuántas negras tiene una región, cuántas faltan y cuántas casillas desconocidas quedan. Si ya hay más de dos, la rama muere. Si ni convirtiendo todas las desconocidas en negras alcanza dos, también. Estas comprobaciones son baratas y evitan búsqueda innecesaria.
La pareja potencial añade otra capa de poda
Una negra sin vecina negra debe conservar al menos una vecina desconocida capaz de convertirse en pareja. Si todas están blancas, el estado es imposible. Si solo queda una, esa celda puede forzarse negra y el resto de vecinos ortogonales pasan a blanco.
Una pareja completa propaga blancos alrededor
Cuando dos negras ya forman su único contacto, cualquier otra vecina ortogonal de ambas debe ser blanca. Esa deducción puede completar una cuota regional y, a su vez, forzar nuevas negras en otra zona. La fuerza del puzzle está en alternar estos dos sistemas de restricciones.
Las trazas semánticas pueden servir para hints
En lugar de registrar únicamente “celda 12 pasó a negra”, el solver puede emitir motivos como “cuota regional completa”, “única pareja disponible” o “pareja cerrada obliga blancos”. Un producto de hints puede seleccionar esas razones y expresarlas al jugador sin exponer la búsqueda completa.
Una traza de recursión no es una explicación
El orden en que el backtracking explora valores puede depender de heurísticas internas y no corresponder a una deducción humana útil. Separar eventos semánticos de pasos de búsqueda permite optimizar el solver sin romper la capa pedagógica.
Las ocho variantes actuales deberían permanecer como regresiones
Aunque llegue un generador procedural, los casos canónicos siguen siendo valiosos. Son pequeños, conocidos y tienen una solución demostrada. Cualquier refactor del solver puede compararse contra ellos para verificar conteo y tiempo.
Los bugs futuros pueden ampliar ese corpus
Cada seed ambigua, lenta o rota que aparezca durante desarrollo puede convertirse en fixture retenida. La suite crece con fallos reales y documenta qué límites han ido apareciendo en el engine.
Un generador futuro debería medir tasa de rechazo
Si de cien candidatos noventa y nueve son ambiguos, quizá la estrategia de construcción no está aportando suficientes restricciones. Métricas de contradicción, ambigüedad y timeout ayudan a comparar algoritmos antes de juzgarlos por unas pocas partidas aceptadas.
La unicidad puede utilizarse durante la mutación
Podemos partir de una instancia única y realizar cambios controlados en fronteras. Después de cada mutación contamos soluciones; si aparece una segunda, revertimos. Esta búsqueda guiada puede producir variedad preservando una propiedad ya conocida.
Las transformaciones también pueden combinarse con cambios locales
Rotación y reflexión dan variedad gratuita porque preservan semántica. A partir de ellas, pequeñas modificaciones verificadas podrían ampliar el catálogo sin empezar cada generación desde cero. El contador sigue siendo la autoridad final.
La memoria del solver merece medición
En 5×5 el espacio es pequeño, pero un generador futuro con tamaños mayores puede copiar muchos arrays por rama. Antes de aumentar escala conviene medir y valorar rollback o representaciones compactas. Optimizar solo tiempo puede esconder un crecimiento de memoria innecesario.
Un worker puede aislar búsqueda pesada
Si el conteo de soluciones se vuelve perceptible, un Web Worker puede mantener responsive la UI. El contrato debería intercambiar regiones y estados serializables, nunca nodos DOM. Además, necesita cancelación para descartar búsquedas de partidas que ya no son activas.
El modo móvil necesita una forma clara de marcar blanco
Si click cicla estados, el gesto debe ser igual de fiable en touch. Botón derecho no puede ser requisito. Controles auxiliares o pulsaciones explícitas pueden reducir errores, siempre con targets suficientemente grandes.
Los bordes regionales son parte de la información, no decoración
Contraste insuficiente puede hacer que dos regiones parezcan una sola y cambiar la interpretación del puzzle. Temas claro y oscuro deben conservar jerarquía entre cuadrícula normal y frontera gruesa.
La accesibilidad puede anunciar región y vecinos
Una celda enfocada podría exponer fila, columna, estado y región. Cuando una negra necesita pareja, un hint accesible puede describir cuántas posiciones ortogonales siguen disponibles. Traducir estructura espacial a texto hace el puzzle más navegable.
Persistencia debería guardar la geometría materializada
Un identificador de variante basta mientras la lista canónica no cambie, pero guardar regiones o una versión protege saves históricos frente a refactors. El estado de las celdas y cualquier historial de undo deben referirse a la misma geometría.
Los resultados no deberían mezclar variantes sin contexto
Aunque las ocho transformaciones sean lógicamente equivalentes, orientación y lectura visual pueden afectar duración. Un resultado puede conservar variante y versión para que comparaciones y soporte sigan siendo reproducibles.
El estado coming-soon ofrece una ventaja
Podemos mantener una garantía algorítmica fuerte mientras terminamos producto sin presión de ocultar limitaciones. La etiqueta permite que “una solución exacta en los fixtures” y “experiencia pública completa” sigan siendo afirmaciones separadas.
Publicar debería exigir un checklist transversal
Además del self-test: móvil, teclado, temas, reduced motion, onboarding, persistencia, retry, resultados y restauración. El motor ya protege la matemática; la plataforma debe proteger todo lo demás.
La variedad futura no debería rebajar el estándar actual
Cuando añadamos generación, cada nuevo tablero debe alcanzar como mínimo la misma evidencia que las variantes canónicas: exactamente una solución y reglas completas válidas. “Más contenido” no puede significar “menos demostrado”.
Norinori es una lección sobre saber retirarse
Reemplazar un generador ambicioso por fixtures verificables puede parecer un paso atrás en cantidad, pero fue un avance en calidad. Reconocer que una abstracción o algoritmo todavía no merece producción es una habilidad de ingeniería tan importante como construirlo.