Lanzamiento de 619 mil tetris en GLSL, su renderizado y un simple bot

Tuve una "idea" para hacer el n煤mero m谩ximo de Tetris ejecutando simult谩neamente para un sombreador (una textura de framebuffer).


La siguiente es una breve descripci贸n de c贸mo funciona el c贸digo resultante.


Que es esto:


Cada tetris funciona en tres p铆xeles, para una resoluci贸n de 1920x1080 puede ejecutar 619200 copias a la vez. Tambi茅n hizo un bot simple para auto-play.
Al final de la publicaci贸n enlaces a ejecutar y fuente.
Video actualizado, muestra el n煤mero de campos restantes, hasta cero.



Almacenamiento de datos


Tabla de Tetris de tama帽o [10, 22] (10 ancho, 22 alto).
Cada celda puede estar vac铆a o no vac铆a.
Se requiere un total de 22 * 10 = 220 bits para almacenar toda la tabla.
Un "p铆xel" son cuatro flotantes de 24 bits, 96 bits por p铆xel.


Visualmente (una parte del marco de depuraci贸n), tres p铆xeles se resaltan en rojo, este es un campo guardado:


imagen


2 * 96 + 24 + 4
Dos p铆xeles, un flotador del tercer p铆xel, 4 bits del segundo flotador del tercer p铆xel
Hay dos flotadores no utilizados en el tercer p铆xel pixel3.zw , almacenan el estado de la l贸gica , m谩s precisamente


  • z almacena tres n煤meros de ocho bits [a,b,c]
    - una posici贸n del bloque actual, como ID de la posici贸n en la matriz (una matriz de 220 bits de tama帽o, la posici贸n m谩xima es 220, que es menor que 0xff)
    - b tiempo hasta la ca铆da autom谩tica (temporizador) cada cuadro -1 a este n煤mero, ya que se convirti贸 en 0, entonces cae en el bloque hacia abajo
    - c ID del bloque actual
  • w tambi茅n [a,b,c] , pero tambi茅n el signo (positivo o negativo) de todo el flotador es la bandera del final del juego en la tabla actual (para no desperdiciar recursos si el campo est谩 abrumado )
    - una acci贸n, ninguna acci贸n (0), izquierda (1), derecha (2), etc., el c贸digo completo en Com煤n , las acciones tienen dos estados, marque a la izquierda y verifique si es posible moverse a la izquierda, luego la acci贸n se configura a la izquierda_mover .
    - [b,c] 0xffff (16 bits) puntos de la tabla actual, el n煤mero de l铆neas que se quemaron

Quedan 20 sin usar en el segundo flotante del tercer p铆xel.


marco de depuraci贸n que muestra que la l贸gica de guardado funciona correctamente
a la izquierda hay un campo blanco de tres p铆xeles de tama帽o, configurado espec铆ficamente para mostrar que los huecos se procesan correctamente (si la resoluci贸n no es un m煤ltiplo de tres, la tira ir谩 en 谩ngulo)
condici贸n en l铆nea 75 Buffer A


imagen


驴Por qu茅 necesito identificadores de acci贸n?


  • Los datos se almacenan en tres p铆xeles, es imposible verificar simult谩neamente la l贸gica y cambiar los datos en un cuadro (sin ejecutar toda la l贸gica y cargar todo el mapa en cada p铆xel, la carga aumentar谩 decenas de veces).
  • Por lo tanto, la l贸gica de almacenamiento de datos funciona en cada p铆xel y ejecuta los comandos recibidos left_ move , los comandos de verificaci贸n left_ check se ejecutan solo en un p铆xel (tercero).

Lugar lento


  • Cada tercer p铆xel (p铆xel l贸gico) descomprime todo el mapa (leyendo los tres p铆xeles).
  • Los dos p铆xeles restantes se descomprimen solo "ellos mismos" (un p铆xel) para realizar la acci贸n guardada.
  • Durante la acci贸n, la l铆nea se quem贸, se carg贸 otro p铆xel, ya que la tabla se cae y las partes inferiores de la tabla deben saber qu茅 hay encima.

Algoritmo de almacenamiento de rendimiento


Para la prueba, configure #define debug en Common y AI 0 all铆 tambi茅n.
Obtuve ese resultado : 10FPS al renderizar y procesar todos los campos 619200,
en 120 mil campos (25 fps)


imagen


L贸gica de bot


L贸gica Muy mal , el bot se quema en un minuto y obtiene hasta 60 puntos.


No pude comenzar una buena l贸gica con muchos ciclos de verificaci贸n de agujeros y repisas y campos combustibles, considerando la mejor posici贸n basada en todas las ca铆das posibles ...
La buena l贸gica funcion贸 para m铆 hasta 100 copias y dio un fuerte retraso al omitir todos los ciclos.


Mi l贸gica de bot funciona as铆
Toda la l贸gica est谩 en la funci贸n AI_pos_gen en el Buffer A, hay diez l铆neas.


Pseudoc贸digo:
la altura de verificaci贸n para la instalaci贸n del bloque es igual al m谩ximo para el campo en la columna actual (marque una l铆nea para la altura)


 (4   ){ (  (10)){ (     ){  (    ,  )   best ID()  best POS } } }  (     )   (  )      0     1 

Resulta que tres ciclos son comunes: colocan el bloque para que la altura sea m铆nima.


La funci贸n AI_pos_gen se llama cuando aparece un nuevo bloque, y devuelve la posici贸n para caer desde arriba , tomando la ID del bloque y haci茅ndola girar, la funci贸n funciona en el tercer p铆xel (l贸gica), es decir, tiene un mapa cargado completo (matriz de mapas).
Puede intentar escribir su bot f谩cilmente si lo desea.


Lugar m谩s lento
Al agregar solo un bucle para probar agujeros , el controlador de mi tarjeta de video se bloque贸 cuando el n煤mero de bots era m谩s de 10 mil ... el bot que escrib铆 es la versi贸n m谩s "minimalista" del bot que pude hacer, y desafortunadamente es muy malo.


Interfaz UI / Renderizado


Todo el renderizado en Imagen , l贸gica de IU en Buffer B.


Renderizado:
Dividir la pantalla en mosaicos y dibujar una tabla en cada mosaico, carga m铆nima.


L贸gica de cargar un mapa: cada p铆xel no est谩 descomprimido, cada p铆xel est谩 desempaquetado, solo el "bit requerido" est谩 desempaquetado (literalmente), el c贸digo de funci贸n es:


 int maptmp(int id, int midg) { int nBits = 8; ivec4 pixeldata = loadat(id, midg); int itt = (id / 24) / 4; //data pixel id 0-2 int jtt = (id - itt * 24 * 4) / 24; //component in data pizel id 0-3 int ott = (id - itt * 24 * 4 - jtt * 24) / 8; //component in unpacked value 0-2 int ttt = (id - itt * 24 * 4 - jtt * 24 - ott * 8); //bit after int2bit 0-7 ivec3 val = decodeval16(pixeldata[jtt]); int n = val[ott]; for (int i = 0; i < nBits; ++i, n /= 2) { if (i == ttt) { if ((n % 2) == 0)return 0; else return 1; //switch + return does not work on windows(Angle) /*switch (n % 2) { case 0:return 0;break; case 1:return 1;break; }*/ } } return 0; } 

Para evitar la pixelaci贸n durante el desplazamiento, a partir de 43000, se pierde la parte fraccional del flotador, y no funciona agregar 619 mil al UV para el desplazamiento (habr谩 p铆xeles en lugar de tablas).
Todo el desplazamiento se divide en un mosaico grande y gira en c铆rculo agregando un m谩ximo de 32 a UV. (l铆nea 207 en la imagen ).


Lo mismo se hace para determinar la ID del campo. (l铆nea 215 en la imagen )


UI


N煤meros:
El amarillo es el n煤mero de campos de tetris.
Izquierda grande: el n煤mero del campo actual.
En la esquina inferior derecha, los puntos del campo actual.


Fuente y lanzamiento


La l贸gica del Bufer A , el Bufer B es control de UI, representaci贸n de imagen
Fuente en https://www.shadertoy.com/view/3dlSzs (tiempo de compilaci贸n a trav茅s de Angle 16 sec)
El bot est谩 deshabilitado all铆 (puede habilitarlo), y todos los campos se pueden reproducir desde el teclado.


Controle las flechas izquierda / derecha / arriba / abajo.


Restablezca el rect谩ngulo rojo de la IU, mu茅vase (arrastre el mouse haciendo clic en LMB) y haga clic en los campos para desplazarse o seleccione el campo para mostrar.


Iniciar desde un navegador web:


  • ejecutar Chrome con chrome.exe --use-angle = gl
  • sigue el enlace a shadowrtoy
  • en el editor del sitio, seleccione Com煤n y elimine #define no_AI
  • (tambi茅n en Com煤n) establezca #define AI 199 en 0, es decir, #define AI 0
  • haga clic en el bot贸n de compilaci贸n (debajo de la ventana del editor en el sombreador) y haga clic en pantalla completa

La segunda opci贸n es ejecutar el sombreador en cualquier "lanzador de sombreadores", aqu铆 est谩 el enlace al archivo ( descarga ) en el que se encuentra el archivo * .exe con este sombreador.


Tiempo de compilaci贸n de OpenGL de unos 10 segundos.


Actualizaci贸n : se agreg贸 un sombreador con comprobaci贸n de agujeros https://www.shadertoy.com/view/wsXXzH
en lugar de la condici贸n para una mejor posici贸n a la misma altura. Se check_block_at_wh funci贸n check_block_at_wh (l铆nea 380 BufA) cuenta los agujeros junto con la verificaci贸n de la validez de la posici贸n, no se han agregado nuevos ciclos y la l铆nea de condici贸n 442 a 459 BufA.
Tambi茅n se quema r谩pidamente en un minuto dentro de 30-60 puntos. (Obviamente, debe verificar si hay agujeros en un 谩rea grande, pero esto da frenos fuertes)


Y dos fotos explicando un poco el trabajo:
selecci贸n de posici贸n https://i.imgur.com/e0uENgV.png
la posici贸n de bloqueo para la condici贸n es https://i.imgur.com/ORECXUW.png

Source: https://habr.com/ru/post/443042/


All Articles