COMPUTADORES II JUEGO DEL...
Transcript of COMPUTADORES II JUEGO DEL...
COMPUTADORES II
JUEGO DEL AHORCADO Grupo B3
Carlos Calvo Rodríguez (12.418.504 E)
Samuel Gallego Chimeno (71.031.505 F)
COMPUTADORES II – JUEGO DEL AHORCADO
2
Contenido Objetivos, Especificaciones, Ensamblado …………………………………………………………………………………3
Funcionamiento
Sistema de menús (sección menu: y subrutina printMenu) ......................................................... 4
Introducción de la palabra secreta (sección setword:) ................................................................. 5
Bucle principal de juego (sección gameloop:) ............................................................................... 5
Comprobador contador de fallos: ............................................................................................. 5
Comprobador FLAGS: ................................................................................................................ 6
Bucle: ......................................................................................................................................... 6
Referencia de Subrutinas
Módulo principal (HANGMAN, hangman2.asm) ........................................................................... 9
Módulo de utilidades de cadenas (STRINGUTILS, stringUtils.asm) ............................................... 9
Módulo de utilidades numéricas (NUMUTILS, numUtils.asm) ................................................... 10
Módulo de utilidades (MISCUTILS, miscUtils.asm) ..................................................................... 10
Notas ……………………………………………………………………………………………………………………………………..11
Anexo: Diagramas de flujo ……………………………………………………………………………………………………..12
COMPUTADORES II – JUEGO DEL AHORCADO
3
Objetivos
El objetivo del proyecto es programar en ensamblador un juego del ahorcado para el Motorola
6809, haciendo hincapié en un uso eficiente de la programación modular mediante uso de
subrutinas, obtención de código reubicable y optimización en tamaño de programa y ciclos de
reloj.
Especificaciones del proyecto
Juego completamente funcional, con entrada validada, comprobación de caracteres
repetidos (tanto aciertos como fallos).
Código completamente reubicable.
Inclusión de diversas subrutinas de utilidad
Diseño completamente modular, expandible y configurable.
Optimizado para una utilización mínima de recursos manteniendo la reubicabilidad.
(aproximadamente 60000 ciclos para una partida media)
Ensamblado
Es posible ensamblar el proyecto mediante el proceso manual.
as6809 –l –o hangman2.asm
as6809 –l –o stringUtils.asm
as6809 –l –o numUtils.asm
as6809 –l –o miscUtils.asm
aslink –s –m –b _CODE=0x<xxxx> -u –w hangman2.rel miscUtils.rel stringUtils.rel numUtils.rel
m6809-run hangman2.s19
O bien mediante la Shell script.
ensambla hangman2 stringUtils numUtils miscUtils
COMPUTADORES II – JUEGO DEL AHORCADO
4
Funcionamiento
El proyecto consta de 4 secciones claramente diferenciadas, además de 3 módulos adicionales
con subrutinas de utilidad general o específica.
Sistema de menús (sección menu: y subrutina printMenu) La gestión de los menús se hace desde la subrutina printMenu del módulo miscUtils.asm,
mediante la creación de una estructura de datos de menú, definida de la siguiente manera.
menu<n>:
.byte <n> ;n = número de elementos del menú
.asciz <cabecera del menú>
.asciz <texto opción #1>
...
.asciz <texto opción #n>
menu<n>_add:
.word <dirección de la subrutina de la opción #1>
...
.word <dirección de la subrutina de la opción #n>
Los menús así definidos no generan código reubicable. Para conseguir código reubicable es
preciso inicializar los menús en tiempo de ejecución de la manera que se ve en el código.
leax menu<n>_add
leay <subrutina n>, PCR
sty ,X++
...
leay <subrutina n>, PCR
sty ,X++
printMenu lee la dirección de la estructura menú deseada en el registro X, gestiona la elección
del usuario, y una vez validada, deja en el registro X la dirección de la subrutina asociada a
dicha elección.
menu_err es una cadena global que será utilizada como mensaje de error por todos los menús
si se escoge una opción incorrecta.
COMPUTADORES II – JUEGO DEL AHORCADO
5
Introducción de la palabra secreta (sección setword:)
La introducción de la palabra secreta se hace mediante la subrutina getAStringN, que lee de la
entrada estándar una cadena de longitud máxima N, especificado por el valor del registro B, y
que será guardada en la dirección indicada por el registro X.
Por ello, se establece B a 20 y X a la dirección de la variable setword.
La entrada del usuario cuenta con un pseudo-búfer, permitiendo el uso de la tecla BACKSPACE
para corregir la entrada (ver nota 1), y es validada contra cadenas vacías o que superen el
máximo de caracteres permitidos. (ver nota 2).
Una vez leída y validada, se utiliza la subrutina toUCase para pasarla a mayúsculas, con el
propósito de homogeneizar la entrada. Se añade también un mecanismo de ocultación de la
palabra, para evitar que se pueda hacer trampa. (ver nota 3).
Finalmente, se establecen los flags R de los caracteres de la palabra secreta. (ver siguiente
sección)
Bucle principal de juego (sección gameloop:)
Esta sección contiene el algoritmo de control del juego. Para su funcionamiento, se requiere
un uso específico de los registros de la CPU, como se detalla a continuación.
A: Contiene el carácter introducido por el usuario.
B: Contiene el último carácter leído de la palabra secreta.
X: “Cursor” que apunta a los sucesivos caracteres de la palabra secreta.
Y: Contiene permanentemente la dirección de la palabra secreta.
U: Contiene 2 comprobadores que se utilizarán durante el algoritmo y que se detallan a
continuación.
Comprobador contador de fallos: Es un simple contador de 1 byte que indica el número de fallos totales cometidos por el
usuario.
(Comprobar la longitud de la cadena misses también valdría, pero es una revisión del código
reciente)
COMPUTADORES II – JUEGO DEL AHORCADO
6
Comprobador FLAGS:
[EN_JUEGO | CONTADOR ACIERTOS]
7 6 ... 0
Es un comprobador de 1 byte cuyo bit más significativo actúa como la flag EN_JUEGO.
EN_JUEGO =1 indica que quedan caracteres por resolver, por lo que continúa el juego.
EN_JUEGO =0 indica que ya están resueltos todos los caracteres, luego se ha ganado.
El resto de bits del comprobador son un contador de los caracteres acertados en una ronda
determinada. Nunca puede ser superior a 20, luego 7 bits dan rango suficiente para
contenerlo.
A mayores, para determinar si un carácter esta ya resuelto o no, se utilizan las flags R (ver nota
4), que se almacenan en sus respectivos caracteres, usando el bit más significativo de éstos, ya
que al ser caracteres ASCII, sólo requieren 7 bits.
R = 1 indica que el carácter no ha sido resuelto
R = 0 indica que el carácter ha sido resuelto.
Por tanto, el formato que tendrán los caracteres usados en el programa será el siguiente.
[R | # ASCII]
7 6... 0
Bucle:
El bucle de juego se detalla a continuación.
Primero, se establece el valor de Y, y se comprueba que no sea una cadena vacía, en cuyo caso
se aborta el bucle y se pide la palabra secreta.
Después se introduce el contador de fallos inicializado a 0 en la pila, y se entra en el bucle.
gl_start:
Se imprimen el ahorcado (subrutina auxiliar printHangman), el progreso de la palabra secreta
(subrutina auxiliar printSecWord) y los fallos cometidos, se resetea el cursor al principio de la
palabra y se introduce el comprobador FLAGS reseteado a 0.
A continuación se lee un carácter mediante la subrutina getChar (ver nota 1), se valida y se
establece su flag R a 1 para proceder a su comprobación.
COMPUTADORES II – JUEGO DEL AHORCADO
7
gl_loop:
Comienza cargando en B el carácter apuntado por el cursor X, se comprueba si se ha llegado al
final de la palabra, y en caso contrario, se comprueba su flag R. De ser un carácter aun por
resolver, se compara con A (carácter introducido). De coincidir, se salta al bloque gl_match y
en caso contrario, se pone la flag EN_JUEGO a 1.
gl_repeat<1,2,3>:
Gestionan los caracteres ya resueltos o repetidos. gl_repeat2 se ejecutará si se ha repetido un
carácter previamente acertado y gl_repeat3 en caso de repetirse un error. Sólo se diferencian
en un pulu extra para mantener la integridad de la pila.
De no ser ninguno de los casos anteriores, se limita a saltar a gl_next.
gl_match:
Establece la flag R de B a 0 (Carácter ya resuelto) y aumenta el contador de aciertos.
gl_next:
Hace avanzar la posición del cursor X en una posición.
gl_correct[2]:, gl_error1:
Son simples bloques de gestión de la interfaz, no forman parte del algoritmo principal.
gl_end:
Comprueba los comprobadores de la pila para determinar el estado de la partida.
Primero, si EN_JUEGO vale 0, se ha ganado. De no ser así, se determina si el carácter
introducido ha sido un acierto o un fallo, aumentando el contador de fallos y añadiéndolo a la
lista de fallos (subrutina auxiliar addMiss) si procede.
Si el número de fallos llega a 7, se ha perdido.
Si ninguna de las condiciones de salida es satisfecha, se regresa al comienzo del bucle.
COMPUTADORES II – JUEGO DEL AHORCADO
8
Fin de juego (secciones win: y lose:)
Son parte de la interfaz, y se limitan a imprimir los mensajes pertinentes (ver nota 5), y a
solicitar si se desea jugar de nuevo, mediante la subrutina auxiliar choiceBox.
COMPUTADORES II – JUEGO DEL AHORCADO
9
Referencia de subrutinas
Se resumen aquí las subrutinas utilizadas en el programa, con un formato similar a una función
de C, para consultar fácilmente sus entradas, salidas y propósito.
Más información en las cabeceras de las subrutinas en sus respectivos archivos fuente.
Módulo principal (HANGMAN, hangman2.asm)
printSecWord (X = dirección de la palabra secreta)
Imprime la palabra secreta sustituyendo los caracteres no resueltos por _.
addMiss (X = dirección de la cadena de fallos, A = carácter)
Añade el carácter A a la lista de fallos.
Módulo de utilidades de cadenas (STRINGUTILS, stringUtils.asm)
printString (X = dirección de la cadena)
Imprime la cadena apuntada por X.
V = isAlpha (A = carácter)
Valida si A es un carácter alfabético (devuelve 1 si lo es).
A = getChar
Lee un único carácter de la entrada estándar.
B,V,Z = getAStringN (B = longitud máxima, X = dirección de guardado)
Guarda en X una cadena alfanumérica de longitud máxima N. Devuelve el número de
caracteres introducidos en B, overflow si se supera el límite (V=1) y Z=1 si no se introduce
nada.
COMPUTADORES II – JUEGO DEL AHORCADO
10
A = toUpper (A = carácter)
Pasa A a mayúscula.
toUCase (X = dirección de cadena)
Pasa la cadena guardada en X a mayúsculas.
Módulo de utilidades numéricas (NUMUTILS, numUtils.asm)
printU16Number (D = número)
Imprime el número binario en D en formato decimal, tratándolo como sin signo.
Módulo de utilidades (MISCUTILS, miscUtils.asm)
clearScreen
Limpia la terminal.
X = choiceBox (D = Dirección mensaje, X = dirección subrutina para sí, Y =
dirección subrutina para no)
Presenta un mensaje al usuario con una elección s/n, y deja la dirección de la subrutina
correspondiente en X.
printHangman (A = fallos)
Imprime un ahorcado según el número de fallos.
X = printMenu (X = dirección de menú)
Imprime el menú apuntado por X y devuelve la dirección de la subrutina a saltar.
COMPUTADORES II – JUEGO DEL AHORCADO
11
Notas finales
Nota 1:
Todas las subrutinas de entrada disponen de pseudo-búferes que admiten el uso de la tecla
BACKSPACE, sin embargo, debido a la programación del emulador, cuando se presiona
BACKSPACE se imprimen caracteres extraños en la terminal. Estos caracteres no influyen en el
funcionamiento de las subrutinas ni en la entrada introducida.
Nota 2:
Las subrutinas de entrada limitada están protegidas contra overflows, por lo que nunca
causarán accesos o sobreescrituras ilegales de memoria.
Nota 3:
El comportamiento del carácter BACKSPACE en el emulador no está muy bien definido. Según
el tipo de consola utilizado, puede que se oculte la palabra o no. Hemos observado ambos
comportamientos, sin ser capaces de dilucidar qué determina dichos comportamientos.
Nota 4:
Hay diversos métodos para comprobar si un carácter está resuelto, como utilizar 3 bytes con
20 flags (versión 0.1), utilizar mayúsculas o minúsculas (versión 0.2), etc.
El método finalmente elegido se demuestra más eficaz computacionalmente y en uso de
memoria que los otros sistemas probados.
Nota 5:
El carácter BEL (0x07) no parece estar implementado en el emulador. La idea era que sonaran
unos pitidos cuando se ha ganado.
Nota 6:
Se podría optimizar el rendimiento si se comprobasen los errores repetidos al comienzo del
bucle, para no ejecutarlo en tal caso, pero por falta de tiempo, al ser una característica añadida
a última hora, no se implementa.
COMPUTADORES II – JUEGO DEL AHORCADO
12
Anexo: Diagramas de flujo
A continuación se presentan los diagramas de flujo para las dos secciones principales, setword:
y gameloop:
Por simplicidad, se omiten todas las llamadas a printString y al resto de elementos de la
interfaz.
Si V=1 o Z=0 (Cadena no válida)
SI
SETWORD
Y = dir(palabra secreta)
B = 20; getAStringN
X = dir(palabra secreta)
A = ,X
A = \0?
toUpper; sta ,X; print BACKSPACE
X+
GAMELOOP
NO
COMPUTADORES II – JUEGO DEL AHORCADO
13
Y = dir(palabra secreta)
B = 0; PUSH B;
,Y = \0?
X = Y; B = 0; PUSH B;
A = getChar
toUpper; R(A) = 1
B = ,X
R(B)?
B = \0?
A = ,X?
EN_JUEGO = 1
R(A) = 0
A = ,X?
R(A) = 1
R(B) = 0; ,X = B; aciertos+
X+
EN_JUEGO?
aciertos?
R(A) = 0
addMiss
Z?
fallos+
fallos=7?
WIN/LOSE
SETWORD
GAMELOOP
SI
SI
SI
SI
SI
1
1
1
0
0
0
0
1
NO
NO
NO
NO
NO