Rush Hour-K para ZX-81

Foro dedicado a la programación en todo tipo de sistemas clásicos.
dancresp
Amiga 1200
Amiga 1200
Mensajes: 1378
Registrado: 23 Dic 2008, 17:53
Sistema Favorito: MSX
primer_sistema: ZX81
Primera consola: Atari 2600
Gracias recibidas: 14 veces

Rush Hour-K para ZX-81

Mensajepor dancresp » 13 Nov 2015, 23:51

Rush_Hour_2.gif
Rush_Hour_2.gif (2.93 KiB) Visto 1488 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.

RushHour_Versiones.jpg
RushHour_Versiones.jpg (268.01 KiB) Visto 1488 veces

RushHour-HowToPlay.jpg
RushHour-HowToPlay.jpg (71.16 KiB) Visto 1488 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 3 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.

Para finalizar el nivel se debe colocar el vehículo “00” delante de la salida. Superado el tercer nivel, en pantalla aparecerá un tablero sin sentido, dando el juego por terminado.

Por evidentes limitaciones de memoria, el programa no detecta movimientos incorrectos o entradas erróneas.

Descargar el juego:
Rush Hour.rar
(593 Bytes) Descargado 31 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 del programa.

Se utilizan las siguientes variables:
A$ - Puzzle en juego.
B$ - Movimiento realizado.
P – Puntero a los datos de los puzzles.
U – Variable numérica que contiene el valor 1.
S – Variable numérica que contiene el valor 6.
F – Variable numérica para bucles y posición inicial del vehículo a mover.
I – Variable numérica de incremento del movimiento respecto al tablero.
L – Variable numérica con la longitud del vehículo -1.

1 – Línea REM que contiene los datos de los tres puzzles disponibles.
3 – Asignamos el puntero a los datos del puzzle –36.
4 – Definimos la variable “U” con el valor 1.
5 – Definimos la variable “S” con el valor 6.
6 – Sumamos 36 al puntero para que realmente apunte al primer valor.
10 – Inicializamos la variable “A$”.
11 – Inicio del bucle que leerá las 36 casillas del puzzle actual.
12 – Vamos añadiendo a la variable “A$” las distintas casillas del puzzle que estamos leyendo.
13 – Final del bucle.
15 – Imprimimos el borde superior del tablero.
16 - Inicio del bucle que mostrará las casillas del puzzle actual.
17 – Imprime una fila del puzzle junto con su borde.
18 – Final del bucle.
19 – Imprimimos el borde inferior del tablero.
20 – Si en la casilla que hay delante de la salida hay un “0” salta a la línea 6 para cambiar de puzzle.
21 – Entramos el movimiento en la variable “B$”.
22 – Inicio del bucle que busca el carácter del vehículo indicado.
23 – Si el valor de la casilla no coincide con el vehículo a buscar salta a la línea 36.
24 – Guardamos en “B$” únicamente el movimiento a realizar.
25 – Guardamos en “I” el desplazamiento a realizar, pudiendo ser 1, -1, 6, -6 según si es horizontal o vertical.
26 – Guardamos en “L” la longitud del vehículo a mover, con un carácter de menos.
28 – Imprime el vehículo en la posición correcta.
30 – Borra de pantalla parte del vehículo.
35 – Guardamos en “F” la longitud del tablero, para forzar el fin del bucle.
36 – Final del bucle.
38 – Saltar a la línea 15


EL PROGRAMA
Rush Hour_Listado.gif
Rush Hour_Listado.gif (10.41 KiB) Visto 1488 veces



APUNTES FINALES
Después de unos meses sin programar equipos de 8 bits, me he decidido a abordar un proyecto que hacía tiempo que quería intentar meter en el fantástico K del ZX-81.

Como el BASIC del ZX-81 es realmente lento, los juegos de acción no son lo más indicado para programar, pero en cambio los juegos de tablero o puzzles pueden ser perfectamente jugables. Como en este caso.

Este juego se incorpora en mi sección de juegos tipo puzzle de 1K, compuesto entre otros por el “Mine Field”, “Sudoku”, “Lights Out”, “Solitario” o el “Pipe Mania”.

Y siempre que me lío con un proyecto de estos, las dificultades han sido variadas aunque felizmente superadas.


UN RUSH HOUR EN 1K
A falta de tiempo libre he usado el emulador “EightyOne” en mis viajes al trabajo en tren, y el 90% del juego estaba listo en poco más de 1 hora. El 10% me ha llevado unas 3 horas más…

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.

RushHour-Encode.jpg
RushHour-Encode.jpg (62.65 KiB) Visto 1488 veces


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.

Posteriormente el bucle de las líneas 10 a 13 cargará las 36 casillas del nivel actual en la variable A$.

Ampliando o modificando la línea 1 en bloques de 36 caracteres nos permite disponer de más o distintos niveles.

3. Indicar el movimiento
Esta parte tenía aspecto se 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.

He tenido que prescindir de la verificación de que el movimiento es correcto, nada complicado, ya que solo me habría permitido incluir un único puzzle.

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 25, 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 26, 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 28 pone en la casilla correspondiente el carácter del vehículo que se mueve, y la línea 30 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. Ssi el vehículo “00” está delante de la casilla de salida se pasa el nivel y sino se introduce un nuevo movimiento.


Para terminar
Otra vez he apostado por una mejor legibilidad del programa, por lo que he evitado la instrucción CODE y he optado por definir los valores numéricos mediante VAL. Como me sobraban unos bytes…


Os invito a probarlo…

Rush_Hour_0.gif
Rush_Hour_0.gif (2.92 KiB) Visto 1488 veces

Rush_Hour_1.gif
Rush_Hour_1.gif (2.94 KiB) Visto 1488 veces
Buscando la IP de la W.O.P.R.

oscarbraindead
Commodore 128
Commodore 128
Mensajes: 117
Registrado: 05 Oct 2012, 17:42
Sistema Favorito: Commodore Amiga
primer_sistema: Spectrum 16Kb/48Kb
consola_favorita: Nintendo GameBoy
Primera consola: Atari 2600

Re: Rush Hour-K para ZX-81

Mensajepor oscarbraindead » 14 Nov 2015, 07:36

Enhorabuena, Dancresp.
Es increíble el jugo que llegas a sacar del BASIC de estos ordenadores. :cartelbravo:
Disculpa una pregunta de ignorante total... ¿puede ser que uses "NOT PI" en lugar de 0?... ¿es más rápido?

Saludos

dancresp
Amiga 1200
Amiga 1200
Mensajes: 1378
Registrado: 23 Dic 2008, 17:53
Sistema Favorito: MSX
primer_sistema: ZX81
Primera consola: Atari 2600
Gracias recibidas: 14 veces

Re: Rush Hour-K para ZX-81

Mensajepor dancresp » 14 Nov 2015, 11:15

oscarbraindead escribió:Disculpa una pregunta de ignorante total... ¿puede ser que uses "NOT PI" en lugar de 0?... ¿es más rápido?


Como ya expliqué en el post del "http://www.zonadepruebas.com/viewtopic.php?f=15&t=6221", al introducir un número en un programa el intérprete BASIC se lo guarda en dos formatos distintos, separados por un byte que contiene un 126 decimal.

Lo explico en esta imagen:

Imagen

Cuando haces LIST, se muestra el primer formato donde cada dígito ocupa un byte, hasta que llega al byte que contiene el 126 y prescinde del resto.
En cambio cuando haces RUN, el intérprete ignora el primer formato y coge los 5 bytes que están a continuación del byte del 126 ya que está el valor numérico en un formato directamente tratable por las rutinas del calculador.

Esto hace que un simple 0, ocupe 7 bytes en memoria: 1 del dígito, el 126 y los 5 bytes del valor empaquetado.
Si poner "1000" ocupa 10 bytes, 4 de los dígitos y los 6 restantes, etc...

En cambio, si usas expresiones tipo "NOT PI", "INT PI", "SGN PI" consigues ciertos valores ocupando solo dos bytes, y te ahorras cinco.

Otras técnicas son usar VAL "0" que ocupa 4 bytes en lugar de 7 y nos ahorramos 3, ó CODE "0" que con valores pequeños nos permita ahorrar unos bytes más que con VAL.

En una máquina con unos 600 bytes disponibles en BASIC, a veces es imprescindible usar éstas técnicas para conseguir hacer funcionar el programa.

Eso si, el programa ocupa menos, pero es algo más lento.
Buscando la IP de la W.O.P.R.

oscarbraindead
Commodore 128
Commodore 128
Mensajes: 117
Registrado: 05 Oct 2012, 17:42
Sistema Favorito: Commodore Amiga
primer_sistema: Spectrum 16Kb/48Kb
consola_favorita: Nintendo GameBoy
Primera consola: Atari 2600

Re: Rush Hour-K para ZX-81

Mensajepor oscarbraindead » 14 Nov 2015, 20:08

Impresionante, no conocía el otro post.
Muchas gracias por la explicación.

Saludos!

Avatar de Usuario
Lenko
Atari 1040 STf
Atari 1040 STf
Mensajes: 648
Registrado: 29 Mar 2005, 11:39
Gracias dadas: 10 veces
Gracias recibidas: 9 veces

Re: Rush Hour-K para ZX-81

Mensajepor Lenko » 15 Nov 2015, 21:39

dancresp... Algún día conseguiré un ZX81 y me hartaré a poner tus programas.

Me encanta lo que consigues con 600 bytes.
Material para cambio y venta

Busco:
- Manual Spectrum +3 español

Avatar de Usuario
zitror
Amiga 2500
Amiga 2500
Mensajes: 5204
Registrado: 02 Jul 2006, 00:16
Sistema Favorito: Spectrum 16Kb/48Kb
primer_sistema: Spectrum 16Kb/48Kb
Ubicación: El interior de un Z80
Gracias dadas: 99 veces
Gracias recibidas: 27 veces
Contactar:

Re: Rush Hour-K para ZX-81

Mensajepor zitror » 18 Nov 2015, 22:53

Yo es que flipo contigo... =D>
(C) 1.982 Sinclair Research Ltd

La buhardilla de Zitror

Avatar de Usuario
Ivanzx
Amiga 1200
Amiga 1200
Mensajes: 1562
Registrado: 05 Abr 2007, 19:39
Gracias recibidas: 4 veces
Contactar:

Re: Rush Hour-K para ZX-81

Mensajepor Ivanzx » 24 Sep 2016, 21:05

Ya sabéis lo que voy a escribir aquí, no? :P


Volver a “Programación”

¿Quién está conectado?

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