Gravedad

Definición de retos

Esta página trata sobre el formato usado por Gravedad para definir sus retos.

Los retos locales se guardan en ficheros de texto independientes con un formato muy sencillo, consistente en un conjunto de órdenes o directivas de una sola línea. Los retos incorporados de antemano al programa tienen el mismo formato, solo que están agrupados en ficheros más grandes, uno por cada conjunto y no son accesibles al usuario.

Cada línea debe comenzar con una palabra especial, algunas de las cuales deben llevar a continuación un texto sin entrecomillar o un cierto número de valores numéricos. Algunas palabras son obligatorias y otras (la mayoría) opcionales. El orden de las líneas no importa.

Gravedad no está preparada para detectar errores o inconsistencias en los ficheros de retos, así que algunos errores pueden tener consecuencias inesperadas o hacer que el programa se interrumpa.

Hay palabras clave que solo deben aparecer una vez (o ninguna). Por ejemplo, las dimesiones del tablero solo hace falta decirlas una vez con la palabra clave dim. Otras en cambio se podrían calificar de «acumulativas». Un ejemplo es la directiva que sitúa la posición inicial de una ficha, que puede aparecer varias veces (una para cada ficha). Si aparece dos veces una palabra clave del primer tipo solo se tendrá en cuenta la última (aunque no es que haya ninguna razón para hacerlo). El efecto de las del segundo tipo se va acumulando: una vez establecido que una ficha debe estar colocada al principio en cierta casilla no hay se puede quitar con otra directiva posterior.

Se pueden añadir líneas en blanco y comentarios precedidos del carácter $.

Veamos todas las palabras clave una por una.

nombre

Indica el nombre del reto, que en ocasiones puede ser de tipo «Nivel 1». En los conjuntos incorporados de serie es obligatoria y debe aparecer al principio de cada reto, pero en un fichero local puede aparecer en cualquier lugar e incluso omitirse. Ejemplo:

nombre Nivel 1

dim x y

Directiva obligatoria que debe ir seguida de dos números enteros mayores que 1, representando el número de columnas (x) y de filas (y) del tablero. Ejemplo:

dim 4 4

ficha x y
posini x y

Cualquiera de estas palabras clave se puede usar para establecer la posición inicial de una ficha. Los argumentos indican las coordenadas de una casilla, empezando a contar por 0 desde la esquina superior izquierda.

La primera ficha declarada será la número 0, la segunda la número 1, etc. Ejemplo:

ficha 0 0

fichas x1 y1 x2 y2...

Para ir más rápido se pueden declarar varias fichas (incluso todas) de una vez con esta otra opción. El número de argumentos debe ser par y no se deben incluir comas. Ejemplo:

fichas 0 0 1 0

En todos los retos debe haber al menos una ficha, así que su definición debe incluir alguna de las palabras clave posini, ficha o fichas.

destino x y
posfin x y

Cualquiera de estas palabras clave establece una casilla de destino. Las coordenadas de la casilla siguen el mismo criterio explicado con respecto a las fichas. Ejemplo:

destino 3 3

destinos x1 y1 x2 y2...

Versión abreviada que permite definir todos (o algunos de) los destinos en una sola línea. El número de argumentos debe ser par y no se deben incluir comas. Ejemplo:

destinos 2 3 3 3

Los destinos se numeran internamente (se vean o no los números) según el orden en que son declarados. Es habitual que el número de fichas y de destinos coincidan, pero no es obligatorio. Veremos esto mejor cuando tratemos sobre otras directivas.

No es obligatorio que haya casillas de destino, también puede haber uno o más agujeros (como en el conjunto Marble Mazes).

paredv fil n
obstv fil n

Cualquiera de estas directivas define una pared vertical en la posición n de la fila fil. Las filas se numeran desde arriba empezando por el 0. Dentro de cada fila las posiciones se numeran de izquierda a derecha empezando por el 0. Ejemplo:

dim 4 3
paredv 1 2

En la siguiente imagen se ve dónde estaría la pared:

paredesv n1 n2...

En lugar de especificar cada pared vertical una a una podemos usar esta otra directiva para decirlas todas juntas (o algunas de ellas). En este caso los argumentos son enteros de 0 en adelante, empezando a contar de izquierda a derecha las paredes verticales de la primera fila, después de la segunda, etc. La pared del ejemplo anterior sería la número 5. Ejemplo:

dim 4 3
paredesv 0 5 7

El tablero resultante es:

Obviamente no es obligatorio que un reto contenga paredes verticales ni horizontales.

paredh col n
obsth col n

Estas son las directivas análogas a las vistas antes para definir una pared horizontal. En este caso col es una columna (0 la de la izquierda, 1 la siguiente, etc.) y n la posición que ocupa la pared horizontal dentro de la columna. Dentro de cada columna las posiciones se numeran de arriba abajo empezando por el 0. Ejemplo:

dim 4 3
paredh 2 1

En la siguiente imagen se ve dónde estaría la pared:

paredesh n1 n2...

Del mismo modo que las verticales podemos definir un conjunto de paredes horizontales de una vez. Se empieza a contar por la columna de la izquierda (de arriba abajo), después por la que está a su derecha, etc. La pared del ejemplo anterior sería la número 5. Ejemplo:

dim 4 3
paredesh 0 5 7

El tablero resultante es:

bloque x y

En lugar de paredes podemos colocar en el tablero bloques que ocupan una casilla completa. Los argumentos son las coordenadas de la casilla, con el criterio de siempre.

bloques x1 y1 x2 y2...

Versión abreviada para definir de una vez un conjunto de bloques. El número de argumentos debe ser par.

Obviamente, no es obligatorio que haya bloques.

movtodas
movuna
movtodasmenosuna

Estas tres directivas no necesitan argumentos e indican a Gravedad cómo se mueven las fichas. El significado de las dos primeras es bastante obvio: se mueven todas a la vez (movtodas) o de una en una (movuna). La tercera en cambio es un poco engañosa, porque el movimiento puede alternar entre todas las fichas menos una o todas sin excepción. Es el tipo de movimiento del conjunto 9.81.

Si no aparece ninguna de las tres palabras Gravedad mueve todas las fichas a la vez (se sobreentiende movtodas). El movimiento tipo movuna se distingue visualmente porque una de las fichas tendrá un pequeño rombo (o tendrá la etiqueta de otro color) indicando que es la que está seleccionada para moverse.

dif
nodif

Estas dos directivas indican si las fichas deben tratarse como equivalentes (nodif) o no (dif).

La directiva dif indica que para resolver el reto hay que llevar cada ficha al destino que le corresponde. Como dijimos antes, independientemente de si hay letras o números visibles, Gravedad numera cada ficha a partir del 0 según se van declarando y lo mismo hace con los destinos. La directiva dif indica que no basta con llevar cualquier ficha a cualquier destino, sino que la ficha 0 debe ir al destino 0, la ficha 1 al destino 1, etc. La directiva nodif indica que cualquier ficha puede colocarse en cualquier destino.

Es posible que el número de fichas y de destinos no coincidan. Veamos los distintos casos.

Si el número de destinos es menor que el de fichas y aparece la directiva dif se conseguirá resolver el reto si cada destino tiene encima la ficha que le corresponde, sin que importe la posición de las fichas «sobrantes» (las que tengan un número mayor que el del último destino). Veamos un ejemplo:

dim 4 3
movuna
dif
fichas 0 0 1 0 2 0
destinos 1 2 0 2

El código anterior produce un reto con esta posición inicial (los colores indican cuál es el objetivo):

Si el número de destinos es menor que el de fichas y aparece la directiva nodif se conseguirá resolver el reto si cada destino tiene encima una ficha cualquiera. El mismo código de antes cambiando dif por nodif produce la misma posición inicial pero con otros colores, indicando que no importa qué fichas se coloquen encima de qué destinos. Una ficha cualquiera quedará suelta.

El caso en que el número de destinos es mayor que el de fichas y aparece la directiva dif es posible, pero no tiene mucho sentido, ya que quedan destinos sin ninguna función. Veamos un ejemplo:

dim 4 3
movuna
dif
fichas 0 0 1 0
destinos 1 2 0 2 2 2

El objetivo es llevar la ficha azul al destino azul y la ficha roja al destino rojo. El (falso) destino negro no sirve para nada. En cambio, si usamos nodif sí puede tener sentido que haya más destinos que fichas (el código es igual cambiando dif por nodif):

El objetivo en este caso es ocupar dos de los tres destinos, no importa cuáles ni con qué fichas.

Si no se usa ni dif ni nodif se sobreentiende la primera.

familia f1 f2...

Una familia es un conjunto de fichas equivalentes. Por ejemplo, si las fichas 0 y 1 forman una familia, tanto la ficha 0 como la 1 pueden colocarse en los destinos 0 o 1. Ejemplo:

dim 4 3
paredesv 3
paredesh 5
fichas 0 0 1 0 2 0
destinos 1 2 2 2 3 2
familia 0 1

Las fichas azules se deben colocar sobre los destinos azules (no importa cuál en cuál) y la ficha roja sobre el destino rojo. Las fichas que no «se meten» en una familia son únicas y deben colocarse en su propio punto de destino. El siguiente código produce el reto de la imagen de la izquierda. Si suprimimos la última línea se genera el de la derecha.

dim 4 3
paredesv 3 5
paredesh 5
fichas 0 0 1 0 2 0 3 0
destinos 0 2 1 2 3 2 2 2
familia 0 1
familia 2 3

   

El concepto de familia es una generalización de las directivas dif y nodif. dif implica la existencia de una familia por ficha; nodif implica la existencia de una sola familia que contiene a todas las fichas. Las fichas que no se incluyen expresamente en una familia forman una familia ellas solas.

Como las fichas y los destinos, las familias se numeran a partir del 0.

fichasfamilia x1 y1 x2 y2...

Esta es una combinación de fichas y familia. Las fichas declaradas (como en fichas) formarán una familia. Así,

fichasfamilia 0 0 1 0 2 0

es una forma abreviada de:

fichas 0 0 1 0 2 0
familia 0 1 2

aleat

Algunos retos tienen una posición inicial aleatoria, diferente, por tanto, cada vez. En estos casos solo hay que definir los puntos de destino, sobre los que se situarán al azar las fichas, una en cada uno. Esta directiva no necesita argumentos.

agujero x y
agujeros x1 y1 x2 y2...

Los agujeros se parecen a los destinos en que...

Y se diferencian en que...

Aunque podrían coexistir casillas de destino y agujeros, esto no sucede en los conjuntos de retos actuales. La existencia de agujeros no implica la obligación o prohibición de tirar fichas por ellos. Esto debe declararse expresamente con las siguientes directivas.

tirarfamilia f
notirarfamilia f

En el primer caso (tirarfamilia) hay que tirar todas las fichas pertenecientes a la familia f por algún agujero. En el segundo (notirarfamilia) no hay que tirar ninguna ficha perteneciente a la familia f.

En caso de que una ficha que no debe caer por un agujero lo haga ya será imposible resolver el reto, lo cual se indica con un borde rojo extra.

Ejemplo:

dim 3 3
paredh 1 1
paredv 2 1
fichasfamilia 0 0 1 0
ficha 2 0
tirarfamilia 0
notirarfamilia 1
agujero 1 2

Para resolver este reto hay que tirar por el agujero (el gran círculo negro) las dos fichas azules y no tirar la ficha roja. La ficha roja forma por sí sola la familia 1.

fichasexplosivas

Esta directiva sin argumentos indica que las fichas (todas ellas) tienen una característica especial: cuando chocan entre ellas explotan, desapareciendo (lo cual es malo). Esta propiedad se destaca gráficamente con un pequeño círculo discontinuo.

Ejemplo:

dim 3 3
paredh 1 1
paredv 2 1
fichas 0 0 1 0
destinos 1 2 2 2
fichasexplosivas

Desde la posición inicial, tanto el movimiento izquierda como derecha provocan la explosión y consiguiente desaparición de ambas fichas. Esto hace que no se pueda resolver el reto, lo que se indica con un borde extra de color rojo.

El movimiento abajo no produce explosión, las fichas no explotan al chocar contra el borde del tablero, una pared interior o un bloque, solo contra otra ficha. Nótese que el movimiento imposible izquierda produce una explosión, mientras que arriba no tiene ningún efecto.

destinoscomestibles

Esta directiva hace que los destinos funcionen de forma distinta. En estos casos no habrá que colocar a las fichas en sus destinos, sino hacerlos desaparecer pasando sobre ellos. Tanto si la ficha se para encima como si pasa de largo, el destino desparecerá (como si hubiera sido comido). El objetivo será hacer desaparecer todos los destinos.

No es posible simultanear destinos normales y comestibles. Además, todos los destinos comestibles pueden ser comidos por cualquier ficha.

Esta característica se resalta gráficamente dibujando ojos y bocas a las fichas y señalando el punto de destino con una fresa en lugar de un cuadradito. En el siguiente ejemplo se combinan los destinos comestibles con un agujero. La ficha debe comerse las dos fresas y después arrojarse por el agujero.

dim 3 3
paredh 1 0
paredv 2 1
ficha 0 0
destinos 2 0 1 1
destinoscomestibles
agujero 2 2
tirarfamilia 0

sinfronteras

Esta directiva hace que los bordes del tablero no actúen como paredes sobre las que pueden chocar las fichas. El usuario debe evitar que las fichas se salgan, en cuyo caso se mostrará un borde adicional rojo indicando que el reto ya no puede resolverse.

Ejemplo:

dim 5 5
ficha 0 0
agujero 2 2
tirarfamilia 0
sinfronteras
bloques 2 0 1 4 4 3 3 0
paredv 1 1

Como se ve en la imagen, el modo sinfronteras se destaca con un borde más fino y discontinuo

estudio

Hay retos tan difíciles que para aprender a resolverlos necesitaremos estudiar el efecto de determinadas secuencias de movimientos desde una posición ordenada. Para estos casos se ha pensado la directiva estudio. Su efecto es que el reto se comporte como si estuviera resuelto desde el principio, sin comprobar tras cada movimiento si se ha conseguido el objetivo.

También es útil para poder probar retos con objetivos atípicos. Ejemplo (más adelante hablaremos sobre mostraretiq):

dim 5 3
bloques 1 1 3 1
fichas 0 0 4 0 1 2 3 2
estudio
mostraretiq

El objetivo de este reto no convencional es juntar horizontalmente en cualquier parte del tablero tres fichas con números consecutivos ordenados de izquierda a derecha: 1-2-3 o 2-3-4. Como Gravedad no puede detectar este objetivo podemos usar estudio y estar atentos para identificar nosotros mismos una posición final. No es que sea lo ideal, pero es mejor que nada.

autor texto

Si se especifica el autor, aparecerá junto al nombre del reto.

infopuzzle texto
instr texto

También puede añadirse un texto con comentarios o instrucciones sobre el reto, que aparecerán debajo del nombre. Este texto puede incluir elementos HTML como <em>, <p>, etc.

footnote texto

Puede añadirse una nota final de página, con información sobre copyright, etc.

primetiq n

Si no se especifica lo contrario, si hay dos o tres fichas distintas (no equivalentes) se diferenciarán por el color: la primera será azul, la segunda roja y la tercera amarilla. Los puntos de destino también tendrán esos colores. De cuatro fichas (y destinos) en adelante todas las fichas serán azules pero estarán identificadas con un número o letra que llamamos etiqueta. Por defecto, las etiquetas empiezan por 1 (recordemos que internamente se numeran a partir de 0). Este comportamiento se puede cambiar con la directiva primetiq, cuyo argumento n puede valer 0, 1 o A.

Ejemplos:

dim 4 3			dim 4 3			    dim 4 3
bloque 1 1              bloque 1 1		    bloque 1 1
dif                     dif			    dif
fichas 0 0 1 0 2 0      fichas 0 0 1 0 2 0 3 0	    fichas 0 0 1 0 2 0 3 0
destinos 0 2 1 2 2 2    destinos 0 2 1 2 2 2 3 2    destinos 0 2 1 2 2 2 3 2
                                                    primetiq A

      

En los modos movuna y todasmenosuna las etiquetas tienen dos usos adicionales al de indentificar las fichas (y destinos): se pueden seleccionar pulsando la tecla correspondiente del teclado; y se usan en la lista de movimientos.

Si el movimiento es de tipo movtodas (recordemos que es el usado por defecto) y el número de destinos es menor que el de fichas, las fichas excedentes (que no hay que llevar a ningún destino) no se etiquetan y aparecen de color rojo. Ejemplo:

dim 5 3
bloque 1 1
dif
fichas 0 0 1 0 2 0 3 0 4 0
destinos 0 2 1 2 2 2 3 2
primetiq 0

mostraretiq
nomostraretiq

Como acabamos de ver, Gravedad decide si debe usar o no etiquetas para las fichas y destinos. Pero si no nos gusta su decisión podemos decirle expresamente si debe o no usarlas con una de estas dos directivas.

dim 3 3
bloque 1 1
dif
fichas 0 0 1 0 2 0
destinos 2 2 1 2 0 2
primetiq 0

   

El ejemplo muestra que primetiq no hace que se usen etiquetas, pero si añadiéramos mostraretiq (derecha) se usarían tanto para las fichas (aunque se siguen diferenciando con colores: esto también lo podemos controlar, como veremos) como para los destinos (que dejan de marcarse con cuadraditos) y primetiq también se tiene en cuenta

difcolores
nodifcolores

Al igual que pasa con las etiquetas, si no nos gusta lo que hace Gravedad con respecto a los colores de las fichas, podemos recurrir a una de estas dos directivas.

dim 4 4
paredesv 3 8
paredesh 4 7
fichas 0 0 1 0 2 0 3 0
destinos 3 3 2 3 1 3 0 3

   

En modo dif (recordemos: por defecto si no se usan nodif ni familia), a partir de cuatro fichas y cuatro destinos Gravedad los diferencia con etiquetas y no con colores, lo que podemos cambiar añadiendo difcolores (derecha).

La aplicación solo está preparada para usar seis colores, que en principio son: azul claro (cornflowerblue), rojo (red), amarillo (gold), verde (green), rosa (pink) y morado (purple). Si en nuestro fichero de reto incluimos difcolores y más de seis fichas y destinos se usará el primer color para todas las fichas y destinos a partir del séptimo. Esto no es muy bueno porque habrá fichas y destinos con la misma apariencia pero no equivalentes.

color n quecolor

Podemos cambiar cualquiera de los seis colores antes mencionados con la directiva color.

dim 5 3				      (lo de la izquierda más...)
paredesv 4 7			      color 0 pink
paredesh 2 4 6			      color 2 #8b0000
fichasfamilia 0 0 1 0
fichasfamilia 2 0
fichasfamilia 3 0 4 0
destinos 1 2 3 2 2 2 0 2 4 2

   

n es un número de familia (que en modo dif equivale a número de ficha), es imposible hacer que dos fichas de la misma familia tengan diferentes colores. quecolor especifica el color y puede ser un número hexadecimal precedido del carácter # o un nombre clave.

mostrardestinos
nomostrardestinos

Posiblemente se den pocos casos, pero puede pasar que, por estética, prefiramos que un reto no muestre las casillas de destino, explicando el objetivo con palabras (o dibujos).

sol solucion

Si queremos dar a conocer la solución de nuestro reto podemos hacerlo con esta directiva. Podemos copiarla de la consola de JavaScript, como se explica en la página sobre la interfaz.

tamsol n

Esta directiva (por supuesto, opcional) está pensada para especificar, si se desea, el número de movimientos de la solución más corta conocida del reto. Este número se muestra entre paréntesis arriba del tablero. Nótese que tamsol y sol son independientes.

En Gravedad, los movimientos se cuentan siempre de la misma forma, independientemente de la modalidad de juego. En particular, en el modo movuna varios movimientos consecutivos de la misma ficha se cuentan por separado. Y, obviamente, marcar o desmarcar una ficha no se considera un movimiento.