Sudoku para ZX-80

dancresp
Mensajes: 5336
Registrado: 13 Nov 2010 02:08
Agradecido : 150 veces
Agradecimiento recibido: 287 veces

Sudoku para ZX-80

Mensajepor dancresp » 26 Mar 2019 22:47

Sudoku_Screen.png
Sudoku_Screen.png (1.39 KiB) Visto 307 veces


EL JUEGO
El objetivo de un SUDOKU es rellenar una cuadrícula de 9x9, que a su vez está dividida en 9 regiones de 3x3, con números de 1 al 9 sin repetir ninguna cifra en la misma fila, columna y región.

El sistema muestra una cantidad de números y debemos deducir el resto hasta completar todas las casillas.

Controles:
En la zona inferior se deben entrar tres valores juntos:
1. Fila: 1 a 9.
2. Columna: 1 a 9.
3. Valor de la celda: 1 a 9, o cualquier otro carácter.


BLOQUES
He dividido el listado en 5 bloques:

- Definición del Sudoku correcto.
- Desordenar las celdas del Sudoku.
- Copiar el Sudoku en el tablero.
- Mostrar el Sudoku en pantalla y comprobar si es correcto.
- Introducir las coordenadas y el valor.

Descargar el juego en formato ".O":
Sudoku.zip
(607 Bytes) Descargado 4 veces


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

Se utilizan las siguientes variables:
P – Puntero a la posición de memoria del primer carácter después del REM de la línea 1.
F – Variable para bucles.
I – Variable para bucles, o de apoyo.
N – Usada como contador entre el puntero P y los caracteres de la línea 2.
A – Usada para comparar si los números introducidos están en la posición correcta.
A$ - Entrada del teclado.

1 – Línea REM que contiene el Sudoku completo.
2 – Línea REM que contiene el tablero del Sudoku.
3 – Guardamos en P el puntero al primer carácter después del REM de la línea 1.
5 – Inicializamos el generador de números aleatorios.
9 – Si un número aleatorio entre 0 y 2 es 2, saltamos a la línea 17.
10 – Inicio del bucle que cambiará la posición de un bloque de 27 dígitos.
11 – Guardamos en I el contenido de memoria de la dirección F.
12 - Ponemos en la posición F el dígito que hay 27 posiciones después.
13 – Ponemos en la posición F+27 el dígito que hay 27 posiciones después.
14 – Ponemos en la posición F+54 el valor de I, que es el que había en F.
15 - Final del bucle.
16 – Saltamos a la línea 9 para ver si hay que volver a desordenar los dígitos de la línea 1.
20 – Inicio del bucle que copia el Sudoku definitivo en el REM de la línea 2, a partir del décimo carácter.
21 – Ponemos en la posición de la línea 2, el valor que hay en la línea 1. Hay una diferencia de 94 posiciones de memoria.
22 – Final del bucle de copia.
30 – Guardamos en N el puntero del primer carácter del REM de la línea 2.
31 – La variable A se pone a 1 y sirve para comprobar si el Sudoku se ha completado correctamente.
32 – Borra la pantalla.
33 – Inicio del bucle que muestra las filas del tablero.
34 – Se muestra el número de fila en vídeo inverso.
35 – Inicio del bucle que muestra las columnas del tablero.
36 – Si la fila F>0 se comparan las posiciones de memoria del REM de la línea 1 con la de la línea 2, y si es distinto A=0.
37 – Muestra un carácter del REM de la línea 2, usando N como puntero.
38 – Si la columna es la 3, 6 o 9, se muestra un bloque gris.
39 – Se incrementa N, que es el puntero del REM de la línea 2.
40 – Final del bucle de las columnas.
41 – Se hace un salto de línea en pantalla.
42 – Si la fila es la 3, 6 o 9, se muestra una línea gris.
43 – Final del bucle de las filas.
44 – Si al acabar de mostrar el tablero A vale 1, el Sudoku se ha solucionado correctamente. Muestra mensaje y acaba.
50 - Se hace un salto de línea en pantalla.
51 – Se muestra el mensaje de orden de los valores de entrada: Fila/Columna/Valor.
52 – Entrada del movimiento a realizar en A$.
53 - Se guarda en F el valor de los dos primeros caracteres de A$.
54 – Si el valor no corresponde no apunta al REM de la línea 2, vuelve a la línea 52.
55 – Modificamos la dirección de memoria del REM de la línea 2, indicado por F.
56 – Saltamos a la línea 30, para volver a mostrar el tablero.


EL PROGRAMA

sudoku_listado.png
sudoku_listado.png (14.16 KiB) Visto 307 veces


PROGRAMANDO EN UN ZX-80
Programar en un intérprete BASIC que ocupa 4 KB es una experiencia dura. Y si quieres hacer algo mínimamente decente, muy dura.

Para situarnos, es un BASIC con unos 30 comandos y funciones, los valores numéricos solo pueden ser enteros de dos bytes, no puedes posicionar nada libremente en la pantalla, solo hay un comando muy simple para gestionar cadenas y no permite matrices alfanuméricas, no puedes consultar el teclado ni entrar caracteres en vídeo inverso, etc. Y así muchas más penurias, hasta llegar al límite de 1 KB de RAM, salvo expansión de memoria o disponer del clon de Wilco2009.

Las primeras veces que me propuse hacer algo en él, adaptando juegos de 1 KB del ZX-81 lo dejé correr porque no sabía cómo llevarlo a cabo. Mi primer reto fue adaptar el “Mine-Field”, y gracias a esta adaptación desarrollé una serie de métodos con los que he podido adaptar casi cualquier juego que no sea de acción. A día de hoy ya he desarrollado 9 juegos, y he podido comprobar que a pesar de con sus limitaciones, este tipo de juegos funcionan mejor en el ZX-80 que en el ZX-81. Al funcionar siempre en modo FAST son más rápidos, y por estructura interna en la forma de guardarse el código BASIC y las variables, todo ocupa menos memoria.

Aquí os presento la versión ZX-80 del Sudoku de 1 KB del ZX-81. Como dispongo de más memoria, es más bonito y puedo controlar si el movimiento es correcto, cosa que en el ZX-81 no podía hacer por limitaciones de memoria. Todo esto teniendo en cuenta que la versión ZX-80 ocupa exactamente el doble de líneas que la versión ZX-81, un total de 40 a 20.

A continuación os detallo el calvario por el que he tenido que pasar.

¿Cómo generar un SUDOKU con un BASIC lento y sin memoria?
Aunque ya lo he explicado en otros post de Sudoku para otros sistemas programados por mi hace unos años, lo vuelvo a explicar.

Analizando bien un Sudoku completado, se puede ver que realmente se pueden dividir en 3 filas o en 3 columnas, como muestro en la siguiente imagen. Si se cambia el orden de estas filas o columnas, el Sudoku sigue siendo perfectamente válido.

sudoku_1_estructura.gif
sudoku_1_estructura.gif (8.84 KiB) Visto 307 veces


Para esta versión he aplicado la misma técnica que ya había usado previamente en las versiones de Commodore VIC-20 y Sharp MZ-80B. Básicamente consiste en introducir un Sudoku correcto, desordenarlo, y al final ocultar parte de las celdas. El Sudoku es correcto pero aparentemente es distinto del Sudoku base.

Al partir de la versión del ZX-81, y debido a sus limitaciones de memoria, el desorden solo se realiza verticalmente, y hay un único Sudoku base, pero al ocultar parte de sus celdas parece que sean distintos. Con más memoria se podrían introducir más Sudoku base.


Cómo adaptar un programa del ZX-81 al ZX-80
En el ZX-81 el Sudoku correcto se almacena en la variable A$ de la línea 10. En el ZX-80, como la gestión de cadenas es tan limitada, he introducido el Sudoku en el REM de la línea 1. Esto tiene la ventaja de que en la versión del ZX-81, ocupa memoria tanto la línea BASIC como el espacio que necesita después en el área de variables.

El siguiente paso consiste en desordenar el Sudoku. En el ZX-81 esto se realiza con el código de las líneas 20 y 22. Simplemente pone al final de la cadena A$ los primeros 27 caracteres. En el ZX-81 esto ocupa 8 líneas (líneas 9 a 16), y consiste en mover los primeros 27 caracteres del REM de la línea 1 hacia el final. Complicado, sí, pero funciona.

En el ZX-81, una vez desordenado el Sudoku en A$, lo copio en la variable B$ con la línea 30. En el ZX-80 las líneas 17 a 19 se encargan de copiar los caracteres del REM de la línea 1 al de la línea 2. Como en el ZX-80 no se pueden entrar caracteres en vídeo inverso desde el teclado, como sí se puede hacer en el ZX-81, en el REM de la línea 2 hay primero 9 caracteres que se han tenido que POKEAR manualmente. Realmente el contenido del REM de la línea 2 hace de buffer del contenido de la pantalla. Lo que hay en esta línea es lo que después se verá en pantalla.

Imagen

Una vez tenemos el Sudoku desordenado en A$/REM-1 y copiado en B$/REM-2, toca ocultar parte de sus celdas. Esta parte ocupa tres líneas en el ZX-81 (40 a 44) y en el ZX-80 (20 a 22). Repite un bucle 21 veces donde ocultamos los dígitos del Sudoku B$/REM-2 aleatoriamente. Si no se repiten las celdas, algo que es posible, se ocultan 21.

Ahora hay que mostrar el Sudoku en pantalla. El ZX-81 lo puede hacer solo con 4 líneas de código (50 a 56), aunque el resultado no es tan bonito. El ZX-80 “solo” necesita 14, desde la línea 30 a la 43. La única ventaja es que mientras lo muestra en pantalla a partir del contenido del REM de la línea 2, lo compara con el contenido del REM de la línea 1 y si es correcto la línea 44 muestra el mensaje “WELL” y detiene el programa provocando un error al intentar mostrar el valor de una variable inexistente. El ZX-81 hace la comprobación en la línea 86, sin mostrar ningún mensaje.

Ahora queda entrar el movimiento. En el ZX-81 se encargan 6 líneas (60 a 70), y por limitaciones de memoria no se puede verificar que el movimiento sea correcto. Simplemente comprueba que el INPUT sea de tres caracteres. Si hay algún error en la entrada el programa peta. Si el movimiento es correcto, muestra el tercer carácter en la posición correcta de la pantalla y a continuación vuelve al INPUT si el Sudoku no es correcto. En el ZX-80 esto es más complejo pero nos indica el formato de la entrada y se comprueba que las coordenadas sean correctas. El código va desde la línea 50 a 56. Aquí se hace uso de las únicas instrucciones que el ZX-80 tiene para tratar cadenas de texto. Así, CODE(A$) devuelve el primer carácter de A$ y TL$(A$) devuelve el primer carácter de A$ después de desplazar el contenido de A$ una posición hacia la izquierda. Una de las particularidades de estos dos comandos es que a diferencia de otros, se han de teclear letra a letra ya que no tienen ninguna tecla asignada. Para guardar el movimiento en el ZX-80, hacemos un POKE en la posición correspondiente del REM de la línea 2. Para ello hay que hacer desplazar dos posiciones el contenido de la variable A$ encadenando dos TL$.

Con todo lo explicado, el Sudoku funciona perfectamente, incluso mejor y con mejor presentación que en el ZX-81. Curioso.

Imagen


Para terminar
Este es el segundo programa que he programado para el ZX-80, y la verdad es que con la técnica de las líneas REM he podido hacer programas bastante más complejos. Son una auténtica obra de orfebrería, pero pieza a pieza, acaban funcionando.

Por otro lado, he podido comprobar que la misma cantidad de memoria cunde bastante más en el ZX-80 y que el hecho de trabajar en modo FAST, los programas son más rápidos. A esto hay que añadir que no es necesario recurrir a los típicos trucos de ahorro de memoria del ZX-81, como usar VAL, CODE, PI, etc. Y los listados son totalmente comprensibles, como podréis comprobar.


Pues nada más, que otra prueba superada ¡!!


Os invito a probarlo.
Adjuntos
Sudoku_Screen_8081.png
(8.69 KiB) No descargado aún
sudoku_listado_80-81.png
(25.84 KiB) No descargado aún

Avatar de Usuario
duca750
Mensajes: 1354
Registrado: 19 May 2015 10:52
Ubicación: Olivenza (Badajoz)
Agradecido : 289 veces
Agradecimiento recibido: 70 veces

Re: Sudoku para ZX-80

Mensajepor duca750 » 26 Mar 2019 23:19

Madre mía, como te lo curras, estás que te sales preparando juegos de distintos sistemas. Gracias y enhorabuena!
-4mstr4d CPC464(7),472 Y 6128 (2) -sp3zy 16K&48K GOMAS,+2,+2A/2B +3 -cocbm1 64 Y -coam1** -0r1c 1 (2ud) y ATMOS** -m3s3x CANON V20, SPECTRAVIDEO 728,TOSHIBA HX10, PHILIPS VG8020,2 NMS 8250+GOTEK -j4tar1 STFM 800XL -3nt3r 64-ACORN ELECTRON -codrg1 32

Avatar de Usuario
minter
Mensajes: 2416
Registrado: 22 Jul 2014 18:51
Agradecido : 2216 veces
Agradecimiento recibido: 969 veces

Re: Sudoku para ZX-80

Mensajepor minter » 27 Mar 2019 00:25

Como dirían las revistas de los 80 cuando presentabas un programa:

Te has ganado el premio de 1000 duros!

Que pasada de aprovechamiento de recursos!

Avatar de Usuario
Chema
Mensajes: 2214
Registrado: 21 Jun 2012 20:13
Ubicación: Gijón
Agradecido : 1748 veces
Agradecimiento recibido: 573 veces
Contactar:

Re: Sudoku para ZX-80

Mensajepor Chema » 27 Mar 2019 16:50

Estás que no paras! Enhorabuena dancresp. Eres un crack!

dancresp
Mensajes: 5336
Registrado: 13 Nov 2010 02:08
Agradecido : 150 veces
Agradecimiento recibido: 287 veces

Re: Sudoku para ZX-80

Mensajepor dancresp » 28 Mar 2019 11:17

Chema escribió:Estás que no paras! Enhorabuena dancresp. Eres un crack!

Este estaba hecho desde hace un tiempo, peor no lo había podido publicar.

Ignoro si hay otra forma de hacer las cosas en un ZX-80, pero yo solo he encontrado esta.

A ver si puedo retomar el tema de publicar los 9 juegos que he programado en cinta de casete...

Avatar de Usuario
WhatIsAMan
Mensajes: 344
Registrado: 10 Dic 2017 17:06
Ubicación: El castillo invertido
Agradecido : 89 veces
Agradecimiento recibido: 103 veces

Re: Sudoku para ZX-80

Mensajepor WhatIsAMan » 29 Mar 2019 12:06

Hola Dancresp,

Un trabajo excelente, como de costumbre. Tienes un estilo simple y claro, por lo que es muy fácil de entender tu código. Haces que parezca fácil y todo. Cuando tenga más tiempo y si fuera posible, me gustaría hacer algun port de algun programa tuyo.

¡Muchas gracias por tus valiosas aportaciones al foro!

dancresp
Mensajes: 5336
Registrado: 13 Nov 2010 02:08
Agradecido : 150 veces
Agradecimiento recibido: 287 veces

Re: Sudoku para ZX-80

Mensajepor dancresp » 29 Mar 2019 12:58

WhatIsAMan escribió:Un trabajo excelente, como de costumbre. Tienes un estilo simple y claro, por lo que es muy fácil de entender tu código. Haces que parezca fácil y todo. Cuando tenga más tiempo y si fuera posible, me gustaría hacer algun port de algun programa tuyo.

Soy tan simple que no se programar de una forma más compleja... -grin

En el trabajo, de responsable de informática, les meto unas "encojidas" de código a mis compañeros que se quedan flipados.
Es lo que tiene haber aprendido a programar con equipos tan simples.

Si haces algún port ya nos lo enseñarás. Todo un honor por mi parte.

Avatar de Usuario
Luis
Mensajes: 1084
Registrado: 03 Nov 2010 19:00
Agradecido : 209 veces
Agradecimiento recibido: 113 veces

Re: Sudoku para ZX-80

Mensajepor Luis » 29 Mar 2019 23:03

Hum no se, no le veo tanto mérito a esto. Usas un pepino como el ZX80, así cualquiera.

Yo hubiera sacado esa 180P que tienes en el cajón. Venga, anímate. -507 -507

Eres un máquina tío -drinks
West of House
You are standing in an open field west of a white house, with a boarded front door. There is a small mailbox here.

afx
Mensajes: 603
Registrado: 25 Nov 2010 23:26
Agradecido : 14 veces
Agradecimiento recibido: 36 veces

Re: Sudoku para ZX-80

Mensajepor afx » 30 Mar 2019 00:39

Guau …. ¡qué compacto el código! -shock

Increíble lo que se puede hacer con tan pocas líneas de código BASIC.

A raíz de este sudoku de dancresp me acordé de uno que escribí para el Sinclair QL hace muchos años. He creado otro hilo con una imagen y el código ese OSUSQ, "Otro Sudok para el Sinclair Ql" (viewtopic.php?f=83&t=200034767).


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