Maze-K para ZX-81

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

Maze-K para ZX-81

Mensajepor dancresp » 28 Dic 2013, 17:24

Screen_1.gif
Screen_1.gif (9.06 KiB) Visto 10020 veces


EL JUEGO
El objetivo del juego consiste en conseguir salir de un laberinto que tiene un tamaño de 9x9=81 cuadrículas.
Cada cuadrícula puede mostrar entre 1 y 4 caminos, y nos moveremos con las teclas de los cursores 5, 6, 7 y 8.
El signo “+” que aparece a la derecha del laberinto nos indica la profundidad en la que nos encontramos.
La posición inicial es aleatoria, y al salir se muestra el número de movimientos realizados.

Descargar el juego en formato ".Z81" (Snapshot del EightyOne):
maze-k.rar
(1.1 KiB) Descargado 449 veces


BLOQUES
He dividido el listado en 6 bloques:

- Datos del laberinto.
- Declaración de variables.
- Impresión de la cuadrícula del laberinto en la que estamos.
- Control del movimiento.
- Comprobar si se ha salido.
- Mostrar los movimientos realizados y fin del juego.


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

Se utilizan las siguientes variables:
P – Puntero a la línea 1, que contiene el REM con los datos del laberinto.
T - Constante con valor 3, usado en distintas partes del programa.
S - Contador de movimientos realizados.
J - Usada para controlar si es una celda fija (1, 3, 5, 7, 9) o una celda variable (2, 4, 6, 8).
N - Valor numérico de la posición del laberinto en la que está el personaje.
B - Usada para obtener un bit de la variable “N”.
G – Tipo de gráfico a mostrar: 1 – Bloque, 10 – Personaje.
Y – Posición vertical del gráfico.
X – Posición horizontal del gráfico.
F – Variable para el bucle de impresión del gráfico.
K$ - Tecla que se ha pulsado.

1 - Línea REM que contiene los datos de las 81 casillas del laberinto.
10 - Guardamos el valor 16514 en la variable “P”. Apunta al primer carácter después del REM de la línea 10.
12 - Asignar a “T” el valor 3.
14 - Asignar a “S” el valor 0.
16 – Borrar la pantalla
18 – Asignar a “J” el valor de “T”, que es tres.
20 – Asignar a “B” el valor 16.
22 – Asignar a “N” el valor de la posición de memoria apuntado por “P” y restar 28 para obtener un valor entre 0 y 15.
24 – Inicio del bucle para imprimir los bloques verticales.
26 - Inicio del bucle para imprimir los bloques horizontales.
28 – Asignar a “G” el valor 1, correspondiente a un bloque.
29 – Si va a imprimir el bloque central asignar a “G” el valor 10, correspondiente al personaje.
30 – Si “J<>0” (bloques fijos) saltar a 38 para imprimir el gráfico del valor de “G”.
32 – Dividir el valor de “B” entre 2, para poder explorar el siguiente bit de “N”. Va de izquierda a derecha.
34 – Si el valor de “N” es inferior a “B” es que el bit explorado es igual a 0 y no imprime el bloque de camino.
36 – Restar a “N” el valor de “B”.
38 - Inicio del bucle que imprime el bloque gráfico.
40 – Imprimir en la posición correspondiente la parte del gráfico que toca.
42 – Incrementar el número del gráfico en 3.
44 – Final del bucle que imprime el bloque gráfico.
46 – Cambiar el valor de la variable “J” de “1 a 0” ó de “0 a 1”.
48 – Final del bucle horizontal.
50 – Final del bucle vertical.
51 – Mostrar el signo “+” para indicar a la profundidad a la que se encuentra el personaje.
52 – Esperar a que se pulse una tecla mediante un PAUSE con el valor de “P”, ya que no admite el PAUSE 0.
54 – Almacenar en “K$” el valor de la tecla pulsada.
56 – Movimiento horizontal si se pulsa “8” ó “5”
58 - Movimiento vertical si se pulsa “6” ó “7”
60 – Incrementar el contador de movimientos en 1.
62 - Si el puntero “P” es mayor o igual a 16514 es que esta dentro del laberinto y saltar a la línea 16.
64 – Mostrar el número de movimientos y finalizar el juego.


EL PROGRAMA
listado.gif
listado.gif (11.05 KiB) Visto 10020 veces


APUNTES FINALES
Después de las versiones 1K de los juegos “Minefield”, “Sudoku” y “Lights Out” tenía ganas de adaptar un juego tipo laberinto.

Para el desarrollo he vuelto a usar el emulador “EightyOne” con unos resultados muy satisfactorios.

Mi primera intención ha sido programar una mini-versión del clásico “MAZOGS”, pero al poco rato ya he visto que sería imposible meterlo en 1K.

Sumando bytes…
Como todo buen proyecto de ZX-81 con 1K lo primera es hacer una estimación de lo que debería ocupar cada parte del programa.
Un ZX-81 básico dispone de 1024 bytes de RAM libres.

Las variables de sistema ocupan 125 bytes y la memoria de video para el tablero de juego ocupa 9x9=81 bytes, más los 25 bytes de final de línea, ocupan unos 106 bytes.

Necesito 10 variables numéricas, que ocupan 7 bytes cada una y una alfanumérica que ocupa 2 bytes. Así que, en principio, las variables consumen unos 72 bytes más aprox. Los datos del laberinto ocupan 81 bytes más, y simplificando la complejidad de los cálculos se consigue que las rutinas del calculador no necesiten más que unos cuantos bytes.

Con todo esto, el programa no debería ocupar más de 600 bytes, aunque en la práctica la cosa quede sobre los 550 bytes.

Hay que tener en cuenta que cuenta que cualquier línea de código ocupa un mínimo de 6 bytes: 2 del número de línea, 2 del tamaño de la línea, 1 del final de línea y el resto según el contenido de la línea. El no poder meter varías sentencias en una misma línea no ayuda a ahorrar memoria.


Empieza el desarrollo
Lo más importante ha sido codificar los datos del laberinto en el mínimo espacio. Para ello he creado una codificación igual a la del juego “Light Out”. En cada posición puede haber entre 1 y 4 salidas. La combinación se hace usando los 4 bits de la derecha de un valor entre 0 y 15 (00h y 0Fh). Si hay muro en una dirección se pone su bit a 1 y se suman los valores: 8 – Superior, 1 – Inferior, 4 – Izquierda y 2 – Derecha. Esta codificación se introduce en el REM de la línea 1. Así, con solo 81 bytes he codificado el laberinto entero.

laberinto.jpg
laberinto.jpg (67.19 KiB) Visto 10020 veces


Como el almacenamiento de números no es muy eficiente y ocupa espacio tanto en el listado como en el área de variables, he declarado la variable “T=3” y se usa en distintos sitios del programa.

Con el bucle contenido entre las líneas 38 y 44 puedo imprimir el bloque que desee (G) en la posición correspondiente (X, Y).

El programa no controla que el movimiento que se realiza sea correcto, con lo que podemos atravesar paredes. En un principio esto no era así y almacenaba si había bloques en el camino guardando una serie de valores 1 y 0 en la zona del buffer de la impresora, y con otro puntero apuntaba allí. En la parte de los INKEY$ controlaba si el valor era 1 o 0 para aceptar el movimiento. Desgraciadamente esta parte se ha tenido que eliminar porque no quedaba espacio para poner el contador de movimientos ni el “+” que nos sirve como pista para saber a que profundidad nos encontramos.

La posición inicial se calcula aleatoreamente, modificando el valor del puntero “P”. Siempre empezamos a partir de la mitad inferior del laberinto. Y como curiosidad, hay una celda que permite pasar de la parte izquierda (fila 3 columna 1) a la derecha (fila 2 columna 9). Así se consigue que el laberinto sea “cilíndrico”.

Para saber si hemos salido del laberinto simplemente miro que el puntero apunte antes que el primer carácter de la línea REM. Si no es así vuelvo a imprimir el laberinto, y sino muestro los puntos y finaliza el juego.


¿Que se ha quedado en el tintero?
- Me gustaría poder validar que el movimiento que se realiza es correcto, pero no ha cabido.
- Encontrar un tesoro antes de salir, pero tampoco cabe.

Como curiosidad, si vamos pulsando la tecla “7” el puntero deja de apuntar en la línea REM y lo hace sobre el programa directamente. En este caso el resultado del laberinto puede ser ilógico.


Sea como sea, prueba superada ¡!!

Os invito a probarlo.

Screen_2.gif
Screen_2.gif (9.36 KiB) Visto 10020 veces

Screen_3.gif
Screen_3.gif (11.55 KiB) Visto 10020 veces
Buscando la IP de la W.O.P.R.

Avatar de Usuario
zitror
Amiga 2500
Amiga 2500
Mensajes: 5349
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: 248 veces
Gracias recibidas: 104 veces
Contactar:

Re: Maze-K para ZX-81

Mensajepor zitror » 28 Dic 2013, 21:17

Esto merece un tweet ¡ya! =D>
(C) 1.982 Sinclair Research Ltd

La buhardilla de Zitror

Shaun_B
ZX Spectrum 16
ZX Spectrum 16
Mensajes: 4
Registrado: 02 Ene 2014, 01:56
Sistema Favorito: C64
primer_sistema: Spectrum +2
consola_favorita: (Otro)
Primera consola: (Otro)

Re: Maze-K para ZX-81

Mensajepor Shaun_B » 02 Ene 2014, 02:06

Una pequeña mejora

Código: Seleccionar todo

54 LET P=(P+(INKEY$="8")-(INKEY$="5"))+(Y*(INKEY$="6")-Y*(INKEY$="7"))


Quitar líneas 56 y 58.

Shaun.

PS, English to Spanish translation provided by Google.

Avatar de Usuario
Hark0
Amiga 1200
Amiga 1200
Mensajes: 1695
Registrado: 11 Jul 2012, 23:44
Sistema Favorito: Spectrum 16Kb/48Kb
primer_sistema: Spectrum 16Kb/48Kb
consola_favorita: (Otro)
Primera consola: (Otro)
Ubicación: Cornellà de Llobregat - Barcelona
Contactar:

Re: Maze-K para ZX-81

Mensajepor Hark0 » 02 Ene 2014, 08:31

BRAVO!!!

=D>
http://www.zxuno.com
ZX-Uno · Clon de ordenador ZX Spectrum basado en FPGA.

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

Re: Maze-K para ZX-81

Mensajepor dancresp » 02 Ene 2014, 10:38

Shaun_B escribió:Una pequeña mejora

Código: Seleccionar todo

54 LET P=(P+(INKEY$="8")-(INKEY$="5"))+(Y*(INKEY$="6")-Y*(INKEY$="7"))


Quitar líneas 56 y 58.

Mira que llego a repasar las líneas y la verdad es que no se me había ocurrido juntar las líneas 56 y 58, siendo la solución que propones totalmente válida.

Pero puestos a ahorrar bytes, eliminamos 4 de los paréntesis de tu línea y la dejamos así:

Código: Seleccionar todo

54 LET P=P+(INKEY$="8")-(INKEY$="5")+Y*(INKEY$="6")-Y*(INKEY$="7")


De esta forma nos acabamos de ahorrar 23 bytes en el listado, que no está nada mal, y unos 5 bytes más en la zona de variables al ahorrarnos "K$". Interesante analizar en que se podrían invertir estos casi 30 bytes...

La única pega de no usar "K$" es que si la pulsación de la tecla es muy rápida, la ejecución de la línea 54 puede no ser correcta ya que al procesar uno de los INKEY$ la tecla puede ya no estar pulsada. Eso si, hay que ser muy rápido...

Gracias Shaun_B !!! =D>


Adjunto nuevo listado:

Listado_2.gif
Listado_2.gif (10.91 KiB) Visto 9786 veces
Buscando la IP de la W.O.P.R.

Shaun_B
ZX Spectrum 16
ZX Spectrum 16
Mensajes: 4
Registrado: 02 Ene 2014, 01:56
Sistema Favorito: C64
primer_sistema: Spectrum +2
consola_favorita: (Otro)
Primera consola: (Otro)

Re: Maze-K para ZX-81

Mensajepor Shaun_B » 02 Ene 2014, 11:37

Gracias Señor.

He añadido el programa para http://www.sinclairzxworld.com con su versión original y una de las mejoras mencionadas.

sinclairzxworld.com/viewtopic.php?f=4&t=552&p=13575 # p13575

Aquí está el listado de programas para la versión "redux":

Imagen

El parpadeo de la pantalla se elimina mediante la sustitución de la orden de "PAUSE" con un cheque por una interacción con el teclado. RAND USR VAL "2602" es equivalente a "CLS".

Shaun.
Última edición por Shaun_B el 02 Ene 2014, 14:09, editado 1 vez en total.

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

Re: Maze-K para ZX-81

Mensajepor dancresp » 02 Ene 2014, 13:24

Shaun_B escribió:Gracias Señor.

He añadido el programa para http://www.sinclairzxworld.com con su versión original y una de las mejoras mencionadas.

sinclairzxworld.com/viewtopic.php?f=4&t=552&p=13575 # p13575

Uix, Señor... :oops:

Gracias por publicar el juego en ese web. Me gusta ver mis trabajos en otros sitios. :D
He visitado el web y me ha sorprendido lo que llega a hacer la gente con un ZX-81 en ensamblador... =D>

De todas formas, si te gustan los programas BASIC de 1K, en los últimos meses he publicado unos cuantos:

Mine-Field 1K para ZX-81

SUDOKU 1K para ZX-81

Lights-Out 1K para ZX-81
Buscando la IP de la W.O.P.R.

Avatar de Usuario
Hark0
Amiga 1200
Amiga 1200
Mensajes: 1695
Registrado: 11 Jul 2012, 23:44
Sistema Favorito: Spectrum 16Kb/48Kb
primer_sistema: Spectrum 16Kb/48Kb
consola_favorita: (Otro)
Primera consola: (Otro)
Ubicación: Cornellà de Llobregat - Barcelona
Contactar:

Re: Maze-K para ZX-81

Mensajepor Hark0 » 02 Ene 2014, 18:13

Me encanta ver como optimizas el lenguaje...

"Hablar" de rascarle 24 bytes a una máquina no tiene precio... ;)

SIGUE ASI!!!!!!!!

;)

Por si quisieras OTRO reto... http://www.handheldmuseum.com/MB/CompIV.htm

Ahi está el manual de la máquina... ;) creo que es ideal para el ZX-81

Imagen
http://www.zxuno.com
ZX-Uno · Clon de ordenador ZX Spectrum basado en FPGA.

Avatar de Usuario
zitror
Amiga 2500
Amiga 2500
Mensajes: 5349
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: 248 veces
Gracias recibidas: 104 veces
Contactar:

Re: Maze-K para ZX-81

Mensajepor zitror » 02 Ene 2014, 18:24

Dani, tu trabajo ha traspasado fronteras =D>
(C) 1.982 Sinclair Research Ltd

La buhardilla de Zitror

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

Re: Maze-K para ZX-81

Mensajepor dancresp » 03 Ene 2014, 10:33

Hark0 escribió:Me encanta ver como optimizas el lenguaje...

"Hablar" de rascarle 24 bytes a una máquina no tiene precio... ;)

Este es uno de los encantos del ZX-81, y algo que se ha perdido en los equipos de hoy en día.

Hark0 escribió:Por si quisieras OTRO reto... http://www.handheldmuseum.com/MB/CompIV.htm

Desconozco el equipo, pero lo estudiaré.

Ahora mismo tengo casi listo otro programilla...

zitror escribió:Dani, tu trabajo ha traspasado fronteras =D>

Ya... :oops:

Otros proyectos también están en otros webs.

:jumper:
Buscando la IP de la W.O.P.R.


Volver a “Programación”

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 8 invitados