Como garantir que uma grade possa ser preenchida com peças do tipo Tetris?

8

Estou pensando em fazer um jogo de quebra-cabeça em que o objetivo é preencher uma grade com peças de quebra-cabeça em forma (por exemplo, as formas clássicas de Tetris).

Como posso gerar um conjunto de peças que podem ser usadas para preencher a grade, sem deixar espaços? Como eu poderia adaptar esse algoritmo para dimensionar a dificuldade do quebra-cabeça resultante?

Baher Ramzy
fonte
11
Você permite duas ou duas peças quadradas?
Steven
@steven "monominos" e "dominós". Todas as peças clássicas de Tetris são tetrominos. Há 12 pentaminó e 35 hexominos ...
david van Brink

Respostas:

8

Este é um problema difícil conhecido, determinando quais retângulos podem ser lado a lado com certas peças.

No entanto, se você está criando quebra-cabeças e pode controlar as peças, é o oposto, o problema construtivo e mais fácil ...

Crie uma solução construtivamente. Pegue algumas peças que desejar e preencha o quebra-cabeça da maneira que desejar. Em seguida, coloque quadrados simples suficientes para preenchê-lo e você garantiu que há pelo menos uma solução. Ou melhor, inclua alguns pedaços pequenos no seu conjunto permitido.

Quanto à resolução / disposição das peças, uma abordagem típica de força bruta é preenchê-la da esquerda para a direita e depois de cima para baixo. Encontre a primeira célula aberta (LR numerada, TB) e tente colocar as peças permitidas nas orientações permitidas (8 orientações para uma peça assimétrica, se você permitir o lançamento). Talvez verifique as primeiras peças grandes permitidas e recorra a peças menores, se necessário. Quando você alcança um estado que não gosta (beco sem saída, muitos pedaços pequenos ou o que não gosta), então recua. Se um determinado conjunto de grade / peça não atender aos seus critérios, ou seja, voltar atrás sem terminar, tente um retângulo e um conjunto de peças diferentes.

Uma maneira de tornar um quebra-cabeça "mais fácil" poderia ser trocar peças maiores por peças menores, como monomino e dominó, pois isso deixará mais maneiras de preencher os últimos buracos. Ou, de forma equivalente, crie uma solução que favoreça essas partes menores.

Alguns polominologistas notáveis ​​incluem:

==> http://ee.usc.edu/faculty_staff/faculty_directory/golomb.htm Golomb originalmente cunhou o termo "Polyomino"

==> http://www.eklhad.net/polyomino/ Dahlke resolveu alguns retângulos cheios de peças idênticas (uma forma de mosaico particularmente rara)

david van brink
fonte
3

Este artigo (página 11-13, exoneração de responsabilidade: sou um dos autores) descreve um algoritmo que usa programação dinâmica para gerar uniformemente regiões retangulares lado a lado com largura w e altura h , em um tempo que é linear em h após um pré-processamento que leva cerca de 2 ( w . D ) tempo / espaço ( D sendo a dimensão mais longa de uma forma individual, por exemplo, 4 no caso de peças Tetris).

A idéia é semelhante à descrita por David acima e se concentra na faixa superior , colocando peças que não criam furos . O principal aqui é que você comece pré-computando as alternativas permitidas para cada estado da faixa superior, para que você não pague mais pela explosão combinatória ao gerar as regiões.

O algoritmo funciona para qualquer conjunto de formas (convexas).

Além disso, um aspecto interessante de uma geração aleatória uniforme é que ela garante a máxima diversidade entre gerações consecutivas (mas você também pode restringir a geração da maneira que desejar). Aqui estão algumas saídas típicas:

Algumas tetrises de largura 6 geradas aleatoriamente

Fique à vontade para perguntar se você está tendo problemas com a implementação (eu posso até ter uma implementação rápida e suja do Python por aí em algum lugar ...)

Yann Ponty
fonte
a implementação python que você mencionou seria muito útil
user2682863 30/01
1

Aqui está uma técnica que usamos no passado para enganar um pouco mais o hardware confinado. Não é tão puro quanto as soluções mais complexas, mas tem a vantagem distinta de ser muito mais fácil de implementar e funciona sempre.

Em vez de focar no quebra-cabeça inteiro, divida-o em unidades menores e uniformes . Cada uma dessas unidades é composta por um número definido de peças que se encaixam para formar quadrados ou retângulos que são muito mais fáceis de preencher em um quebra-cabeça. Escolha aleatoriamente as diferentes configurações para preencher a largura do quebra-cabeça (exemplos abaixo, mas há muitas, muitas configurações). Abaixo estão 4x4s, um 5x4 e até um exemplo de 10x4.

Quadrados e retângulos

A idéia é que você "decole" o quebra-cabeça ... escolha as larguras aleatoriamente com base na sala restante disponível. Quando uma "faixa" terminar, inicie uma nova faixa.

Você libera peças uma faixa de cada vez, aleatoriamente em cada conjunto de "faixas". Se você quiser aumentar a dificuldade, solte aleatoriamente de duas ou mais faixas por vez.

Usando essa técnica, você não apenas garantiu que o quebra-cabeça é solucionável, mas também ajudou a "enganar" a ordem de lançamento para facilitar a manutenção da vida. É claro que, na prática, os jogadores não são capazes de resolver perfeitamente cada faixa e, portanto, o caos ocorre.

Continue gerando listras até o jogador perder. Obviamente, meu exemplo é uma faixa de 4 blocos de altura, mas você pode escolher algo maior e mais complexo:

insira a descrição da imagem aqui

Rob Craig
fonte