Python 2.6+ - 334 322 316 caracteres
397 368 366 caracteres sin comprimir
exec'xÚEPMO!½ï¯ i,P*Ýlš%ì‰=‰Ö–*†þz©‰:‡—Lò¾fÜ”bžAù,MVi™.ÐlǃwÁ„eQL&•uÏÔ‹¿1O6ǘ.€LSLÓ’¼›î”3òšL¸tŠv[ѵl»h;ÁºŽñÝ0Àë»Ç‡ÛûH.ª€¼âBNjr}¹„V5¾3Dë@¼¡•gO. ¾ô6 çÊsÃЮürÃ1&›ßVˆùZ`Ü€ÿžcx±ˆ‹sCàŽ êüRô{U¯ZÕDüE+³ŽFA÷{CjùYö„÷¦¯Î[0þøõ…(Îd®_›â»E#–Y%’›”ëýÒ·X‹d¼.ß9‡kD'.decode('zip')
Se requiere la nueva línea única y la he contado como un carácter.
La palabrería de la página de códigos del navegador puede evitar que se pueda copiar y pegar correctamente este código, por lo que puede generar el archivo a partir de este código:
s = """
23 63 6F 64 69 6E 67 3A 6C 31 0A 65 78 65 63 27 78 DA 45 50 4D 4F 03 21
10 BD EF AF 20 69 2C 50 2A 02 DD 6C 9A 25 EC AD 07 8D 89 07 3D 89 1C D6
96 2A 86 05 02 1B AD FE 7A A9 89 3A 87 97 4C F2 BE 66 DC 94 62 9E 41 F9
2C 4D 56 15 69 99 0F 2E D0 6C C7 83 77 C1 16 84 65 51 4C 26 95 75 CF 8D
1C 15 D4 8B BF 31 4F 01 36 C7 98 81 07 2E 80 4C 53 4C 08 D3 92 BC 9B 11
EE 1B 10 94 0B 33 F2 9A 1B 4C B8 74 8A 9D 76 5B D1 B5 6C BB 13 9D 68 3B
C1 BA 8E F1 DD 30 C0 EB BB C7 87 DB FB 1B 48 8F 2E 1C AA 80 19 BC E2 42
4E 6A 72 01 7D B9 84 56 35 BE 33 44 8F 06 EB 40 BC A1 95 67 4F 08 2E 20
BE F4 36 A0 E7 CA 73 C3 D0 AE FC 72 C3 31 26 9B DF 56 88 AD F9 5A 60 DC
80 FF 9E 63 78 B1 88 8B 73 43 E0 8E A0 EA FC 52 F4 7B 55 8D AF 5A 19 D5
44 FC 45 2B B3 8E 46 9D 41 F7 7B 43 6A 12 F9 59 F6 84 F7 A6 01 1F AF CE
5B 30 FE F8 F5 85 28 CE 64 AE 5F 9B E2 BB 45 23 96 59 25 92 9B 94 EB FD
10 D2 B7 58 8B 64 BC 2E DF 39 87 6B 44 27 2E 64 65 63 6F 64 65 28 27 7A
69 70 27 29
"""
with open('golftris.py', 'wb') as f:
f.write(''.join(chr(int(i, 16)) for i in s.split()))
Pruebas
intetris
[]
[]
[]
[]
[# # #]
[## ######]
[==========]
T2 Z6 I0 T7
Las líneas nuevas deben ser de estilo Unix (solo salto de línea). Un salto de línea final en la última línea es opcional.
Probar:
> python golftris.py <intetris
[]
[]
[]
[# ###]
[# ###]
[##### ####]
[==========]
10
Este código descomprime el código original y lo ejecuta con exec
. Este código descomprimido pesa 366 caracteres y se ve así:
import sys
r=sys.stdin.readlines();s=0;p=r[:1];a='[##########]\n'
for l in r.pop().split():
n=int(l[1])+1;i=0xE826408E26246206601E>>'IOZTLSJ'.find(l[0])*12;m=min(zip(*r[:6]+[a])[n+l].index('#')-len(bin(i>>4*l&31))+3for l in(0,1,2))
for l in range(12):
if i>>l&2:c=n+l/4;o=m+l%4;r[o]=r[o][:c]+'#'+r[o][c+1:]
while a in r:s+=10;r.remove(a);r=p+r
print''.join(r),s
Se requieren nuevas líneas y son de un carácter cada una.
No intente leer este código. Los nombres de las variables se eligen literalmente al azar en busca de la compresión más alta (con diferentes nombres de variables, vi hasta 342 caracteres después de la compresión). A continuación se muestra una versión más comprensible:
import sys
board = sys.stdin.readlines()
score = 0
blank = board[:1]
full = '[##########]\n'
for piece in board.pop().split():
column = int(piece[1]) + 1
bits = 0xE826408E26246206601E >> 'IOZTLSJ'.find(piece[0]) * 12
drop = min(zip(*board[:6]+[full])[column + x].index('#') -
len(bin(bits >> 4 * x & 31)) + 3 for x in (0, 1, 2))
for i in range(12):
if bits >> i & 2:
x = column + i / 4
y = drop + i % 4
board[y] = board[y][:x] + '#' + board[y][x + 1:]
while full in board:
score += 10
board.remove(full)
board = blank + board
print ''.join(board), score
El quid está en las tres líneas crípticas que dije que explicaría.
La forma de los tetrominós está codificada en el número hexadecimal allí. Se considera que cada tetrónimo ocupa una cuadrícula de celdas de 3x4, donde cada celda está en blanco (un espacio) o completa (un signo de número). Luego, cada pieza se codifica con 3 dígitos hexadecimales, cada uno de los cuales describe una columna de 4 celdas. Los dígitos menos significativos describen las columnas más a la izquierda y el bit menos significativo de cada dígito describe la celda más alta de cada columna. Si un bit es 0, entonces esa celda está en blanco, de lo contrario es un '#'. Por ejemplo, el I tetronimo se codifica como 00F
, con los cuatro bits del dígito menos significativo activados para codificar los cuatro signos numéricos en la columna más a la izquierda, y la T es131
, con el bit superior establecido a la izquierda y a la derecha, y los dos bits superiores colocados en el medio.
El número hexadecimal completo se desplaza un bit hacia la izquierda (multiplicado por dos). Esto nos permitirá ignorar el bit más bajo. Explicaré por qué en un minuto.
Entonces, dada la pieza actual de la entrada, encontramos el índice en este número hexadecimal donde comienzan los 12 bits que describen su forma, luego lo desplazamos hacia abajo para que los bits 1–12 (saltando el bit 0) de la bits
variable describan la pieza actual.
La asignación drop
determina cuántas filas desde la parte superior de la cuadrícula caerá la pieza antes de aterrizar en otros fragmentos de pieza. La primera línea encuentra cuántas celdas vacías hay en la parte superior de cada columna del campo de juego, mientras que la segunda encuentra la celda ocupada más baja en cada columna de la pieza. La zip
función devuelve una lista de tuplas, donde cada tupla consiste en el n ° de células de cada elemento en la lista de entrada. Entonces, usando la placa de entrada de muestra, zip(board[:6] + [full])
devolverá:
[
('[', '[', '[', '[', '[', '[', '['),
(' ', ' ', ' ', ' ', ' ', ' ', '#'),
(' ', ' ', ' ', ' ', '#', '#', '#'),
(' ', ' ', ' ', ' ', ' ', '#', '#'),
(' ', ' ', ' ', ' ', ' ', ' ', '#'),
(' ', ' ', ' ', ' ', ' ', '#', '#'),
(' ', ' ', ' ', ' ', ' ', '#', '#'),
(' ', ' ', ' ', ' ', '#', '#', '#'),
(' ', ' ', ' ', ' ', ' ', '#', '#'),
(' ', ' ', ' ', ' ', ' ', '#', '#'),
(' ', ' ', ' ', ' ', '#', '#', '#'),
(']', ']', ']', ']', ']', ']', ']')
]
Seleccionamos la tupla de esta lista correspondiente a la columna apropiada, y buscamos el índice de la primera '#'
en la columna. Es por eso que agregamos una fila "completa" antes de llamar zip
, para que index
tenga un retorno sensato (en lugar de lanzar una excepción) cuando la columna está en blanco.
Luego, para encontrar el más bajo '#'
en cada columna de la pieza, cambiamos y enmascaramos los cuatro bits que describen esa columna, luego usamos la bin
función para convertir eso en una cadena de unos y ceros. La bin
función solo devuelve bits significativos, por lo que solo necesitamos calcular la longitud de esta cadena para encontrar la celda ocupada más baja (bit de conjunto más significativo). La bin
función también antepone '0b'
, así que tenemos que restar eso. También ignoramos el bit menos significativo. Es por eso que el número hexadecimal se desplaza un bit hacia la izquierda. Esto es para tener en cuenta las columnas vacías, cuyas representaciones de cadena tendrían la misma longitud que una columna con solo la celda superior llena (como la pieza T ).
Por ejemplo, las columnas de la I tetromino, como se mencionó anteriormente, son F
, 0
, y 0
. bin(0xF)
es '0b1111'
. Después de ignorar '0b'
, tenemos una longitud de 4, que es correcta. Pero bin(0x0)
es 0b0
. Después de ignorar '0b'
, todavía tenemos una longitud de '1, que es incorrecta. Para dar cuenta de esto, hemos agregado un bit adicional al final, para que podamos ignorar este bit insignificante. Por lo tanto, +3
en el código está ahí para tener en cuenta la longitud extra que ocupa al '0b'
principio y el bit insignificante al final.
Todo esto ocurre dentro de una expresión generadora para tres columnas ( (0,1,2)
), y tomamos el min
resultado para encontrar el número máximo de filas que la pieza puede caer antes de tocar en cualquiera de las tres columnas.
El resto debería ser bastante fácil de entender leyendo el código, pero el for
ciclo que sigue a estas asignaciones agrega la pieza al tablero. Después de esto, el while
ciclo elimina filas completas, reemplazándolas con filas en blanco en la parte superior y suma la puntuación. Al final, la pizarra y la puntuación se imprimen en la salida.