Segunda entrega de nuestro curso de juegos en BASIC, en la cual vamos a
profundizar en qué son y cómo se usan las variables, las instrucciones que nos
permiten tomar decisiones en nuestro programa, creación de subrutinas y el control
del flujo de nuestro programa. Todo esto lo ilustraremos con algún pequeño ejemplo
en forma de un sencillo juego con el que llevaremos a la práctica todos estos
conceptos teóricos.
VARIABLES EN EL BASIC DEL SPECTRUM
Las variables son posiciones de memoria que se reservan para almacenar
un determinado valor al que necesitamos acceder con facilidad desde nuestro
programa y modificarlo a nuestro gusto. A estas posiciones de memoria se
accede con el nombre que les damos al declarar las variables. Realmente
poco nos importa en que posición de memoria las almacena nuestro ordenador,
ya que siempre nos referiremos a ellas por su nombre.
- DECLARACIÓN DE LAS VARIABLES
Las variables tenemos que declararlas para poder usarlas, el ordenador no sabe
ni el nombre ni el valor ni el tipo de la misma si no se lo decimos antes.
Esto lo podemos hacer en cualquier lugar de nuestro programa siempre que
lo hagamos antes de utilizarla. Para tener esto un poco más claro veamos
el siguiente ejemplo:
No os preocupéis, de momento, por lo que hace la línea anterior.
Si ejecutamos la anterior línea con RUN, nos dará el siguiente
error: 2 Variable not found, 10:1. Esto quiere decir
que no ha encontrado la variable que intentamos utilizar en la parte uno de
la línea 10, o lo que es lo mismo, la variable 'A' justo después del IF.
El error ha sido generado por no haber declarado antes de su uso la variable.
Añadamos al programa anterior la línea 5 LET A=10,
de manera
que el programa quede de la siguiente forma:
Lo volvemos a ejecutar con RUN y, en esta ocasión, nos devolverá el
mensaje 0 OK, 10:2, con lo cual nos dice que la
ejecución del programa se ha llevado a cabo correctamente.
Si cambiásemos el número de la línea 5 por 15, nos volvería a generar un error
de variable no definida, ya que declaramos la variable, pero después de hacer
uso de ella.
- TIPOS DE VARIABLES
Las variables en el BASIC del Spectrum pueden ser de dos tipos: numéricas
y alfanuméricas.
- VARIABLES NUMÉRICAS
Al contrario de lo que pasa en otros lenguajes de programación, en los
que
tenemos diferentes tipos de variables para cada número que queremos
almacenar,
INT, FLOAT, DOUBLE, etc., en el BASIC del Spectrum no se distingue el
tamaño
de las variables numéricas. Al contrario, en ellas podemos
almacenar cualquier tipo de número, ya sea entero o fraccionario,
positivo
o negativo.
El nombre por el que las vamos a designar debe comenzar obligatoriamente
por
una letra y puede estar seguida de más letras o números. Veamos los
siguientes
ejemplos de lo que son variables numéricas correctas e incorrectas:
Todas estas declaraciones de variables son perfectamente válidas.
Y las siguientes no podríamos declararlas:
Al intentar teclear estas instrucciones, el intérprete BASIC del
Spectrum
simplemente no nos dejaría introducirlas, generando un pitido y
colocando el
cursor en el punto erróneo.
A la hora de asignar los nombres a las variables numéricas, tenemos un
par
de excepciones que tener en cuenta: las variables que controlan los
bucles y
las que denominan a una matriz (a continuación explicamos qué es una
matriz),
que únicamente pueden estar nombradas con una sola letra:
FOR F=1 TO 10: PRINT F: NEXT F sería
correcto y
FOR F1= 1 TO 10: PRINT F1: NEXT F1 sería
incorrecto.
Las variables que controlan los bucles no es necesario declararlas antes
de
utilizarlas, ya que en el mismo FOR se hace su declaración.
DIM A(10,10) válido y
DIM A1(10,10) inválido.
Las matrices se componen de una serie de valores almacenados en una
cuadrícula a
la que se accede por el nombre de la variable más su índice, cuya
numeración comienza por
uno. Es decir, si tenemos declarada una variable tal que
DIM A(10), podemos asignar
a cada una de sus diez posiciones un valor diferente y utilizarlo de la
misma forma
que cualquier otra variable.
Por ejemplo, si queremos asignar a la quinta posición de nuestra matriz
llamada 'A'
el valor 345, nos bastaría con hacer: LET
A(5)=345 y lo
podríamos utilizar, por ejemplo, de la siguiente forma:
IF A(5)>345 THEN CLS.
Las matrices pueden tener más de una dimensión, podemos tener una cuadrícula
de
NxN elementos, sin más límite que la memoria del Spectrum. Imaginaos que
definimos
A(10,10), con lo cual tendremos una matriz de 10x10=100 elementos, cada
uno
almacenando un valor independiente, y a la que accedemos de la siguiente
forma: LET A(5,7)=10. ¿Sencillo, verdad?
Imaginaos las aplicaciones que a una matriz se le puede dar en un juego.
Valga como
ejemplo el famoso juego de los barquitos, que los colocamos en una
cuadrícula de
NxN elementos, lo extrapolamos a una matriz y tendríamos el problema de
cómo resolver su almacenamiento solucionado de una forma muy sencilla.
Laberintos
en un juego tipo Maziacs, las cartas en el Póker, etc.
- VARIABLES ALFANUMÉRICAS
El otro tipo de variables que tenemos disponibles son las alfanúmericas.
En ellas
podemos almacenar todo tipo de caracteres ASCII, es decir, números,
letras y
cualquier otro carácter o token del Spectrum.
Los nombres de las variables alfanuméricas solo pueden estar formados
por una
letra seguidos del símbolo '$', y no son válidas como índice de bucles,
aunque sí para realizar comparaciones y diferentes operaciones de
cadenas, como
pueden ser concatenar unas con otras, elminar caracteres, etc. Este tipo
de
variables necesita que el valor que vayamos a asignarlas se indique
entre comillas.
Unos cuantos ejemplos:
Variables
alfanuméricas correctas
|
LET A$="BUENOS DIAS"
LET A$="BUENOS"+"DIAS"
LET A$=CHR$ 65 (CHR$ meterá el caracter ASCII correspondiente
al código 65, en este caso la letra 'A').
|
Todos los ejemplos anteriores son válidos y, al igual que anteriormente
con
los numéricos, los siguientes generarán un error:
También podemos crear matrices con contenido alfanumérico. Éstas tienen
un
peculiaridad muy importante. Siempre reservamos una longitud fija para
almacenar la
cadena. Mejor lo vemos con un ejemplo:
DIM A$(10,10)
Con esta instrucción le decimos a nuestro Spectrum que nos reserve
memoria para una
matriz de 10 elementos y con una longitud de 10 caracteres por elemento,
es decir,
podríamos almacenar diez 'frases' diferentes con una longitud de 10
caracteres
y, si no rellenamos esos diez caracteres, el ordenador los rellena con
espacios a
la derecha de la cadena. Por ejemplo:
LET A$(2)="HOLA"
introduciría la palabra 'HOLA' (mejor dicho, sus códigos ASCII) en la
posición
2 de la matriz, y rellenaría con seis espacios (carácter ASCII 32) los
seis bytes restantes. Hay que tener en cuenta que cada carácter en ASCII
tiene
un byte de longitud.
- CONSIDERACIONES FINALES SOBRE LAS VARIABLES
Con las variables se pueden efectuar una amplia variedad de operaciones
aritméticas, trigonométricas y lógicas: suma, resta, multiplicación,
división, seno, coseno, etc., como pueden ser la siguientes:
LET A=A+B que suma el contenido de las
variables A y B
dejando el resultado en A.
LET A=A+1 que suma a la variable A uno a su
valor inicial.
LET A=C*10 que pone en A el resultado de
multiplicar
por 10 el contenido de la variable C.
Y así con todas las operaciones disponibles.
Debemos tomar por costumbre nombrar a las variables con nombres que nos
indiquen
su utilidad, pero teniendo en cuenta que a mayor longitud del nombre,
más espacio
ocupan en memoria, y en el Spectrum la RAM es un bien escaso. Como
ejemplo nos puede
valer lo siguiente:
VIDASJ1=3 con lo cual queremos indicar que
el jugador
1 tiene tres vidas; esto ocupa, sólo por la definición del nombre, 7
bytes, sin
contar el coste de almacenar el valor en memoria. En cambio si
ponemos 'VJ1=3' lo reducimos en 4 bytes, esto puede parecer poco, pero
si nos imaginamos un programa que utilice 30 variables, y sumamos los
bytes
gastados en la declaración más los que usemos cada vez que tengamos que
realizar una
operación con ella, podemos darnos cuenta de que se nos dispara el
consumo de memoria.
TOMANDO DECISIONES
Cuando programemos nuestro juego, llegará un momento en que tengamos que hacer
una cosa u otra dependiendo de determinadas condiciones que se den en el programa:
si se nos terminan las vidas tiene que finalizar la partida, si matamos a un
enemigo, que nos incrementen los puntos, etc. Esto se puede hacer en BASIC con los
comandos que nos provee.
Para tomar una decisión hacen falta dos elementos que queramos comparar (o más en alguna
ocasión) y un operador lógico que realice la comparación, es decir, podemos ver
si entre dos variables una es mayor que la otra, si son iguales, si diferentes...
La principal instrucción que nos da el BASIC para efectuar comparaciones es
IF condición THEN. Con esto conseguimos que,
si el resultado de la comparación es cierto, se ejecuten los comandos que vienen a
continuación del THEN. Lo veremos más claramente con
un ejemplo:
10 IF VIDAS=0 THEN PRINT "ESTAS MUERTO": STOP
Con esta instrucción comparamos si el contenido de la variable
VIDAS es igual a 0, en caso afirmativo, se ejecutan los comandos situados después
del THEN. En caso de que no sea cierta, simplemente se ignoran y se pasa
la ejecución del programa a la siguiente línea del mismo.
Pero no sólo podemos realizar una comparación única por cada IF THEN que
tengamos, podemos concatenar varias comparaciones:
10 IF VIDAS=0 OR TIEMPO=0 THEN PRINT "ESTAS MUERTO": STOP
Aquí hacemos dos comparaciones y gracias al operador lógico OR, las instrucciones
a continuación del comando THEN se ejecutan si cualquiera de los dos casos se
cumple, que vidas o tiempo sea igual a 0.
Podemos tener la necesidad de que tengan que ser ciertas las dos, y
no sólo una. Para que nuestra condición se cumpla:
10 IF VIDAS>0 AND TIEMPO >0 THEN LET TIEMPO=TIEMPO-1
Fácil de comprender, si tenemos más vidas y tiempo que lo indicado, '0',
ejecutamos las instrucciones colocadas después del THEN.
- OPERADORES
Con estos elementos podremos comparar diferentes circunstacias entre variables.
Y siempre devolverá la comparación si es cierto o falso.
- Mayor que ">" Cierto si el resultado de comparar el primer dato es
mayor que el segundo.
- Menor que "<" Cierto si el resultado de comparar el primer dato es
menor que el segundo.
- Igual que "=" Cierto si los dos datos son exactamente iguales.
- Diferente que "<>" Será cierto si los datos comparados son
diferentes.
- Mayor o igual que ">=" Cierto si el primer dato es mayor o igual
que el segundo.
- Menor o igual que "<=" Cierto en caso de que el primer dato sea
menor o igual que el segundo.
Con este conjunto de operados lógicos podremos realizar las
comparaciones necesarias en nuestro programa.
FLUJO DEL PROGRAMA
En el BASIC del Spectrum, las diferentes instrucciones de los programas las
vamos introduciendo con un número delante, que nos sirve para poder controlar el
flujo del programa como necesitemos durante la ejecución del mismo, entre otras
cosas. La numeración de estas líneas la podemos indicar desde el número 1 al 9999,
con los saltos intermedios que queramos, podemos numerarlas de 2 en 2, de 10
en 10, etc. Es aconsejable irlas numerando de manera que quede hueco entre
una y otra para poder introducir una línea con instrucciones adicionales
sobre la marcha, en caso de que sea necesario. Por ejemplo de 10 en 10.
En cualquier programa la ejecución de las instrucciones se va realizando de
manera correlativa, en primer lugar la línea superior y consecutivamente las
siguientes hasta llegar a la última. Esto para un programa sencillo puede
servir, por ejemplo para uno que nos dé la equivalencia entre
kilómetros y millas. Pero, en un juego, en el que hay porciones del programa
que se ejecutarán varias veces, no es útil.
Tenemos dos instrucciones que nos van a permitir variar este flujo:
GO TO y GO SUB.
- GO TO
Con GO TO saltaremos a la línea indicada
después de la misma instrucción,
saltando las que pudiese haber tanto delante como detrás de la misma:
- PROGRAMA 3 -
|
10 LET A=5
20 IF A=5 THEN GO TO 100
30 PRINT "NO ES CIERTO"
40 STOP
100 PRINT "SI ES CIERTO"
|
Al ejecutar este programa, como A=5, ya que así lo hemos asignado al principio
del mismo, la condición analizada en la línea 20 se cumple y se ejecuta la
instrucción GO TO, saltando directamente a la línea 100 sin pasar por la 30
ni la 40. Podemos variar ahora la línea 10 cambíando 5 por cualquier otro
número.
Veremos cómo la condición no se cumple y la ejecución del programa sigue por la
línea 30 finalizando en la 40 por obra del STOP situado en ella, instrucción
que sirve para detener la ejecución del programa drásticamente.
- GO SUB y RETURN
La instrucción GO SUB es una evolución
de GO TO ya que nos permite desviar
en un momento dado la ejecución del programa, ejecutar un bloque de
instrucciones y devolver el flujo a la línea siguiente donde se ejecutó el
GO SUB con la instrucción RETURN.
Este tipo de construcciones se denominan subrutinas.
Lo vamos a ver con un ejemplo:
- PROGRAMA 4 -
|
10 LET A =5
20 IF A=5 THEN GO SUB 100
30 PRINT "DESPUES DEL GOSUB"
40 STOP
100 PRINT "EL GOSUB HA FUNCIONADO"
110 RETURN
|
Es un programa similar al que usamos para ilustrar al comando GO TO. Si la
condición
de la línea 20 se cumple, que lo hará porque A vale 5 en un comienzo,
salta a la línea 100, ejecuta lo que hay en ella y al llegar a la
instrucción RETURN de la línea 110 , devuelve el flujo a la línea 30, justo
después de la ejecución del GO SUB.
GO SUB nos va a ser muy útil a la hora de tener porciones de programa que se
tienen que ejecutar varias veces, para no reescribirlos en varias ocasiones,
simplemente lo tenemos una vez y cada vez que nos haga falta lo llamamos con
el correspondiente GO SUB.
Una precaución que tenemos que tener con el uso de RETURN, si lo ponemos en
una línea, y el programa llega a ella sin haber ejecutado previamente una
sentencia GO SUB,
se detendrá la ejecución del mismo con el informe de error
7 RETURN without GO SUB, 0:1. Es decir,
la ejecución de RETURN tiene que estar ligada forzosamente a una llamada
anterior por medio de GO SUB.
Damos por supuesto que el lector ha comprendido que la utilización de GO TO
y GO SUB no se limita al ámbito de una instrucción comparativa, sino que
puede ser puesta en cualquier línea como un comando más para alterar el
flujo del programa:
- PROGRAMA 5 -
|
10 PRINT "HOLA MUNDO"
20 GO TO 100
30 REM A ESTA LINEA NO LLEGARA NUNCA LA EJECUCION DEL PROGRAMA
40 REM YA QUE EL GO TO HACE QUE LA EJECUCION SALTE ESTA LINEA
100 PRINT "POR AQUI CONTINUA EL PROGRAMA"
|
Vemos una instrucción nueva, REM, que sirve para insertar comentarios en
nuestros
programas, y que no se ejecuta en ningún caso. Nuestro programa se ejecuta
escribiendo un saludo y luego salta directamente a la línea 100.
BUCLES
Podemos tener la necesidad de ejecutar una serie de instrucciones un
número determinado de veces. Para eso tenemos los bucles, formados por los comandos
FOR TO, NEXT y STEP.
El comando FOR necesita de una variable que irá incrementando o decrementando
hasta que la condición de salida sea cierta y salga del mismo. Esta variable
no es necesario que se declare previamente y su nombre constará de una única letra.
10 FOR F=1 TO 10
20 PRINT F
30 NEXT F
Este programa ejecutará 10 veces las instrucciones contenidas entre las
instrucciones FOR y NEXT. En la línea 10 le decimos que vamos a crear un bucle llamado
F que va a comprender un rango de 1 a (TO) 10, en la línea 20 ejecutamos lo
que queremos, en este caso un PRINT y en la 30 cerramos el bucle.
La iteración del bucle no tiene por que ir de uno en uno, podemos hacer
que la suma sea mayor con la inclusión del comando STEP. Cambiamos la
línea 10 únicamente:
10 FOR F=1 TO 10 STEP 2
El bucle ahora se ejecutaría la mitad de veces, ya que le estamos indicando
que incremente el valor de F de dos en dos, en lugar de uno como es lo habitual.
Para hacer que el bucle se ejecute hacia atrás, necesitaremos ponerle
obligatoriamente un STEP -1, ya que de otra manera, la iteración siempre
suma. Cambiando la línea 10 del anterior programa por la siguiente podremos ver
los resultados:
10 FOR F=10 TO 1 STEP -1
Podemos anidar un bucle dentro de otro sin ningún problema, siempre que nos
preocupemos de cerrar el más interno antes de que se ejecute otra iteración
del externo, Con un ejemplo lo veremos perfectamente:
- PROGRAMA 6 -
|
10 FOR F=1 TO 10
20 PRINT "TABLA DEL: ";F
30 FOR D=1 TO 10
40 PRINT F*D
50 NEXT D
60 NEXT F
|
Con este programa sacaremos por pantalla las tablas de multiplicar del
1 al 10, y podemos apreciar como antes de cerrar el bucle externo, hay
que hacer lo propio con el interno, en caso contrario el resultado obtenido no será el
deseado. Se puede probar intercambiando las líneas 50 y 60.
NUESTRO PRIMER JUEGO
Para ilustrar todo lo que acabamos de leer, vamos a crear un
jueguecillo simple de adivinación de números en el que vamos a utilizar
las instrucciones vistas hasta aquí.
- ADIVINACIÓN -
|
10 PRINT "DEBE ADIVINAR UN NUMERO ELEGIDO ALEATORIAMENTE ENTRE 1 Y 100 EN LA
CANTIDAD DE INTENTOS QUE USTED INTRODUZCA"
20 INPUT "Introduzca el número de intentos (Max.10) ";A
30 IF A<1 OR A >10 THEN GO TO 20
40 LET VALOR=(RND*100)+1
50 FOR F=1 TO A
60 INPUT "INTRODUZCA NUMERO ";B
70 IF B=VALOR THEN PRINT "ENHORABUENA, ACERTO EN ";F;" INTENTOS": STOP
80 IF B>VALOR THEN PRINT "EL NUMERO INTRODUCIDO ES MAYOR"
90 IF B
100 NEXT F
110 CLS: PRINT "NO HA SIDO CAPAZ DE ADIVINAR EL NUMERO EN ";A; " INTENTOS"
120 PRINT "EL NUMERO ERA ";VALOR
|
El programa es muy sencillo de entender, y solo haremos hincapié en
unas cuantas instrucciones nuevas.
- INPUT, que como se habrá podido apreciar, sirve para
introducir un valor por el teclado y asignarlo a una variable.
- PRINT, Sirve para presentar texto por pantalla.
- RND, que vale para generar números aleatorios,
en este caso le decimos
que busque un número entre 1 y 100 (como puede asignar 0 a este valor, le
sumamos 1 para que nunca ocurra este caso).
- CLS, sirve para borrar la pantalla.
- STOP, con este comando paramos la ejecución del
programa.
Algunas de estas instrucciones las comentaremos en profundidad en próximos capítulos
del curso, de momento con saber qué hacen será suficiente.
CONCLUSIONES
Este mes hemos visto una serie de instrucciones que van a ser
imprescindibles para realizar nuestros programas, así como dejamos sentados
unos cuantos conceptos de programación sin los cuales no conseguiremos realizar
un proyecto medianamente serio.
El juego de ejemplo de este mes puede no decir gran cosa, ya que
carece de gráficos, efectos, movimiento, etc. pero sirve perfectamente para
ver todo lo explicado en este artículo.
En la siguiente entrega de este curso, en la que abordaremos la presentación
gráfica y la lectura de teclado, veremos moverse algo por la pantalla
controlándolo a nuestro antojo.
|
MIGUEL |
|