RUSH HOUR para ZX-80

dancresp
Mensajes: 5634
Registrado: 13 Nov 2010 02:08
Agradecido : 314 veces
Agradecimiento recibido: 446 veces

RUSH HOUR para ZX-80

Mensajepor dancresp » 30 Jun 2020 00:03

RushHour_Screen.png
RushHour_Screen.png (2.48 KiB) Visto 126 veces


EL JUEGO
Basado en el clásico juego de puzzles de la casa “Thinkfun”, el objetivo consiste en conseguir hacer salir del tablero al vehículo rojo, moviendo horizontal o verticalmente el resto de vehículos que lo obstaculizan.

Imagen

RushHour-HowToPlay.jpg
RushHour-HowToPlay.jpg (70.92 KiB) Visto 126 veces


Al igual que en el juego original, en esta versión el tablero se compone de una rejilla de 6x6 casillas, con un obertura a la derecha de la tercera fila por donde debe salir el vehículo indicado con “00”. Las tarjetas que indican cómo colocar los vehículos de cada nivel se han eliminado y en su lugar hay pregrabados 4 puzzles de dificultad creciente.

El movimiento, casilla a casilla, se indica introduciendo 2 valores, uno al lado del otro:
- Vehículo a mover. Es un número o una letra, según sea un vehículo de dos o tres piezas.
- Dirección del movimiento. Número entre 5 y 8 que corresponde con las flechas de los cursores.
- Si el movimiento introducido es “00”, se fuerza un reinicio del nivel.

Para finalizar el nivel se debe colocar el vehículo “00” delante de la salida. Superado el cuarto nivel finalizará el juego.

Descargar el juego en formato ".o":
RushHour.rar
(586 Bytes) Descargado 3 veces


BLOQUES
He dividido el listado en 4 bloques:
- Definir los puzzles e inicializar las variables.
- Cargar el puzzle.
- Mostrar el estado del puzzle en pantalla.
- Introducir y realizar el movimiento.

COMO FUNCIONA
A continuación detallo, línea por línea, el funcionamiento de las 44 líneas del programa.

Se utilizan las siguientes variables:
A - Usada para varias cosas.
F - Usada para bucles.
I - Usada para bucles.
L - Usada para realizar el movimiento.
N - Nivel del juego.
P - Puntero al REM de la línea 1.
T - Puntero al REM de la línea 1.
A$ - Entrada del movimiento a realizar, o para la pausa.

1 - Línea REM que contiene la posición de los vehículos de los 4 niveles.
2 - Línea REM que contiene la posición de los vehículos en el nivel en que estamos jugando.
3 - Guardamos el valor 0 en la variable "N".
5 - Guardamos en la variable "P" el puntero a los datos del nivel actual del REM de la línea 1.
6 - Guardamos en la variable "T" el puntero al primer carácter después del REM de la línea 2.
10 - Inicio del bucle que vuelca los caracteres del REM de la línea 1 al REM de la línea 2.
11 - Se hace un POKE a la posición correspondiente del REM de la línea 1.
12 - Final del bucle que copia el nivel de un REM al otro.
20 - Se borra la pantalla.
21 - Imprime el borde superior del tablero.
22 - Guardamos en la variable "A" el valor de la variable "T".
23 - Inicio del bucle que controla la impresión de las filas del tablero.
24 - Imprime el borde izquierdo de una fila del tablero.
25 - Inicio del bucle que controla la impresión de las columnas de una fila del tablero.
26 - Imprime el carácter correspondiente de esa posición, a partir de un carácter del REM de la línea 2.
27 - Se incrementa en 1 el valor de la variable "A".
28 - Final del bucle que controla la impresión de los caracteres de una fila.
29 - Si no es la fila 3, la de la salida, imprime el borde derecho de una fila del tablero.
30 - Imprime un salto de línea.
31 - Final del bucle que controla la impresión de las filas del tablero.
32 - Imprime el borde inferior del tablero.
33 - Imprime un salto de línea.
34 - Imprime el nivel en el que estamos jugando.
35 - Imprime un salto de línea.
36 - Si el carácter que hay delante de la salida no es un "0" salta a la línea 48.
37 - Incrementa el nivel.
38 - Si el nivel es 4, finaliza la partida mostrando un mensaje y provocando un error con una variable inexistente.
39 - Muestra un mensaje conforme se ha superado el nivel.
40 - Se fuerza una pausa mediante un INPUT.
41 - salta a la línea 5.
48 - Muestra el mensaje del formato del movimiento a realizar.
49 - INPUT en A$ para entrar el movimiento a realizar.
50 - Si la entrada es "00" se fuerza un reinicio del nivel saltando a la línea 5.
51 - Inicio del bucle que busca el vehículo indicado en el tablero.
52 - Si el carácter en el tablero no corresponde con el introducido, salta a la línea 60.
53 - Guardamos en la variable "A" el código de la letra correspondiente al vehículo.
54 - Guardamos en la variable "I" el carácter correspondiente a la dirección del movimiento.
55 - Se modifica el valor de "I" en función del movimiento a realizar.
56 - Guardamos en la variable "L" un 0 o un 1 en función si movemos un número o una letra.
57 - POKE en la posición correspondiente del carácter del vehículo que estamos moviendo.
58 - POKE en la posición inicial del vehículo a mover poniendo un punto.
59 - Guardamos en la variable "F" un 35 para forzar el final del bucle.
60 - Final del bucle que localiza el vehículo.
61 - Salta a la línea 20.


EL PROGRAMA
RushHour_List.png
RushHour_List.png (12.48 KiB) Visto 126 veces


UN RUSH HOUR EN UN ZX-80
Este juego ha sido un nuevo reto ya que aunque aparentemente es simple, el movimiento de las piezas y su distinto tamaño me han complicado el desarrollo.

1. Los vehículos
Antes de embarcarme en el proyecto era imprescindible aclarar cómo serían los vehículos. La solución condicionaba la forma de indicar el vehículo a mover.

Después de estar pensando en usar los caracteres semigráficos del ZX-81, he optado por usar algo tan simple como números para los vehículos que ocupan dos casillas y letras para los de tres casillas.

2. Introducir los puzzles
En un principio me había planteado codificar los puzzles, como ya hice en “Light-Out” en que en 5 bytes guardaba un tablero de 5x5 casillas, o el “Maze-K” en que en 81 bytes guardaba las salidas de las 81 posiciones del laberinto. Pero no, analizado el tema me di cuenta que ocupaba más la información y el decodificador que introducirlos tal cual.

El criterio es muy simple, los vehículos que ocupan 2 casillas los forman números y los de 3 los forman letras. Cualquier número o letra es válido, pero el “0” está reservado para el vehículo que debe salir. Esto hace que no puedan haber más de 9 vehículos de 2 casillas, pero bueno, no creo que se de el caso.

De esta forma, cada nivel ocupa 36 caracteres que están introducidos secuencialmente en el REM de la línea 1. Se empieza por la casilla superior izquierda y se avanza hacia la derecha, hasta el final. Así de simple.

RushHour-Encode.jpg
RushHour-Encode.jpg (62.43 KiB) Visto 126 veces


Ampliando o modificando la línea 1 en bloques de 36 caracteres nos permite disponer de más o distintos niveles. Por cada nivel extra se debe incrementar el valor de la variable “T” de la línea 6 en 36, también.

Esta versión tiene 4 tableros, uno más que la versión del ZX-81.

3. Indicar el movimiento
Esta parte tenía aspecto de ser complicada, pero el hecho de usar caracteres ha facilitado mucho la cosa.

La entrada consta de dos caracteres: “Vehículo a mover” y “Dirección”.

A continuación se busca por el tablero un carácter que coincida con el introducido, y se mueve en la dirección indicada por un número entre el 5 y el 8, correspondientes a las teclas de los cursores. El movimiento ha sido con diferencia la parte más compleja del proyecto.

Si el movimiento introducido no es correcto, no se mueve ningún vehículo. En la versión del ZX-81 no se pudo realizar esta comprobación.

4. Moviendo un vehículo
Esta parte es la más complicada ya que hay vehículos de dos bloques y otros de tres, y se pueden mover horizontal o verticalmente, y me ha costado dar con el método más simple.

Cuando el vehículo se mueve hacia la izquierda (5) o hacia arriba (7), se reduce la posición del vehículo, y cuando se mueve hacia la derecha (8) o hacia abajo (6) la posición se incrementa, pero teniendo en cuenta la orientación del vehículo lo hace en 1 o 6 casillas, donde también influye el tamaño del vehículo.

Esta parte me dejo bloqueado ya que el código era engorroso y lo componían varias líneas, hasta que decidí irme a dormir y rehacerlo de nuevo al día siguiente después de comprobar que con unas “sencillas” fórmulas y pocas líneas de código se podía resolver.

Así, lo primero que hago es calcular la dirección del movimiento en la línea 55, en función de la tecla de dirección introducida, y se guardar en la variable “I”, pudiendo contener 4 valores posibles - 1, 6, -6 ó 1. Después se calcula el tamaño del vehículo en la línea 56, pero con una posición menos, y se guardar en la variable “L”. Estos dos valores son necesarios para los cálculos posteriores.

A continuación, la línea 57 pone en la casilla correspondiente el carácter del vehículo que se mueve, y la línea 58 se encarga de borrar el otro extremo del vehículo para liberar la casilla, teniendo en cuenta en ambos casos la dirección del movimiento y la longitud del vehículo.

Al redibujar el tablero se muestra el vehículo en su nueva posición. Si el vehículo “00” está delante de la casilla de salida se pasa el nivel y si no se introduce un nuevo movimiento.


Os invito a probarlo…

RushHour_List8081.png
RushHour_List8081.png (332.92 KiB) Visto 126 veces
Buscando la IP de la W.O.P.R. he encontrado mi índice

Volver a “Lenguajes de Programación y herramientas Dev”

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 1 invitado