Estoy pensando en hacer un juego de rompecabezas donde el objetivo es llenar una cuadrícula con piezas de rompecabezas con forma (por ejemplo, las formas clásicas de Tetris).
¿Cómo puedo generar un conjunto de piezas que puedan ser utilizadas para llenar la cuadrícula, sin dejar espacios en blanco? ¿Cómo podría adaptar este algoritmo para escalar la dificultad del rompecabezas resultante?
Respuestas:
Este es un problema difícil conocido, que determina qué rectángulos se pueden colocar en mosaico con ciertas piezas.
Sin embargo, si estás construyendo rompecabezas y puedes controlar las piezas, es el problema opuesto, constructivo y más fácil ...
Desarrolle una solución de manera constructiva. Toma algunas piezas que te gusten y llena el rompecabezas como quieras. Luego agregue suficientes cuadrados individuales para completarlo, y ha garantizado que hay al menos una solución. O más bien, incluya algunas piezas pequeñas en su conjunto de piezas permitido.
En cuanto a la resolución / disposición de las piezas, un enfoque típico de fuerza bruta es llenarlo de izquierda a derecha, luego de arriba a abajo. Encuentre la primera celda abierta (numerada LR, TB) e intente colocar las piezas permitidas en sus orientaciones permitidas (8 orientaciones para una pieza asimétrica si permite voltear). Quizás revise las primeras piezas grandes permitidas y recurra a las más pequeñas si es necesario. Cuando llegas a un estado que no te gusta (callejón sin salida, demasiadas piezas pequeñas o lo que no), retrocede. Si un conjunto de cuadrícula / pieza dado no cumple con sus criterios, es decir, retrocedió completamente sin terminar, pruebe con un conjunto de rectángulo y pieza diferente.
Una forma de hacer un rompecabezas "más fácil" podría ser cambiar piezas más grandes por piezas más pequeñas como monominoes y dominó, ya que esto dejará más formas de completar los últimos agujeros. O, de manera equivalente, cree una solución que favorezca esas piezas más pequeñas.
Algunos poliominólogos destacados incluyen:
==> http://ee.usc.edu/faculty_staff/faculty_directory/golomb.htm Golomb acuñó originalmente el término "Polyomino"
==> http://www.eklhad.net/polyomino/ Dahlke ha resuelto bastantes rectángulos llenos de piezas idénticas (una forma de mosaico particularmente rara)
fuente
Este artículo (página 11-13, descargo de responsabilidad: soy uno de los autores) describe un algoritmo que usa programación dinámica para generar uniformemente regiones rectangulares perfectamente en mosaico de ancho w y altura h , en el tiempo que es lineal en h después de un preprocesamiento que ocupa aproximadamente 2 ( w . D ) tiempo / espacio ( D es la dimensión más larga de una forma individual, por ejemplo, 4 en el caso de piezas de Tetris).
La idea es similar a la descrita por David arriba, y se enfoca en la tira superior , colocando piezas que no crean agujeros . La clave aquí es que comience precalculando las alternativas permitidas para cada estado de la franja superior, de modo que ya no pague por la explosión combinatoria cuando genere las regiones.
El algoritmo funciona para cualquier conjunto de formas (convexas).
Además, un aspecto interesante de una generación aleatoria uniforme es que garantiza la máxima diversidad entre generaciones consecutivas (pero también puede restringir la generación de la forma que desee). Aquí hay algunos resultados típicos:
No dude en preguntar si tiene problemas con la implementación (incluso podría tener una implementación rápida y sucia de Python por ahí ...)
fuente
Aquí hay una técnica que hemos usado en el pasado para engañar un poco a un hardware más confinado. No es tan puro como las soluciones más complejas, pero tiene la clara ventaja de ser mucho más fácil de implementar y funciona cada vez.
En lugar de centrarse en todo el rompecabezas, divídalo en unidades más pequeñas y uniformes . Cada una de estas unidades se compone de un número establecido de piezas que se unen para formar cuadrados o rectángulos que son mucho más fáciles de completar en un rompecabezas. Elija al azar de las diferentes configuraciones para llenar el ancho del rompecabezas (ejemplos a continuación, pero hay muchas, muchas configuraciones). A continuación se muestran 4x4, 5x4 e incluso un ejemplo de 10x4.
La idea es que "raya" el rompecabezas ... elija los anchos aleatoriamente en función del espacio restante disponible. Una vez que haya terminado una "franja", comience una nueva franja.
Libera piezas una franja a la vez aleatorizando dentro de cada conjunto de "franjas". Si desea aumentar la dificultad, suelte aleatoriamente de dos o más franjas a la vez.
Usando esta técnica, no solo has garantizado que el rompecabezas es solucionable, también has ayudado a "engañar" el orden de lanzamiento para que sea más fácil mantenerse con vida. Por supuesto, en la práctica, los jugadores no pueden resolver perfectamente cada raya, por lo que se produce el caos.
Sigue generando rayas hasta que el jugador pierda. Por supuesto, mi ejemplo es una franja de 4 bloques de altura, pero puedes elegir algo más grande y más complejo:
fuente