Programacion Basic Con Amstrad

Descargar como pdf o txt
Descargar como pdf o txt
Está en la página 1de 206

PROGRAMACION

BASIC
CON AMSTRAD
PROGRAMACIÓN BASIC
CON AMSTRAD
PROGRAMACIÓN
BASIC
CON AMSTRAD

Wynford James

inrip^rnmp
PROGRAMACIÓN BASIC CON AMSTRAD
edición española de la obra
BASIC PROGRAMMING ON THE AMSTRAD
Wynford James

publicada en castellano bajo licencia de


MICRO PRESS
Castle House
27 London Road
Tunbridge Wells, Kent

Traducción
Emilio Benito Santos

INDESCOMP, S.A.
Avda. del Mediterráneo, 9
28007 Madrid

© 1984 Wynford James


© 1985 Indescomp, S.A.

Reservados todos los derechos. Prohibida la reproducción total o parcial


de la obra, por cualquier medio, sin el permiso escrito de los editores.

ISBN 84 86176 25 5
Depósito legal: M-10945-85

Impresión:
Gráficas Lormo. Isabel Méndez, 15. Madrid.

Producción de la edición española:


Vector Ediciones.
Gutierre de Cetina, 61.
28017 Madrid (91) 408 52 17
Contenido

Capítulo 1 Primeros pasos.................................................................................. 1


Capítulo 2 La programación.............................................................................. 17
Capítulo 3 Dibujos.............................................................................................. 42
Capítulo 4 Bucles.................................................................................................. 68
Capítulo 5 Acciones condicionadas.................................................................. 87
Capítulo 6 Cadenas literales .............................................................................. 98
Capítulo 7 Bucles y listas.................................................................................... 114
Capítulo 8 Juegos y gráficos.............................................................................. 129
Capítulo 9 Planificación de un programa........................................................ 151
Capítulo 10 Música y sonidos.............................................................................. 173
Capítulo 11 Ficheros.............................................................................................. 181
índice......................................................................................................................... 191
1

Primeros pasos

INTRODUCCIÓN AL SISTEMA DEL MICROORDENADOR

Ya es usted propietario de un microordenador Amstrad y, como tal, se encuentra


en una situación privilegiada, porque lo que usted ha adquirido es un completo siste­
ma de microordenador. Es decir, no va a necesitar comprar nada más para poder
servirse de él desde el momento en que lo desembale.
¿Qué es un sistema de microordenador? Su Amstrad se aloja en una caja gris de
plástico que contiene numerosos componentes electrónicos que le permiten tanto di­
bujar como realizar operaciones aritméticas, o llevar a cabo todas las demás tareas
que hoy día exigimos de los microordenadores personales.
Pero el ordenador por sí solo, sin su ayuda, es una criatura básicamente ignoran­
te; tan torpe como un coche sin conductor. Para que el Amstrad pueda realizar aun
la más mínima tarea útil, ha de recibir instrucciones de un ser humano. Para ello
el Amstrad dispone de un teclado que nos permite comunicarnos con el microproce­
sador situado en su interior y pasarle así nuestras instrucciones.
Sin embargo, los seres humanos tenemos puntos débiles que el ordenador no tie­
ne. Por ejemplo, a nosotros nos gusta ver lo que estamos escribiendo; por eso el
Amstrad dispone de un monitor, especie de pantalla de televisión en la que aparece
cada letra que vamos pulsando en el teclado.
El medio que nos permite dar instrucciones al Amstrad es el teclado, o dispositivo
de entrada de datos. El ordenador también puede comunicarnos mensajes, hacién­
dolos aparecer en el monitor, o dispositivo de salida. De ordenar los datos se ocupa
el propio ordenador. Entonces ¿no necesitamos nada más? ¿Para qué sirve el cas­
sette que se encuentra a la derecha del teclado?
Para poder entender por qué es tan útil el cassette que forma parte esencial del
Amstrad, tenemos que examinar más de cerca los componentes del ordenador. Aun­
que estos componentes son muy numerosos, para nosotros los más importantes son
los que componen su memoria.

EL ORDENADOR OLVIDADIZO

El Amstrad tiene dos tipos de memoria: la ROM y la RAM. Quizá sea más fácil
comprender por qué necesitamos ambas si examinamos las cosas que recuerdan los
seres humanos: nuestros nombres, dónde vivimos, cómo conectar el televisor. Todo
1
2 Programación BASIC con Amstrad

esto está permanentemente almacenado en nuestro cerebro, ya que nos es imprescin­


dible para nuestra vida cotidiana. El ordenador también tiene que recordar perma­
nentemente ciertas instrucciones: tiene que saber aritmética, qué puntos de la panta­
lla tiene que iluminar cuando se pulsa en el teclado la letra ‘A’, cómo dibujar rectas,
y muchas otras cosas. El fabricante del Amstrad ha grabado las instrucciones que
capacitan al ordenador para realizar estas tareas en ROM (read-only memory, me­
moria de sólo lectura).
Se dice que esta memoria es de “sólo lectura” porque el acceso que a ella tienen
tanto el ordenador como el usuario está limitado al mero examen o lectura de la
ROM. Estas instrucciones están grabadas permanentemente y no se las puede cam­
biar. Esto es deseable, ya que no nos interesa interferir accidentalmente con la ca­
pacidad de cálculo que posee el ordenador, ni que, por ejemplo, aparezca en la pan­
talla una ‘Q’ cada vez que tecleemos la ‘A’.
Por otra parte, los seres humanos no recuerdan permanentemente todo lo que ha­
cen. A veces se alegran de poder olvidar aquella pésima película que vieron anoche
en la televisión o las malas notas que obtuvieron en un examen, o la distancia de
la Tierra a la Luna. Gran parte de la información que se utiliza se recuerda sola­
mente durante un tiempo muy corto; por ejemplo, el número de teléfono de la tien­
da de ordenadores, el nombre de las personas que han batido cierto record de atletis­
mo, etc.
Del mismo modo, el ordenador recuerda cierta información sólo temporalmente.
Las instrucciones registradas en ROM hacen posible que el ordenador multiplique
12345 por 6789, pero, una vez realizada la operación y mostrado el resultado en el
monitor, ¿tendría alguna utilidad que almacenase para siempre la respuesta?
Verdaderamente no, y por consiguiente el ordenador almacena las instrucciones que
nosotros le damos en RAM (random-access memory, memoria de acceso aleatorio).
Ésta es una memoria temporal. La RAM está vacía cuando conectamos la máqui­
na, y se va ocupando paulatinamente según vamos introduciendo nuestras instruc­
ciones. Esta información permanecerá en el ordenador hasta que lo apaguemos.
La RAM realiza la función de un encerado en el que el ordenador registra la infor­
mación, la cual se borra cuando lo desconectamos. La RAM es capaz de contener
una cantidad de información que equivaldría a unas 20 páginas de este libro. Natu­
ralmente, el microordenador no nos sería muy útil si sólo pudiese almacenar infor­
mación de modo permanente, ya que pronto agotaríamos toda su memoria y su
efectividad. De ahí que podamos borrar la RAM en cualquier momento, pidiendo
al ordenador que lo haga o, simplemente, desconectándolo.
Por otra parte, la facilidad con que podemos borrar la RAM nos plantea otro pro­
blema. Supongamos que hemos estado trabajando con el ordenador varias horas.
Hemos escrito muchas instrucciones, denominadas programa, que nos permiten di­
bujar una vista de la Tierra divisada desde el espacio. ¿Qué hacemos ahora con esta
obra maestra? Si dejamos el ordenador conectado permanentemente para conser­
var el programa, no podremos volver a utilizarlo, ya que otro programa necesitará
la RAM que hemos ocupado. El dilema es que si desconectamos el ordenador per­
demos el programa almacenado en la RAM.
Así es como llegamos, por un camino indirecto, a lo que explica la presencia del
cassette situado a la derecha del teclado. El ordenador puede convertir cualquier
Primeros pasos 3

programa almacenado en RAM en una serie de señales eléctricas que podemos gra­
bar en cinta magnetofónica. Una vez grabado el programa, podemos desconectar
el Amstrad con toda tranquilidad.
La próxima vez que queramos demostrar a nuestros amigos que somos unos gran­
des artistas, todo lo que tenemos que hacer es pasar por la máquina la cinta que con­
tiene el programa; el ordenador se ocupará de convertir los sonidos grabados en pro­
grama para la RAM, esto es, de “cargar” el programa. Podemos pedir al ordena­
dor que obedezca las instrucciones del programa, es decir, que lo ejecute, y la panta­
lla del monitor mostrará de nuevo la vista de la Tierra desde el espacio.
Cabe mencionar aquí que los diferentes modelos de microordenadores no pueden
cargar los programas de otros modelos.

EL AMSTRAD

Ahora que nos hemos familiarizado un poco con los principales componentes de un
sistema informático y hemos visto cuál es su utilidad, examinemos el Amstrad.
El teclado del Amstrad es similar al de una máquina de escribir, si bien está dota­
do de algunas teclas adicionales, de diferente color que el resto del teclado. Vamos
a estudiar para qué sirven esas teclas. Conecte su Amstrad (las instrucciones de ins­
talación aparecen en las páginas F1.1 a F1.6 de la Guía del Usuario que se suministra
con el ordenador).
Si no ha utilizado nunca un microordenador, quizá le preocupe la posibilidad de
averiar una máquina tan costosa tecleando algo indebidamente. No tema: nada que
usted haga en el teclado puede afectar permanentemente al Amstrad. Si la pantalla
presenta un color rojo subido y no muestra nada de que lo usted escribe, lo peor
que puede ocurrir es que tenga que desconectar el ordenador. Cuando vuelva a co­
nectarlo, el problema habrá desaparecido.
Al encender su Amstrad, verá en la pantalla una líneas de texto que le anuncian
que está utilizando un ordenador Amstrad, y a continuación, en otra línea,
‘BASIC 1.0’. BASIC es el lenguaje de ordenador utilizado por la mayor parte de
los microordenadores, y en concreto por el Amstrad. Algo más abajo en la pantalla
aparecerá el mensaje ‘Ready’ (preparado), y en la siguiente línea, un pequeño rec­
tángulo, junto al borde izquierdo de la pantalla. Este rectángulo se denomina cur­
sor de texto-, indica el lugar en que va a aparecer el siguiente carácter que se escriba;
equivale, pues, al punto de la pluma.
Cuando usted conecta el Amstrad, las teclas están en situación de minúsculas,
aunque las letras que están grabadas en las teclas sean mayúsculas. Así, cuando pul­
se las teclas A, B, C observará cómo el Amstrad escribe en la pantalla:

abe«

Observe también que el cursor se desplaza a medida que usted va escribiendo y que
siempre indica la próxima posición en que el ordenador va a escribir un carácter.
Pulse ahora la tecla verde CAPS LOCK de la izquierda del teclado. Pulse a conti­
nuación las teclas A, B y C de nuevo y podrá ver en la pantalla:
4 Programación BASIC con Amstrad

abeABCB

La tecla CAPS LOCK cambia todas las letras del alfabeto a mayúsculas. Si la pul­
samos otra vez, volvemos al modo de minúsculas. Así, pulsando CAPS LOCK por
segunda vez y tecleando A, B y C tendremos:

abcABCabc®

Como se puede observar, CAPS LOCK funciona como conmutador que bascula en­
tre los modos de mayúsculas y minúsculas. Sin embargo, no hay forma de saber
en qué situación se encuentra el conmutador con sólo mirar al teclado. El único
modo de averiguarlo es pulsar una tecla y observar el resultado.

Si cometemos errores

En realidad no ocurre nada grave si se pulsa una tecla equivocadamente o si se escri­


be en mayúsculas cuando se deseaba hacerlo en minúsculas; estos errores se corrigen
muy fácilmente en el Amstrad. Pulse la tecla verde de la parte superior derecha del
teclado, marcada con DEL, y no la suelte.
El cursor regresa al comienzo de la línea, borrando todos los caracteres que en­
cuentra a su paso. La tecla DEL es la tecla de borrado (delete en inglés), que hace
desaparecer el carácter que se encuentre a la izquierda del cursor. Si se mantiene
esta tecla pulsada durante algún tiempo, su acción se repite automáticamente y con­
tinúa borrando caracteres hasta que se la suelta o hasta que el cursor llega al princi­
pio de la línea.
Análogamente ocurre con casi todas las teclas del Amstrad: se autorrepiten tras
una breve pausa. Pulse la tecla A y no la suelte mientras en la pantalla sigan apare­
ciendo letras ‘a’. Observe que se han completado seis líneas y que el cursor se ha
detenido en la séptima.
La razón por la que el ordenador detiene la repetición automática de la tecla es
porque ya tenemos 255 caracteres y el Amstrad no permite líneas de mayor longitud
que ésta. Para el Amstrad, el borde derecho de la pantalla no es el final del renglón,
de modo que, aunque lo que hemos escrito ocupe más de seis líneas físicas de la pan­
talla, para el ordenador es una sola línea continua.
Para el Amstrad, la línea sólo termina cuando se lo indicamos explícitamente. Po­
demos decirle “éste es el final de esta línea” pulsando la tecla grande azul que está
marcada con ENTER. Hágalo y vea qué sucede.
Después de la línea de letras ‘a’ aparece el siguiente mensaje:

Syntax error
Ready

Cuando pulsamos la tecla ENTER, le estamos pidiendo al ordenador que dé por ter­
minada la línea que estábamos escribiendo y que la introduzca en la memoria. En
Primeros pasos 5

este momento estamos usando el Amstrad en modo inmediato o directo, así denomi­
nado porque cada vez que pulsamos ENTER el ordenador examina la línea que aca­
bamos de introducir y obedece inmediatamente las instrucciones contenidas en ella.
En todo caso, el ordenador ha de entender las instrucciones para poder obedecerlas.
En concreto, no ha encontrado ningún sentido a la línea de 255 letras ‘a’; las pala­
bras ‘Syntax error’ son su forma de decir “no entiendo”. La palabra ‘Ready’ sólo
significa que el ordenador ha terminado de obedecer todas las órdenes y está prepa­
rado para recibir más.
El objetivo de este libro es estudiar las instrucciones que el Amstrad sí entiende;
pero antes de pasar a explicarlas, vamos a completar el breve examen del teclado.
Las dos teclas verdes marcadas con SHIFT sirven para seleccionar los caracteres
de la parte superior de las teclas que tienen dos símbolos. Teclee los números
1234567890 (situados en la fila superior del teclado) y después, manteniendo pulsada
una de las dos teclas SHIFT, teclee 1234567890 de nuevo:

1234567890! " #$'/.?<’ () _■

Cualquier tecla que esté marcada con dos caracteres hará que aparezca en la pantalla
el de la mitad superior, si la pulsamos al mismo tiempo que una de las teclas SHIFT.
Aunque el conmutador CAPS LOCK se encuentre en situación de minúsculas, al pul­
sar SHIFT al mismo tiempo que una letra alfabética, ésta aparecerá en mayúscula.
Las letras marcadas con dos símbolos producen normalmente el de la mitad infe­
rior. Hay otro conmutador que cambia esta situación: funciona pulsando CAPS
LOCK al tiempo que se mantiene pulsada la tecla verde CTRL situada en el extremo
inferior derecho del teclado. Hágalo y pulse a continuación las teclas de la primera
fila del teclado:

! ()_■ .

Las teclas alfabéticas escribirán ahora en mayúsculas. No obstante, puede conti­


nuar escribiendo números también, ya que el Amstrad tiene un teclado independien­
te, situado a la derecha del principal, destinado a este fin. Para normalizar el tecla­
do se debe pulsar nuevamente la combinación CTRL/CAPS LOCK.
La tecla DEL es útil cuando se observa un error poco después de cometerlo, esto
es, cuando el carácter incorrecto está cerca del cursor. Pero ¿qué ocurre si el error
está al principio de la línea y no queremos perderla? Escriba lo siguiente sin pulsar
la tecla ENTER:

Ezte es un error

Tenemos que poner una *s’ en lugar de la *z’ de ‘Ezte’. Recordemos que el cursor
nos indica en qué posición aparecerá el siguiente carácter. La posición del cursor
puede ser modificada utilizando las teclas marcadas con flechas y situadas por enci­
ma del teclado numérico. Por eso se las denomina teclas del cursor. Pulse la tecla
♦- y no la suelte. El cursor se desplazará hacia la izquierda de la línea. Suéltela
cuando el cursor esté sobre la letra ‘z’ de ‘Ezte’. No se preocupe si se pasa; con
6 Programación BASIC con Amstrad

la tecla podrá volver a llevar el cursor al punto deseado. La ‘z’ será visible a
través del cursor. Si pulsamos ahora la tecla CLR, situada junto a la DEL en la
parte superior derecha del teclado, la ‘z’ desaparecerá y tendremos:

Ete es un error.

Los restantes caracteres de la línea han retrocedido un lugar y el cursor se encuentra


ahora sobre la ‘t’ de ‘Ete’. Para borrar cualquier otro carácter de la línea seguiría­
mos el mismo procedimiento: situar el cursor sobre el carácter incorrecto y pulsar
CLR. Si tenemos varios caracteres equivocados seguidos, manteniedo pulsada la te­
cla CLR haremos que ésta se autorrepita y los borre todos. DEL borra el carácter
situado a la izquierda del cursor, mientras que CLR hace desaparecer el que está
situado bajo el cursor.
En este ejemplo queremos también intercalar un nuevo carácter en la palabra
‘Ete’. Desplacemos el cursor hasta la ‘t’ y pulsemos la tecla S. Así insertamos una
‘s’ en el lugar correcto y el resto de la línea se desplaza un lugar hacia la derecha:

Este es un error

Los errores que se cometen al escribir la líneas son fáciles de corregir usando las
teclas CLR, DEL y las del cursor, pero es preciso recordar que este sistema funciona
siempre que no se haya pulsado antes ENTER. Una vez pulsada esta tecla, el orde­
nador considera que la línea está terminada. Para corregir (o, como se dice en la
jerga informática, editar) líneas que ya hayan sido introducidas en la memoria, hay
que seguir un procedimiento diferente.
Las teclas CTRL, ESC y COPY realizan funciones especiales que se comprende­
rán mejor cuando hayamos practicado algo más con el Amstrad. La tecla TAB no
tiene ningún cometido especial; sólo produce una flecha que apunta a la derecha.

Cómo dar órdenes al Amstrad

Ya hemos visto que para el Amstrad una línea de 255 letras ‘a’ no tiene ningún senti­
do. ¿Qué tipo de instrucciones puede entender y obedecer este ordenador? Son
muchas y se las daremos a conocer más adelante. Hay órdenes que hacen que el
Amstrad dibuje rectas en la pantalla, cambie los colores, realice cálculos complica­
dos o emita notas musicales. Todas estas órdenes tienen algo en común: el ordena­
dor las obedece porque el fabricante ha grabado los pormenores de estas órdenes
en la memoria ROM, y por lo tanto el ordenador puede reconocerlas.
Pero esto da lugar a que el ordenador nos pueda parecer tanto muy listo como muy
torpe, según los casos. Puede realizar maravillas y, no obstante, por una sola letra
incorrecta, se negará a obedecer y hará que en la pantalla aparezca el mensaje ‘Syntax
error’ para indicarnos que está perdido. Vamos a ver una de las órdenes que el Ams­
trad puede obedecer: la instrucción PRINT (imprimir, escribir). Un humano quizás
aceptaría PRONT en lugar de PRINT (después de todo, la ‘i’ y la ‘o’ están juntas
en el teclado y es fácil cometer este error). Pero el ordenador no aceptaría PRONT.
Primeros pasos 7

Cuando demos órdenes al Amstrad tendremos que atenernos a las reglas de sinta­
xis del lenguaje de ordenador que él entiende. Ustedpuedeentenderestafraseaun-
cuandonotengaespacios, pero no el Amstrad.

La visualización en la pantalla

Ya estamos preparados para comenzar a utilizar el Amstrad seriamente. Lo prime­


ro que tenemos que hacer es reinicializar (reset) el ordenador; es decir, devolverlo
al estado en que se encontraba en el momento de encenderlo, con la RAM completa­
mente borrada. Para ello podemos desconectarlo y volverlo a conectar; también
podemos obtener el mismo resultado, de modo menos drástico, pulsando la tecla
ESC en combinación con CTRL y SHIFT. La pantalla se borra y vuelve a aparecer
el anuncio de Amstrad.
Cuando estamos seguros de que la línea que hemos escrito, es decir, nuestra “en­
trada” (input) hacia el ordenador, es correcta, pulsamos la tecla ENTER para indi­
car al Amstrad que hemos acabado y que ya puede obedecer la orden. Por el mo­
mento escribiremos <ENTER) para recordarle que debe pulsar esta tecla cada vez
que termine de escribir una instrucción. Escriba ahora lo siguiente:

mode2<ENTER>

y obtendrá el mensaje:

Syntax error
Ready

El Amstrad no ha entendido la orden. En el lenguaje BASIC del Amstrad se utili­
zan los espacios para indicar dónde termina una palabra y dónde comienza la si­
guiente. El Amstrad puede comprender ‘mode’ si le sigue un espacio, pero en este
caso cree que la palabra es *mode2’, que él no conoce. Los espacios son muy impor­
tantes en el BASIC de Amstrad, por lo que deberá asegurarse de que no omite nin­
guno en los siguientes ejemplos. En algunos casos descubrirá usted por sí mismo
que los espacios no parecen tener importancia en algunas instrucciones (por ejem­
plo, precediendo a las dobles comillas). De todos modos, lo más seguro es espaciar
siempre las palabras ya que, cuando los espacios no son necesarios, el Amstrad sen­
cillamente los ignora, mientras que si lo son y usted los omite, el Amstrad se queja­
rá. Escriba ahora:

mode 2<ENTER>

En esta ocasión el ordenador reconoce la palabra ‘mode’ y obedece la instrucción.


La pantalla se borra y aparece el mensaje “Ready”, en letras mucho más estrechas,
en el extremo superior izquierdo de la pantalla.
En el mundo real hay diversas clases de papel destinadas a usos diferentes. El
8 Programación BASIC con Amstrad

arquitecto no diseña una casa en un cuaderno de notas, y el novelista no utiliza papel


de tamaño A3 para escribir sus relatos. En informática, la pantalla equivale a la
hoja de papel, y por lo tanto es útil poder elegir el formato que más nos convenga.
La instrucción ‘mode’ seguida de los números 0, 1 o 2 selecciona uno de los forma­
tos de que dispone el Amstrad. Cada modo permite la visualización de un número
diferente de caracteres por línea.
Si el texto que tenemos que escribir es muy extenso, nos será útil poder visualizar
el mayor número de caracteres posible. El modo 2 es el más adecuado en este caso,
ya que en este modo el Amstrad escribe en una pantalla de 25 líneas por 80
columnas.
Teclee ahora:

mode 1<ENTER>

La pantalla se borrará de nuevo y aparecerá el mensaje ‘Ready’ en el extremo supe­


rior izquierdo de la pantalla. Este modo ya nos es familiar, pues es el que el Ams­
trad adopta cuando lo encendemos o reinicializamos. El modo 1 tiene 25 líneas de
40 caracteres cada una. En este modo los caracteres son más legibles; podemos con­
siderarlo como modo “de trabajo’’ para la introducción de instrucciones.
Escriba ahora lo siguiente:

mode 0<ENTER>

De nuevo aparecerá ‘Ready’, pero ahora en caracteres mucho más anchos. El modo
0 nos da 25 líneas de 20 caracteres cada una. Este modo es el más adecuado para
dibujar en color, como veremos más adelante.

Modo Número de líneas Caracteres por línea

0 25 20
1 25 40
2 25 80

Figura. 1. Los tres modos de pantalla del Amstrad.

Casi todos los ordenadores son bastante exigentes en cuanto a la utilización de


mayúsculas y minúsculas cuando escribimos las instrucciones, pero una de las bue­
nas características del Amstrad es que acepta igualmente ‘mode 0’, ‘MODE 0’ o in­
cluso ‘mOde 0’ como órdenes válidas. Por razones que veremos más adelante, es
aconsejable utilizar siempre letras minúsculas. En el resto del libro aparecerán ins­
trucciones en mayúsculas y en minúsculas para demostrar que son intercambiables,
pero le recomendamos que se acostumbre a escribirlas en minúsculas. Finalmente,
escriba
Primeros pasos 9

iriode 1<ENTER?

para hacer que el ordenador vuelva al “modo de trabajo”.

La instrucción PRINT

Escriba:

pr i nt"Pedro"<ENTER?

En la pantalla podrá ver:

Pedro
Ready
IB

Utilizamos PRINT cuando queremos visualizar algo en la pantalla. Esta instruc­


ción escribe, sin modificación alguna, cuanto pongamos entre comillas. Teclee

print" 7+5"<ENTER?

y obtendrá

7+5
Ready

El ordenador no ha calculado el valor de 7 + 5 porque la expresión estaba entre comi­


llas, y todo lo que encuentra entre comillas lo copia literalmente.
Usemos ahora el Amstrad como si fuera una calculadora, sirviéndonos de PRINT
para visualizar los resultados. Escriba:

print 7+5<ENTER?

(El signo * + ’ se obtiene de la tecla del combinada con SHIFT.) El ordenador


escribirá:

12

Esta vez ha calculado la suma y escrito el resultado, porque los números no estaban
entre comillas. El espacio que precede al 12 está reservado para el signo; los núme­
ros mayores que 0 aparecen con un espacio delante, en lugar del signo +. Teclee:

print 7-5<ENTER?
10 Programación BASIC con Amstrad

(El signo - se encuentra en la misma tecla que el =.) El ordenador escribirá:

Ahora pruebe

print 5-7ÍENTER>

que dará

La multiplicación es un poco más peculiar. En lugar del aspa, X, los ordenadores


suelen utilizar el asterisco, *, como signo de multiplicar. Escriba:

print 9*7<ENTER>

(El signo * se obtiene de la tecla combinada con SH1FT.) El ordenador


escribirá:

63

El signo de división es la barra inclinada, /, que está en la tecla del signo de interro­
gación, “?’. Escriba:

print 12/4<ENTER>

y obtendrá

Hasta ahora sólo hemos hecho aritmética muy sencilla, pero naturalmente el or­
denador puede realizar cálculos mucho más complicados. Escriba:

print 12345*9876<ENTER>

y obtendrá

121919220

O, con tres factores,

print 12.34*5.67*8.9<ENTER>

lo cual dará
Primeros pasos 11

622.71342

Después de realizar el cálculo anterior, observará que el contenido de la pantalla se


ha desplazado hacia arriba. La instrucción ‘print “Pedro” ’ con que empezamos
esta sección ha desaparecido. El ordenador desplaza la pantalla hacia arriba cuan­
do el cursor ha alcanzado la última línea y todavía tiene que seguir escribiendo.
En este momento la pantalla está bastante llena. Vamos a borrarla, aprovechan­
do al mismo tiempo para presentar otra instrucción de BASIC. Escriba:

cls<ENTER>

Estas letras son la abreviatura de CLear Screen (borrar la pantalla); su efecto no


requiere más explicación. A partir de ahora, utilice ‘cls<ENTER>’ siempre que
quiera borrar la pantalla.

Orden y claridad en la pantalla

Dado que tendrá que utilizar la instrucción PRINT tan frecuentemente para progra­
mar el Amstrad, le alegrará saber que la ROM reconoce el signo *?’ como abreviatu­
ra de ‘print’. Escriba:

?"E1 signo ? es abreviatura de print"<ENTER>

(El signo ? se obtiene con / y SHIFT.) Escriba:

?"Si suma 7 y 6 obtiene";"el resultado"<ENTER>

y en la pantalla aparecerá:

Si suma 7 y 6 obtieneel resultado

El signo le pide al Amstrad que siga escribiendo y además que lo haga en la mis­
ma línea. Pero, al no haber dejado espacio entre ‘observe’ y las comillas en la ins­
trucción, se nos han juntado las dos palabras: ‘obtieneel’. No ha sido demasiado
útil, ¿verdad? Pruebe entonces con esto:

?"Si suma 7 y 6 obtiene";7+6<ENTER>

En la pantalla ha aparecido:

Si suma 7 y 6 obtiene 13

Así está mejor. El ordenador ha realizado el cálculo y mostrado el resultado. Pero


escriba:
12 Programación BASIC con Amstrad

?"Si calcula 5-6 obti ene"; 5-6;"1 o cual e


s confuso"CENTER>

En la pantalla aparece:

Si calcula 5—6 obtiene-1


lo cual es contuso

Todo esto demuestra el cuidado que hay que tener con el en las instrucciones
PRINT. Pruebe ahora con los espacios en su sitio:

?"Si suma 7 y 6 obtiene ";"el result ado" < ENTERA-


?"Si calcula 5-6 obtiene ";5-6;"lo cual
no es con-f uso"<ENTERA-

Escriba:

?1 ; 2; 3CENTERA-

y observe que en

el ordenador ha puesto un espacio antes de cada número, reservado para un posible


signo y otro después. Pruebe ahora con:

?12;13;14CENTERA-

lo que da:

12 13 14

Como puede observar, estos números no quedan alineados en vertical con los que
escribimos antes. Si estuviésemos tratando de escribir números en columnas, esta
forma de visualizarlos sería confusa. Probemos con comas en lugar de con el signo
de punto y coma; escriba:

? 1,2,3<ENTER>

y ahora:

?12, 13, 14< ENTERA­

IS 14
Primeros pasos 13

Esto tampoco es perfecto porque, por ejemplo, podríamos no querer tanta separa­
ción entre columnas, pero al menos los números han quedado bien alineados. La
coma ha pedido al ordenador que saltase a la siguiente “zona de escritura” de la
pantalla. El mismo método vale para palabras:

?"F'edro", "Juan", "El ena"<ENTER>


Pedro Juan Elena

Si cree que los nombres no están bien alineados con los números, recuerde que éstos
van precedidos de un espacio.

Organización de la pantalla en modo 1

¿Cómo sabe el Amstrad en qué lugar de la pantalla debe escribir para mantener la
alineación en vertical? Dicho de otro modo, ¿qué son las “zonas de escritura”? Ya
sabemos que en el modo 1 la pantalla consta de 25 líneas de 40 caracteres cada una.

Podemos escribir un carácter en cualquier lugar de la pantalla siempre que identi­


fiquemos su posición mediante dos números: el número de columna y el de fila. La
letra ‘A’ de la figura 2 se encuentra en la columna 20 y en la línea 13, aproximada­
mente en el centro de la pantalla. Observe que siempre mencionamos el número de
columna antes que el de fila.
14 Programación BASIC con Amstrad

14 27

ZONA ZONA ZONA


1 2 3

Figura 3. Las zonas de escritura en modo 1.

El Amstrad divide la pantalla en zonas de escritura verticales, cada una de ellas


de 13 caracteres de anchura. Si en una instrucción PRINT separamos los elementos
con comas, el primero se empieza a escribir en la columna 1, el segundo en la 14
y el tercero en la 27. Para el cuarto tendría que empezar en la columna 40 pero,
como ya no hay más sitio para otra zona de 13 caracteres, saltará a la columna 1
de la línea siguiente. Si alguno de los elementos es de más de 13 caracteres, abarcan­
do, por lo tanto, dos o más zonas, el siguiente elemento se escribe en la siguiente
zona libre. Escriba:

?1,2,3,4,5<ENTER>

y verá cómo el ordenador escribe los dos últimos números en una nueva línea. Prue­
be con

?"Demasiado 1 argo. " , "Cabe. " , "F'ero este n


Q cabe."<ENTER>

para ver cómo se las arregla el ordenador cuando tiene que escribir algo que no cabe
en una zona de escritura.

Las instrucciones TAB y SPC

Aunque las zonas de escritura son útiles para escribir los datos en forma de tabla
en la pantalla, sería una limitación grave estar restringidos a ellas. El BASIC de
Amstrad dispone de intrucciones que nos permiten elegir a nuestro gusto las posicio­
nes de escritura en la pantalla. Así, para escribir un título centrado podemos utili­
zar la instrucción PRINT TAB o, abreviadamente, ?TAB. Escriba lo siguiente:
Primeros pasos 15

cls<ENTER>
?tab(6)"Esto empieza en la columna 6"<ENTER>

Si consultamos la figura 2, veremos que en modo 1 disponemos de 40 columnas.


Podemos hacer referencia a ellas por sus números.
Con la instrucción ?TAB(6) estamos pidiendo al ordenador que empiece a escribir
a partir de la columna número 6. En modo 1, el número que va entre paréntesis
después de ‘TAB’ puede ser cualquiera comprendido entre 1 y 40.
Quizá quiera usted experimentar con números mayores que 40, o con números
negativos.
Dentro de una misma instrucción PRINT se pueden incluir varias cláusulas TAB:

?tab(6)"Buenos"tab(18)"di as"tab(30)"ami g
□s"<ENTER>

La instrucción TAB ordena avanzar hasta la posición especificada escribiendo espa­


cios; así, cuando el ordenador ha escrito “Buenos”, escribe espacios hasta alcanzar
la columna 18, en la cual empieza a escribir “dias”. Se podría pensar que la instruc­
ción

7tab(30)"ami gos"tab(18)"di as"tab(6)"Buen


□s"<ENTER>

debería producir el mismo efecto que la anterior, pero no es así. La cláusula TAB
no hace retroceder la posición de escritura dentro de una línea, sino que previamente
provoca el avance a la línea siguiente.
Escriba ahora:

?"La"spc(4)"frase"spc(4)"queda"spc(4)"mu
. y"spc(4)"espaciada"<ENTER>

El ordenador deja 4 espacios entre cada dos palabras. Con SPC(10) dejaría 10 espa­
cios, y así sucesivamente. El parámetro de SPC, es decir, el número que va entre
paréntesis, puede estar entre 1 y 40 en modo 1. SPC y TAB se pueden mezclar en
una misma instrucción PRINT:

?tab(8)"Una mezcla de TAB"spc(8)"y SPC"<ENTER>

Como habrá observado, las cláusulas TAB y SPC impiden el salto a la línea siguien­
te lo mismo que si se tratara de signos de punto y coma
16 Programación BASIC con Amstrad

Ejercicios

1. Escriba varias instrucciones PRINT, utilizando como separador la coma, en los


modos 0 y 2. ¿Por qué son estos resultados diferentes de los que se obtienen en
modo 1?
2. Experimente con TAB y SPC en modo 2 y en modo 0. ¿Hay diferencias entre
los márgenes de valores que podemos utilizar en los diversos modos?
2

La programación

PROGRAMACIÓN SENCILLA

En el capítulo anterior hemos estado utilizando el ordenador en modo inmediato o


directo. Cada vez que escribíamos una instrucción, el Amstrad la obedecía inmedia­
tamente, si la entendía. El modo directo es útil porque nos permite experimentar
con las órdenes y observar los resultados inmediatemente.
Pero lo más normal es utilizar el ordenador en modo de programa. Para observar
la diferencia entre ambos modos, escriba lo siguiente:

1 print"Manolo"<ENTER>

Al pulsar la tecla ENTER no ha ocurrido nada evidente. Como hemos escrito un


número, el 1, al principio de la línea, el ordenador lo ha considerado como número
de línea y ha supuesto, por consiguiente, que no tenía que ejecutar la instrucción
inmediatamente, sino almacenarla en la RAM en espera de que le pidamos que la
ejecute.
Para comprobar que efectivamente la instrucción ha quedado almacenada en la
RAM, escriba:

list<ENTER>

En la pantalla ha aparecido el listado del programa, que de momento consiste en


solamente una línea. El ordenador reconoce la palabra ‘print’ como una de las pa­
labras clave de BASIC y por lo tanto la ha convertido en PRINT, en mayúsculas.
Escriba ahora:

9 print"Enrique"<ENTER>
5 print"Ricardo"<ENTER>
list<ENTER>

A pesar de que hemos introducido las líneas en el orden 1, 9, 5, en el listado apare­


cen en orden de números crecientes, y en ese mismo orden las ejecutará cuando lle­
gue el momento. ¿Cómo podemos hacer para que el ordenador ejecute el progra­
ma? Escriba:

17
18 Programación BASIC con Amstrad

run<ENTER>

El ordenador ejecuta el programa, esto es, obedece las instrucciones del mismo
por orden creciente de número de línea. Cuando ha terminado de ejecutarlo, el pro­
grama permanece almacenado en la memoria, como podrá comprobar escribiendo
de nuevo LIST<ENTER>. Teclee:

5 print"Elena"<ENTER>
list<ENTER>

Observará que la nueva línea ha sustituido a la antigua, y que el pobre Ricardo


ha desaparecido. Cuando desee efectuar un cambio en cualquier línea, escriba sim­
plemente la nueva línea con el mismo número de la que desee sustituir. Teclee:

1<ENTER>
listCENTER>

La línea ha sido reemplazada por una línea vacía, por lo que el Amstrad no la inclu­
ye ya como parte del programa. De este fácil modo podemos eliminar cualquier lí­
nea que no necesitemos.
Ahora podemos hacer varias cosas con el programa: ampliarlo añadiendo nuevas
líneas en cualquier orden, conservarlo para uso futuro grabándolo en la cinta o bo­
rrarlo de la RAM. Esto último es lo que vamos a hacer, hasta que tengamos un
programa que merezca la pena. Teclee:

new<ENTER>

Esto indica al ordenador que se desea borrar el programa y comenzar otro nuevo.
Si tecleamos ahora list<ENTER> no aparecerá ningún listado, ya que el programa
se ha borrado.

AYUDAS QUE PUEDE OFRECERLE EL AMSTRAD

El Amstrad posee diversas características que facilitan considerablemente la progra­


mación.
Lo prudente es espaciar los números de las líneas, en previsión de que más tarde
haya que intercalar alguna instrucción entre las ya introducidas. Se complicarán las
cosas si usted ha dado a sus líneas los números 1, 2, 3 y 4 y luego se le ocurre interca­
lar una nueva línea entre la 2 y la 3. Por eso es habitual numerar las líneas de diez
en diez; de esta forma dejamos números libres que más tarde podemos asignar a las
líneas adicionales. La numeración automática de las líneas es una labor que el Ams­
trad puede realizar por usted. Utilizaremos este método para escribir el siguiente
programa. Teclee:

auto<ENTER>
La programación 19

El ordenador escribirá “10” y esperará a que usted introduzca la línea. Teclee:

10 mode 0CENTER>
20 ?"Esto esta en modo 0"CENTER>
30 ?"Aqui tiene una multiplicacion:"<ENTER>
40 ?"73.45 por 5.769 da"; 73.45*5.769CENTER>

El ordenador escribirá también el número 50 después de la última línea, pero ya no


tenemos más líneas que añadir al programa. Para detener la numeración automáti­
ca de las líneas, debemos pulsar la tecla roja ESC (“escape”), situada en la parte
superior izquierda del teclado. Teclee ahora:

1 i st-'.ENTER>

y observará que la línea 50 no’está en el programa. Teclee:

run CENTER)-

y verá cómo el ordenador obedece su programa línea por línea. Teclee:

mode 1 CENTER)-

para volver al modo “de trabajo”.


AUTO puede empezar la numeración a partir de cualquier número de línea. Ade­
más, podemos elegir también el intervalo entre líneas, aunque generalmente se espa­
cian del modo arriba indicado. Teclee:

auto 15, 1 CENTER)-

y observará que los números de las líneas comenzarán por el 15 y se incrementarán


de uno en uno. Teclee:

15?"He aqui una linea mas"CENTER>


16?"y aqui otra"CENTER)-

y pulse <ESC> de nuevo. Liste el programa y ejecútelo. Verá que las dos nuevas
líneas han sido insertadas en el programa en la posición correcta. El ordenador
comprueba si los números de línea que va generando han aparecido ya en el progra­
ma, ya que en tal caso las líneas nuevas sustituyen a las antiguas de igual número
en cuanto pulsamos <ENTER>. El ordenador le advierte de este riesgo mostrando1
un asterisco * después del número de línea. Compruébelo tecleando:

autaC ENTER)-

En el modelo CPC664 aparece la línea completa, la cual puede ser editada o conservada sin modificación.
20 Programación BASIC con Amstrad

El ordenador escribirá:

10*

para advertirle de que ya tiene una línea con el número 10 y de que, si escribe algo
antes de pulsar <ENTER>, la línea quedará sustituida por lo que escriba. Si no de­
sea modificar el programa, pulse <ESC>.
Si sigue intercalando líneas en el programa, podrá llegar a encontrarse con el pro­
blema que intentaba evitar: que no quede lugar para nuevos números de línea. Si
lista el presente programa, verá que ya no hay hueco para otra línea entre la 15 y
la 16. Afortunadamente, el Amstrad puede ayudarnos también en este caso. Teclee:

renum<ENTER>
list<ENTER>

La orden RENUM vuelve a numerar todas las líneas del programa, empezando por
la número 10 e incrementando los números de línea de diez en diez. Al igual que
con AUTO, se puede elegir tanto el número de la primera línea como el intervalo
entre líneas. Teclee:

renum 100,3<ENTER>
list<ENTER>

y verá cómo el programa queda renumerado comenzando por la línea 100 y con los
siguientes números de línea espaciados de 5 en 5.

¿Qué podemos hacer si cometemos un error?

Escriba exactamente lo siguiente:

l.pront"Esta es la primera 1 inea"<ENTER>

En esta línea hemos cometido un error deliberadamente, al escribir ‘pront’ en lugar


de ‘print’. En cuanto pulsamos <ENTER> en modo inmediato, el Amstrad intenta
obedecer la orden; si la orden es errónea, el ordenador emite un mensaje de error
para informar de lo que ha ocurrido.
Esto no ocurre así en modo de programa. Lo que el Amstrad hace en este caso
es almacenar cualquier línea que esté numerada y no comprueba si es inteligible
mientras no le pidamos que ejecute el programa. Escriba:

run<ENTER>

El ordenador tratará de obedecer las instrucciones de la línea 1, pero se ve obligado


a abandonar la ejecución del programa porque no reconoce ‘pront’. Le dirá cuál
es la línea que está causando el problema, e incluso la muestra en la pantalla. Usted
La programación 21

puede ahora editar la línea 1 para corregir el error.


Como puede observar, el cursor se encuentra sobre el primer carácter de la línea,
o sea, sobre el número 1. Utilizando la tecla de cursor a la derecha (la tecla con
flecha situada junto a la tecla verde de COPY de la parte superior derecha del tecla­
do), desplace el cursor hasta que se encuentre sobre la ‘o’ de ‘pront’. En el capítulo
anterior vimos que pulsando CLR borrábamos el carácter situado en la posición del
cursor. Esto es lo que tenemos que hacer ahora, ya que debemos borrar la ‘o’. Pul­
se CLR una vez. La línea queda de la siguiente forma:

1 prnt"Esta es la primera linea"

con el cursor sobre la ‘n’. Ahora tenemos que insertar la letra ‘i’. El Amstrad inser­
ta automáticamente cualquier carácter que tecleemos, delante (a la izquierda) del ca­
rácter que se encuentra bajo el cursor. Pulse ahora ‘i’ y podrá leer:

1 prínt"Esta es la primera linea"

Los cambios que hemos realizado hasta ahora han afectado sólo al aspecto de la
línea en pantalla. Pulse <ENTER> y el Amstrad sustituirá la línea incorrecta por
esta nueva versión corregida. (En este caso no importa que el cursor no se encuentre
al final de la línea.) Si quiere comprobar que la línea ha quedado corregida, liste
otra vez el programa.
Si observa que ha cometido un error en su programa, antes de ejecutarlo, puede
corregir la línea fácilmente tecleando:

edit 1<ENTER>

o el número de cualquier otra línea que desee editar. Después puede utilizar las te­
clas del cursor, la CLR o quizás la DEL para corregir la línea. Para practicar esta
técnica, introduzca algunas modificaciones en las líneas de su programa y devuelva
después las líneas a su forma original.

La edición mediante el copiado de líneas

Hay otro método de edición, denominado “del cursor de copia”, que se basa en
copiar líneas de la pantalla. Escriba lo siguiente:

1 pront"He aquí otra linea con error"<ENTER>

Pulse la tecla de ‘cursor hacia arriba’ (T) al tiempo que pulsa una de las teclas
SHIFT. Ha aparecido un segundo cursor, que se ha superpuesto al 1 de la línea que
acaba de escribir. Éste es el cursor de copia, que señala lo que vamos a copiar. El
otro es el cursor normal de texto, que muestra en qué lugar de la pantalla va a apare­
cer lo que copiemos. Pulse la tecla COPY una vez y verá que el ‘1’ queda copiado
en la nueva línea. Pulse COPY tres veces más y verá lo siguiente en su pantalla:
22 Programación BASIC con Amstrad

1 pront"He aquí otra linea con error"


1 pr

Al llegar aquí no deseamos copiar la ‘o’, pues ésta es la parte incorrecta de la línea.
Como el cursor inferior es el de texto, o sea, el que normalmente muestra dónde
se va a escribir el siguiente carácter que pulsemos, si pulsamos ahora la ‘i’ ésta apa­
recerá en esta posición y la pantalla mostrará:

1 pront"He aquí otra linea con error"


1 pr i

Ahora tenemos que copiar el resto de la línea, pero sin la ‘o’. Si piensa que puede
desplazar el cursor de copia utilizando sin más las teclas del cursor, pruebe y verá
lo que ocurre.
Las teclas del cursor mueven el cursor de texto, pero el Amstrad emitirá un pitido
si usted intenta salirse de la línea nueva que está confeccionando. El cursor de copia
se mueve siempre manteniendo pulsada una tecla SHIFT al tiempo que pulsa las de
movimiento del cursor. Hágalo así para colocar el cursor de copia sobre la ‘n’ de
‘pront’ saltándose la *o’. Asegúrese de que el cursor de texto esté a la derecha de
la ‘i’ de ‘1 pri’, ya que es ahí donde el ordenador comenzará a escribir el texto copia­
do. Mantenga pulsada la tecla COPY hasta que llegue al final de la línea que está
copiando. No se preocupe si copia también espacios, porque el Amstrad no los ten­
drá en cuenta. Pulse <ENTER> para que la nueva línea 1 sustituya a la antigua en
la memoria del ordenador, lo que podrá comprobar listando el programa.
En este momento este proceso puede,parecerle complicado, pero se familiarizará
con él rápidamente. Merece la pena que dedique algún tiempo a aprender a editar,
ya que así podrá programar con rapidez mucho mayor.

Las mil y una aplicaciones de la tecla COPY

Aunque la tecla COPY es muy útil para editar, también se la puede aprovechar para
introducir líneas nuevas. Si en el programa hay varias líneas similares, se puede co­
piar trozos de una línea a otra. Veamos un ejemplo sencillo. Escriba:

new<ENTER>
auto<ENTER>
10 p r i n t "*****■**"< E NT E R>

Ahora utilice las teclas del cursor combinadas con la de SHIFT para poner el cursor
sobre la “p” de “print”. Pulse la tecla COPY y copie el resto de la línea; al final,
pulse <ENTER>. Ahora debe de haber en la pantalla lo siguiente:

10 print"»**»»*♦"<ENTER>
20 pri n t"*******"< ENTER >
30
La programación 23

Repita este procedimiento de copia para las líneas 30, 40 y 50. Pulse ESC en cuanto
aparezca el número de la línea 60. Liste y ejecute el programa. El resultado deberá
ser un rectángulo formado por asteriscos. Podemos utilizar esta misma técnica para
copiar sólo parte de una línea anterior o para combinar diferentes partes de otras
líneas.
Nos hemos concentrado tanto en el tema de la edición que hemos descuidado lo
relativo a la programación. Utilicemos algunas de las instrucciones que conocimos
en el capítulo anterior. Escriba:

new<ENTER>
auto<ENTER>
10 ?"He aquí un punto y coma ";<ENTER>
20 ?"y mira lo que hace!"<ENTER>
30 <ESC>

Ejecute el programa. ¿Recuerda para qué sirve el punto y coma? Impide que el
cursor salte a la línea siguiente. Edite la línea 10 para suprimir el punto y coma y
vuelva a ejecutar el programa. Observará que el texto aparece ahora en dos líneas.
Cuando el Amstrad se encuentra con una instrucción PRINT, empieza a escribir en
una nueva línea, a no ser que la instrucción PRINT anterior haya terminado en pun­
to y coma. Esto ocurre también con PRINT TAB y PRINT SPC:

new<ENTER>
auto<ENTER>
10 ?tab(9)"Esto es;"<ENTER>
20 ?tab(17)"el Amstrad."<ENTER>
30 <ESC>

Ejecute el programa y verá que todo el texto queda en la misma línea. Edite la línea
10 para suprimir el punto y coma. Observará que el texto se parte ahora en dos
líneas.
Escriba el siguiente programa con la ayuda de la tecla COPY:

new<ENTER>
auto<ENTER>
10 ?tab(20);"A"<ENTER>
20 ?tab(19);"A A"<ENTER>
30 ?tab(1S);"A";spc(3);"A"<ENTER>
40 ?t ab(17);"A";spc(5);"A"< ENTER >
50 ?tab(16);"AAAAAAAAA"<ENTER>
60 ?t ab(15); "A";spc ( 9 );"A"<ENTER >
70 ?tab(14);"A";spc(11);"A"<ENTER>
80 <ESC>

Ejecute el programa y observe cómo hemos utilizado SPC. Esto es más cómodo que
tener que contar cuidadosamente los espacios para escribir líneas como la siguiente:
24 Programación BASIC con Amstrad

60 PRINT TAB(13);"A A"

La instrucción LOCATE

Utilizando la instrucción LOCATE se puede escribir en cualquier posición de la


pantalla:

newCENTER)
auto<ENTER>
10 mode 1CENTER>
20 ?"Empezamos a escribir en ( 10,12):"CENTER)
30 locate 10,12CENTER>
40 ?"Aqui esta !"CENTER)
50 CESO

La orden LOCATE de la línea 30 desplaza el cursor a la columna 10 de la línea 12


de la pantalla. Al ejecutarse la línea 40, el ordenador queda dispuesto para empezar
a escribir en esa posición.
Ejecute el programa de nuevo, cambiando previamente la línea 10:

10 mode 0CENTER)

El mensaje quedará escrito en la mitad derecha de la pantalla. El modo 0 sólo dis­


pone de 20 columnas, por lo que la décima columna se encuentra en el centro. Si

Figura 4. Control de la posición del cursor.


La programación 25

ejecutamos el programa en modo 2, el mensaje quedará mucho más cerca del borde
izquierdo de la pantalla, puesto que este modo dispone de 80 columnas.
Desde luego, se puede utilizar SPC y TAB para acceder a otras posiciones, pero
sin olvidar que estas instrucciones no permiten retroceder.

Ejercicios

Puede utilizar la tecla COPY para facilitar la programación de los siguientes ejerci­
cios. Antes de abordar un programa nuevo, no olvide escribir new<ENTER> para
borrar el programa anterior.
1. Escriba un programa que dibuje lo siguiente:

***********
* *
* *
***********

2. Programe la realización de este dibujo en modo 1, comenzando en (10, 20):

*****
****
***
**
*

3. Utilizando TAB o SPC, programe el siguiente dibujo:

*****
****
***
**
*
4. Utilice PRINT TAB o PRINT SPC para programar esta representación en panta­
lla (en modo 1, centrada):

Este mensaj e
es para
usuarios de
ftmstrad

Utilización de variables

Escribamos un programa breve que haga que el ordenador escriba un mensaje:


26 Programación BASIC con Amstrad

new<ENTER»
auto<ENTER»
10 T" Hol h y ami go"<ENTER»-
20 ?"Mi nombre es Amstrad "CENTER»-
30 ?"y creo que eres maravi11 oso !"CENTER»
40 CESO

Si ejecutamos el programa, veremos que el ordenador nos escribe el mensaje, como


era de esperar. Sin embargo, no se puede decir que este programa sea muy emocio­
nante. Si volvemos a ejecutarlo, el mensaje que obtenemos es siempre el mismo.
¿No sería interesante que el ordenador se dirigiese a la persona que lo está utilizando
por su propio nombre? Eso ya estaría mucho mejor. Escriba:

5 let nombre$="Mariano"CENTE-R»-

(ponga entre las comillas el nombre que desee). Modifique ahora la línea 10:

10 ?"Hola, amigo nombre®

Liste el programa y ejecútelo. En esta ocasión, el ordenador escribe un mensaje per­


sonalizado. No es que esto sea un gran progreso, pero lo cierto es que la diferencia
entre los dos programas es importante.
La línea 5 dice:

5 let nombre®="Mari ano"

La memoria del Amstrad se compone de miles de “células de memoria” que pode­


mos considerar como una especie de casillero vacío. Cada casilla se puede utilizar
para almacenar información. La línea 5 del programa pide al ordenador que bus­
que un casillero vacío, lo denomine ‘nombreS’ y coloque en su interior la palabra
‘Mariano’.

Figura 5. Cómo se almacena una cadena literal en la memoria.


La programación 27

El signo * = ’ de la línea 5 nos puede inducir a error si entendemos que ‘ = ’ indica


que dos cosas son exactamente iguales. En informática, una línea del estilo de la
5 se debe interpretar de esta forma:
Toma la palabra ‘Mariano’ y almacénala en la dirección de la memoria
en la que hemos puesto la etiqueta ‘nombreS’.
Cada vez que hagamos referencia a nombre$ (como ocurre en la línea 10 del progra­
ma), el ordenador irá a la “casilla” etiquetada con ‘nombreS’ y tomará la palabra
que encuentre allí. Esta palabra será utilizada después en la instrucción print, como
podrá comprobar cuando ejecute el programa.
Si cambia el valor de nombreS modificando la línea 5,
5 let nombre$="Ati1 a el Huno "< ENTERA-

y vuelve a ejecutar el programa, observará que el ordenador ha almacenado ahora


‘Atila el Huno’ en la zona de la memoria etiquetada con nombreS y utiliza este nue­
vo nombre cuando ejecuta la instrucción de la línea 10. De hecho, en la casilla
nombreS se puede almacenar cualquier cosa-, por eso decimos que nombreS es una
variable. Esto quiere decir que su valor varía y depende de lo que nosotros desee­
mos que sea. El signo *$’ con que termina el nombre de la variable indica que
nombreS es una variable literal. Esto quiere decir que lo que se almacena en su inte­
rior es una cadena de caracteres (o sea, una cadena literal), que pueden ser alfabéti­
cos, numéricos o signos de puntuación, o mezcla de estos tipos. Escriba:

5 let nambra$=" 123abc#$%" <ENTER>

y ejecute de nuevo el programa para comprobar que en nombreS se puede almacenar


cualquier cosa.
¿Tenemos que utilizar nombreS necesariamente? Escriba:

5 let OtroNombreCualquierJohn ilcEnro


e"< ENTERA­
IS ?"Hola, amigo ";OtroNombreCualquiera$<ENTER>

y ejecute el programa. Al ordenador no le importa que demos a las variables nom­


bres rebuscados. Sin embargo, conviene que al programar utilicemos nombres de
variables que nos ayuden a recordar cuál es su contenido. Por ejemplo:
1et marcadecoche$="Seat "
let ti tulodelibro="Las uvas de la ira"
let priraer j Ligad or$="Alfredi tu"
let ciudadí-"Sal amanea"

Nombres tales como ‘eso$’ o ‘xyz$’ no nos ayudarán a recordar para qué sirven
cuando revisemos el programa al cabo de unos meses para tratar de corregirlo. No
obstante, hay algunas limitaciones en cuanto a los nombres que podemos dar a las
variables:
28 Programación BASIC con Amstrad

1. No pueden comenzar por un número, aunque sí pueden contener números


en otras posiciones.
2. Sólo podemos usar caracteres alfabéticos o numéricos.
3. El nombre no puede constar de más de 40 caracteres.
4. No se pueden usar palabras clave (reservadas) tales como PR1NT o LET.
Aunque se pueden utilizar indistintamente letras mayúsculas y minúsculas, es
aconsejable utilizar siempre minúsculas. Esto nos permite identificar las variables
con más facilidad cuando listamos el programa, ya que el Amstrad convierte auto­
máticamente a mayúsculas todas las palabras clave de BASIC, pero no los nombres
de las variables.
El LET de la línea 5 del programa es opcional, lo que quiere decir que no es nece­
sario incluirlo en la instrucción. Edite la línea 5 para suprimir el LET y verá que
el ordenador ejecuta el programa igual que antes. Ahora que se ha familiarizado
con LET, siento decirle que no lo volverá a ver en este libro, ya que su omisión nos
ahorra bastantes pulsaciones.
Si tiene dudas sobre la posible validez de un nombre de variable, pruébelo en
modo inmediato para ver cómo reacciona el Amstrad. Escriba:

estomarcha$="Bocadillo de calamares"<ENTER>

y el Amstrad emitirá el mensaje ‘Ready’, lo que indica que el nombre de esta varia­
ble es correcto; pero si escribe:

esano marcha$="10 huevos al plato"<ENTER>

obtendrá un mensaje de error, puesto que el nombre de una variable no puede conte­
ner espacios.
Cuando hemos asignado un valor a una variable, podemos ya utilizarla tantas ve­
ces como deseemos dentro del programa:

new<ENTER>
auto<ENTER>
10 let buenacomida$="helado"<ENTER>
20 let malacomida$="hormigas con chocóla
te "< ENTERR­
ES ?"Asi que le gusta el ";buenacomida$;
", verdad?"CENTERÍ
40 ?"Yo, en cambio, prefiero ";malacomid
a$<ENTER>
50 ?buenacomida$;" es mejor para persona
s"<ENTER>
60 ?"Quisiera ver ";buenacomida$;" de
malacomi dat ÍENTER>
70 <ESC>
La programación 29

¿Qué ocurre si almacenamos una nueva cadena en una de las variables ya existen­
tes? Escriba:

1.5 1 et buenacomi da$""bi zcocho"<ENTER>

y vuelva a ejecutar el programa. Verá que la cadena ‘helado’ se ha perdido al susti­


tuirla por la cadena ‘bizcocho’. La línea 15 pide al ordenador que almacene la pala­
bra ‘bizcocho’ en la casilla ‘buenacomidaS’ de la memoria, la descarta y la sustituye
por ‘bizcocho’.

Ejercicios

1. ¿Cuáles de los siguientes nombres son permisibles como nombres de variables?


UNAPALABRAGRANDES
PresidentedeGobiernoS
15Moncloa$
QuinceMoncloaS
Quince-MoncloaS
A$
t$
$
2. Corrija los errores del siguiente programa:

10 -fecha actual$="15 de julio de 1985"


20 FRINT"Hoy estamos a";-fecha actual $

3. Complete este programa para que al ejecutarlo escriba:


Hola, Sr. Villanueva
O puedo llamarle Marianito?

10 1 et apel 11 doí :::::"i 1 ariuev¿i"


20 let nombre$="Mar-ianito"

4. Seleccione algunas palabras apropiadas que podamos almacenar en cadenas que


pueda utilizar el ordenador para escribir una descripción del sheriff del conda­
do. He aquí un ejemplo en el que las cadenas aparecen en mayúsculas para faci­
litar su identificación:
Llevaba un SOMBRERO NEGRO en la CABEZA y se llamaba MUDD, más
conocido por MUDD EL RAPIDO por su forma de manejar el REVOLVER
y por el número de PERSONAS que había enviado a criar AMAPOLAS.
30 Programación BASIC con Amstrad

La instrucción INPUT

Nuestro programa nos ha servido para presentar las variables, pero no llega a ser
mucho mejor que el programa original. Cada vez que lo ejecutamos, nos sigue dan­
do el mismo mensaje, con el valor que hayamos asignado a nombreS en la línea 5.
Sin embargo, pretendíamos escribir un programa que diese un mensaje personaliza­
do al usuario. Para cumplir ese objetivo necesitamos aprender para qué sirve la ins­
trucción INPUT. Escriba:

new<ENTER>
auto<ENTERO
10 input"Como te llaman tus amigas";notnb
re$<ENTER>
20 ?"Espero que de encuentres bien, ";no
mbre$<ENTER>
30 <ESC>

Observe que no hemos asignado valor a nombreS en ninguna parte del programa.
¿Cómo sabe el ordenador qué tiene que escribir en la línea 20? Si ejecutamos el pro­
grama, el Amstrad escribirá:

Como te llaman tus amigcss?B

Escriba su nombre (sin comillas) y pulse <ENTER>. El ordenador capta su nom­


bre, lo almacena en la variable nombreS y lo utiliza cuando llega a la línea 20. Eje­
cute el programa unas cuantas veces respondiendo con diferentes nombres. Hemos
conseguido un programa más general que dará diferentes mensajes según quién lo
utilice.
La instrucción INPUT permite que el ordenador obtenga información durante la
ejecución del programa. El mensaje entrecomillado de la línea 10 se denomina
prompt (que podríamos traducir por “apuntador” o “inductor”) ya que nos indica
que tenemos que escribir algo en el teclado, e incluso nos recuerda qué información
espera el ordenador. El uso de este apuntador es opcional. También habríamos po­
dido poner simplemente:

10 input nombre!

pero entonces el ordenador nos interrogaría con un frío y poco explícito signo *?’
al ejecutar el programa. Ya hay demasiados programas de ese tipo por todas partes.
Por lo tanto, incluyamos siempre un apuntador en las instrucciones INPUT.
El punto y coma del final del apuntador indica al Amstrad que sí queremos que
escriba el'?’ que él genera automáticamente en las instrucciones INPUT. Si lo sus­
tituimos por una coma en la línea 10, observaremos que el ordenador omite el “?’.
En realidad, esto es sólo cuestión de estilo. Puede ser que usted prefiera una línea
1 más seria, sin signo de interrogación. Escriba:
La programación 31

1 input"Escriba su nombre: ",nombre»<ENTER>


run<ENTER>

y observe la diferencia.
Se puede utilizar una sola instrucción INPUT para captar varias cadenas literales
al mismo tiempo:

new<ENTER>
autc<ENTER>
10 input"Escriba su nombre y edad, separ
ados por una coma: ", nombre»,edad$<ENTER>
20 ?"Vamos, "jnombre»;". ";"Nc aparentas
tener ";edad»;" aftas."<ENTER>
30 CESO

El Amstrad exige que los valores que introduzcamos queden separados por comas.
De no hacerlo así, el ordenador emite el mensaje ‘Redo from start’ (repetir desde
el principio). También se provoca el mismo mensaje si sólo se introduce una cadena
cuando el ordenador espera dos, o si se introducen cuatro en lugar de tres. Esta
es otra razón que hace aconsejable la inclusión del “apuntador” en las instrucciones
INPUT, ya que nos recuerda cuántas entradas hacen falta y en qué consisten.

Ejercicios

1. Quizás haya recibido usted alguna vez una de esas temibles cartas “personaliza­
das” escritas por ordenador, en las que se le ofrece la oportunidad de ganar un
premio en un concurso. Normalmente, se le invita al mismo tiempo a adquirir
un libro muy útil, como puede ser el “Atlas Universal de los Gusanos”. Escriba
un programa que confeccione una carta de este tipo, después de captar por el te­
clado datos tales como nombre, dirección, fecha, etc. En el ejemplo siguiente,
los datos captados por el teclado (con INPUT) son los que aparecen en mayúscu­
las.
Empresa de Libros Encuadernados en Piel
C/. Astucia, 31
66175 Guardalapala

25 de JULIO de 1984

Estimado SR. PÉREZ:

Estaba el otro día paseando junto al número 20 de la CALLE ARNUL­


FO, cuando pensé en usted. El SR. PÉREZ es la persona más inteligente del
barrio de los REYES GODOS, me dije. Estoy seguro de que tanto él como
cualquier otra persona de la CALLE ARNULFO reconocerá el interés de in­
vertir en “Inversiones Guardalapala” por sólo 20.000 pesetas, cuando ade­
32 Programación BASIC con Amstrad

más el SR. PÉREZ puede ganar también un viaje a la Empresa de Libros En­
cuadernados en Piel, con todos los gastos pagados. No se demore, SR. PÉ­
REZ, sólo tiene siete días desde el 25 DE JULIO DE 1984 para beneficiarse
de esta oportunidad única.
Atentamente,
Un buen amigo

2. Escriba un programa que escriba un “poema” después de captar por el teclado


la terminación de tres de sus líneas. Por si le sirve de ayuda, le ofrecemos un
ejemplo. Los datos captados con instrucciones INPUT son los que aquí figuran
en mayúsculas:
Erase una vez un tal MANOLO
al que le gustaba COMER COMO A EL SOLO
Un día se fue de su casa
y se dedicó a ESPERAR A VER QUE PASA

3. Escriba un programa que le pregunte por su propio nombre y dirección y que


escriba una tarjeta de visita como la siguiente:

NOMBRE: Mariano Villanueva


DIRECCION: Calle Arnul-fo, 20
Guar'dal apal a

La instrucción LINE INPUT

Seguro que este último ejercicio le ha dado problemas si en respuesta a una instruc­
ción INPUT ha escrito una cadena que contuviese una coma. Hay ocasiones en que
sucede esto. Por ejemplo, puede ocurrir que alguien desee escribir su nombre como
‘Juan Rodríguez, S.J.’. En tal caso no sirve la instrucción INPUT normal, pues
el Amstrad emitiría el mensaje de error ‘Redo from start’ al incluir una coma en
la respuesta. Escriba:

newCENTERz
auto<ENTER>
10 input"Escriba su profesión: ",profesi
□n$<ENTER>
10 CESO-

AI ejecutar este miniprograma observará que si respondemos con ‘abogado, nota­


rio’ obtenemos el mensaje ‘Redo from start’. El ordenador se encuentra la coma
y cree que la respuesta es ‘abogado’. Como usted ha seguido escribiendo, “piensa”
que su intención es introducir una segunda cadena y, naturalmente, protesta.
La programación 33

En previsión de accidentes de este tipo, debemos utilizar la instrucción LINE IN-


PUT, que acepta una línea completa de texto, incluidas las comas. Modifique la
línea 10 de la siguiente forma:

10 line input"Escriba su profesión: ",pr


of esi on$<ENTER>

y comprobará que ahora puede escribir cualquier respuesta, que será aceptada como
entrada válida. Con cada LINE INPUT sólo se puede captar una cadena, porque
ahora el ordenador ya no tiene forma de saber dónde termina una respuesta y co­
mienza la siguiente. Otra cosa que hay que recordar LINE INPUT no genera auto­
máticamente el signo *?’ a que nos tenía acostumbrado INPUT. Si el signo de inte­
rrogación es necesario, tendrá que incluirlo explícitamente en la cadena apuntadora.

Variables numéricas

Deberemos utilizar variables literales siempre que queramos almacenar cadenas de


caracteres alfabéticos o una mezcla de alfabéticos y numéricos. Parece lógico que
podamos almacenar también números y, en efecto, podemos. Pero la forma de al­
macenarlos dependerá de lo que queramos hacer con ellos. Escriba:

new<ENTER>
auto<ENTER>
10 primernumero$==" 123" CENTER>
20 segundonumero$="345"<ENTER>
30 ?"E1 primer numero es ";primernumero$<ENTER>
40 ?"E1 segundo numero es ";segundonumer
o»<ENTER>
50 <ESC> .

Ejecute el programa. Funciona bien, ¿verdad? Si todo lo que pretendemos hacer


con los números es escribirlos, no hay inconveniente en utilizar variables literales
para almacenar sus valores. Pero veamos qué ocurre cuando intentamos realizar
cálculos aritméticos. Modifique la línea 50:

50 ?"A1 multiplicarlos obtenemos"; primer


numer o$*segun don umer o$< ENTER >

Ejecute el programa. El Amstrad emite el siguiente mensaje:

Type mismatch in 50

(incongruencia de tipos en 50). Un nuevo mensaje de error. Lo que indica es que


el Amstrad no puede hacer cálculos aritméticos con cadenas literales. En realidad,
esto es muy conveniente. Después de todo, primernumero$ podía muy bien haber
34 Programación BASIC con Amstrad

sido “martillos” y segundonumeroS podría haber sido “El océano Atlántico” y,


claro, la multiplicación habría sido imposible. Antes de realizar cálculos aritméti­
cos con variables, el Amstrad tiene que asegurarse de que está tratando con núme­
ros. Por consiguiente, si tenemos números con los que hemos de realizar cálculos,
éstos deberán ser almacenados en variables numéricas, no en variables literales.
Las variables numéricas son muy parecidas a las literales. La diferencia más evi­
dente para nosotros es que carecen del signo y que cuando les asignamos valores
no utilizamos las comillas. Por ejemplo:
longitud=27
altura=7.6
distancia=38.45
gasolinagastada=5.5
temperatura = -10.5
son todos nombres de variables perfectamente razonables y aceptables. También
son aceptables, aunque no muy útiles en un programa, los siguientes:
y33=5.6
A=75
Las variables numéricas pueden contener números enteros (sin decimales), tales co­
mo 27, o números decimales, tales como -10.5, pero no pueden contener cadenas
literales. Compruébelo.
Si lista el programa original, verá que con algunos cambios sencillos podrá hacer­
lo funcionar. Sólo tiene que editar algunas líneas para conseguir que los números
se almacenen en variables numéricas, y no como cadenas. Edite el programa para
que tome la siguiente forma:

10 primernumero=123
20 segundonumerc=345
30 ?"E1 primer numero es";primernumero
40 ?"E1 segundo numero es";segundonumero
30 ?"A1 multiplicarlos obtenemos: "¡prim
ernumero*segundonumero

Ejecute el programa. El efecto de la última línea debería ser el siguiente:

Al muítip1 i car 1 os obtenemos 42435

Pero añadamos algunas otras líneas. Escriba lo siguiente:

auto 60<ENTER>
60 ?"A1 sumarlos obtenemos: "jprimernume
ro+segundonumero<ENTER>
70 ?"A1 dividirlos obtenemos: ";primernu
mero/segundonumero<ENTER>
80 ?"A1 restarlos obtenemos: ";primernum
La programación 35

er o --segúndonumeroi ENTER >


90 CESO
run<ENTER>

En las líneas que van de la 50 a la 80, el Amstrad toma los números de las “casillas”
de la memoria y los utiliza para realizar los cálculos aritméticos. Podemos cambiar
las líneas 10 y 20 para que el programa capte por el teclado (con INPUT) los valores
de ‘primernumero’ y ‘segundonumero’:

10 input"Cual es el primer numero"; prime


r n umer o < E NT E R >
20 input"Cual es el segundo numero";segu
n d o n u me r a < ENT ER >

El Amstrad efectuará ahora los cálculos con los números que el usuario introduzca.

Ejercicios

1. Usted va a visitar Rurislovaquia, donde la moneda es el ruri, que equivale a 305.4


pesetas. Escriba un programa para convertir pesetas en ruris después de pregun­
tar al usuario cuántas pesetas quiere cambiar.
2. Escriba un programa que capte por el teclado el largo y el ancho de una alfombra
y luego calcule y escriba su superficie.

Aritmética con variables

Aunque hasta ahora sólo hemos explicado unas cuantas instrucciones de BASIC,
la utilización de las variables ampliará considerablemente sus horizontes. Por ejem­
plo, con sólo 3 líneas, usted puede escribir un programa para convertir kilómetros
en millas:

newt ENTER'1
aut□<ENTER?
10 unami 11a=l.6093<ENTER>
20 inpuf'Cual es la distancia en kilomet
ros"; di stanci aenki1 ometrosiENTER>
30 ?"Eso equivale a"; distanciaenki1ometr
□s/unamiIla;"millas"<ENTER>
40 <ESC>

Pero ampliemos este programa. Su coche puede recorrer unas 30 millas con un ga­
lón de gasolina, y queremos saber cuántos galones vamos a necesitar para recorrer
una determinada distancia, dada en kilómetros. En la línea 30 se calcula el número
de millas. En vez de realizar este cálculo de nuevo en otra línea para después dividir
36 Programación BASIC con Amstrad

por 30 para averiguar cuántos galones necesitamos, es mucho más fácil conservar
el resultado de la línea 30 almacenándolo en otra variable. Así pues, añada estas
líneas a su programa:

10 unaroi 11a=1.6093
20 INPUT"Cual es la distancia en kilomet
ros";di stanci aenki 1 ometros
25 di stanci aenmi 11 as==di stanci aenki 1 ometr
os/unami 11 a
30 F'RINT"Eso equivale a";distanciaenki1 o
metros/unamilia;"mili as"
50 F'RINT"F'ara recorrerlas se necesitan";
di stanci aenmi 11 as/30; "gal oríes de gasolin
a. "

La línea 25 toma el resultado de dividir la distancia en kilómetros por 1.6093 y lo


almacena en la variable ‘distanciaenmillas’, para luego volver a utilizarlo en la línea
50 para averiguar cuántos galones de gasolina necesitamos.
El precio de la gasolina es de £1.80 por galón, y usted desea saber cuánto costará
el viaje. Vamos a tratar de generalizar este programa ahora, ya que quizás compre
usted un nuevo coche dentro de poco y su consumo sea distinto. Además, es proba­
ble que el precio de la gasolina suba también. Tratemos todos estos números como
variables:

10 unami 11a=1.6093
12 mi 11asporgalon=30
14 preciogasoli na-1.8
20 INF’UT"Cual es la distancia en kilomet
ros";di stanci aenki1 ometros
25 dista n c i a e n'm 1 lias- tí i s t a n c i a e n k i 1 o m e t r
os/unamilia
30 F'RINT"Eso equivale a" ; di stanci aenki 1 o
metros/unamilia;"millas."
40 galonesparavi aj e=di stanci aenmi11 as/mi
11 asporgal o n
50 F'RINT"F'ara recorrerlas se necesitan";
galcnesparaviaje;"galones de gasolina,"
60 costovi aj e=galonesparavi aje*prec i ogas
o1 i na
70 F’RINT"que cuestan";costoviaje;" 1 ibras

En las líneas 25, 40 y 60 utilizamos variables de valores conocidos para calcular los
valores de nuevas variables, que son a su vez utilizadas en cálculos posteriores. Si
usted cambia de coche o sube el precio de la gasolina, lo único que tiene que hacer
es modificar las líneas 12 y 14 para asignar los nuevos valores y podrá seguir utili
La programación 37

zando el programa. ¿No será ésta una forma complicada de realizar esta tarea? Lo
ideal sería disponer de un programa que nos preguntase cuántas millas por galón
hace el coche y cuánto cuesta un galón de gasolina; de esa forma el programa podría
ser utilizado por alguien que ni siquiera sepa qué es eso de “editar líneas”. Cambie,
pues, las líneas 12 y 14 para que el usuario pueda introducir los valores por el tecla­
do, como ocurre en la línea 20.

Ejercicios

1. En un programa anterior, el ordenador captaba los datos relativos al ancho y lar­


go de una alfombra y calculaba el área. Amplíe el programa para que halle el
precio de la alfombra cuando introduzcamos el coste del metro cuadrado.
2. El propietario de un restaurante de comida rápida acaba de comprar un ordena­
dor y desea poder teclear el precio de los artículos y que el ordenador calcule el
12 por 100 de IVA. Además, debe sumar el IVA al precio para dar el importe
total.
3. El Club del Libro del Mes envía una carta mensual a sus socios en los siguientes
términos:
Nombre del socio: Mariano Pérez
Número de socio: 12345678
Saldo anterior 1250 pesetas
El libro de este mes vale +595
Total 1845
Su pago del mes pasado -500
Saldo a nuestro favor 1345 pesetas
Escriba un programa que capte por el teclado el nombre del socio, su núme­
ro, la cantidad que adeuda, el precio del libro del mes actual y el último pa­
go mensual efectuado por el socio. El programa deberá escribir el detalle de
los movimientos de la cuenta, tal como se indica más arriba.

¿Es 2=2+1?

Este extraño título sólo pretende recordarle que el signo * = ’ no siempre significa
“igual a” en informática. Escriba lo siguiente:

r.e*<ENTER>

.n n Limero; ", numero< ENTER >


20 nsera=numero+KENTER;
30 ?"E1 numero de ha convertido en";nume
38 Programación BASIC con Amstrad

Ejecute el programa y teclee un número cualquiera. Observará que el valor que apa­
rece en la pantalla al final del programa es el número que usted introdujo más 1.
¿Cómo ha ocurrido esto?
Puede que parezca que la línea 20 carece de sentido, y así sería si el signo * = ’ sig­
nificase “igual a”. Revisemos el programa y veamos lo que le ocurre al número
que usted introduce. En la línea 10, el ordenador toma el valor que ha introducido
y lo almacena en una “casilla” de la memoria, a la que pone la etiqueta ‘numero’:

Figura 6. Así almacena el ordenador en su memoria el valor 6 que hemos introducido.

En la línea 20 lo que hacemos es decirle al ordenador:


Saca el valor que hay en la casilla ‘numero’, súmale 1 y vuelve a
colocar el resultado en la misma casilla.

Figura 7. número=número +1. Así es cómo lo interpreta el Amstrad.


La programación 39

Análogamente ocurre en el ejemplo siguiente:

newíENTERJ
autc<ENTER>
10 ir.put"Cuanto tenias ahorrado ayer"; ah
orrosC5NTER>
20 input"Cuanto has gastado hoy";gastos<ENTER>
3E ahcrr«s=ahorros "-gastos
40 ?”Tus ahorros son ahora";ahorros<ENTER>
50 CESO

Supongamos que sus ahorros eran de 60 pesetas y que usted ha gastado 20:

Figura 9. Ahorros y gastos.


40 Programación BASIC con Amstrad

La línea 30 hace que el ordenador tome el valor de los ‘ahorros’ (60) y le reste
los ‘gastos’ (20); el resultado es 40, que vuelve a quedar almacenado en ‘ahorros’.
(Ver figura 9.)
Éste es el valor que escribe la línea 40. El valor almacenado en ‘gastos’ no se ve
afectado.
Esta capacidad que poseen las variables, nos proporciona la forma de contar fá­
cilmente hasta cierto valor:

new<ENTER>
auto<ENTER>
10 input"Introduzca un valor inicial:
valor<ENTER>
20 valor=valor+l<ENTER>
30 ?"ñhora es";valor<ENTER>
40 valor=valor+l<ENTER>
50 ?"Ahora es" ; val.or<ENTER>
60 valor=valor+l<ENTER>
70 ?"Ahora es";valor<ENTER>
80 <ESC>

¿No le parece monótona esta repetición de líneas? Hay una forma más sencilla
y corta de escribir este programa, pero tendremos que esperar hasta que hayamos
avanzado un poco más para conocerla.

Ejercicios

1. El dueño del restaurante utiliza ahora su ordenador para sumar las facturas. Él
introduce los precios de cuatro artículos y el ordenador los suma y escribe el to­
tal. También calcula los impuestos.
La factura queda como sigue:
Artículo 1 95 pesetas
Artículo 2 120
Artículo 3 35
Artículo 4 50
Total 300
IVA 36
Importe total 336 pesetas
Este programa adolece de algunos defectos. Si en la factura sólo tenemos que in­
cluir dos artículos, tendremos que introducir 0 como precio de los restantes, y si hay
más de cuatro, tendremos que hacer otra factura. A veces los impuestos son canti­
dades con decimales, tales como 0.48, y entonces el importe total contiene fraccio­
nes de peseta. Tanto el propietario del restaurante como usted tienen aún bastante
que aprender.
La programación 41

Cómo grabar y cargar los programas

Quizás piense usted que ya es capaz de escribir programas que vale la pena grabar
en cinta para poder utilizarlos en el futuro. Si es así, consulte la página F1.13 de
la Guía del Usuario, donde se explica cómo hacerlo. Las páginas F1.10 a F1.12 le
indican cómo puede volver a cargar el programa en la memoria desde la cinta.
Es aconsejable hacer constar claramente en la etiqueta de la cinta el nombre del
programa o programas que contiene, ya que de otro modo acabará con un montón
de cintas y nunca sabrá cuál de ellas contiene su última obra maestra, ni con qué
título la había grabado.

¡Adelante con la programación!

Estos dos primeros capítulos sólo han servido para que el lector se familiarizase un
poco con la informática. Hemos hablado de la RAM y la ROM, de las variables,
que son fundamentales para poder manejar los datos, y hemos presentado algunas
de las palabras clave, PRINT, LET e INPUT, utilizándolas en pequeños programas.
En los capítulos que siguen aceleraremos el ritmo, así que no intente leerse todo
el libro en un día. No pase nada por alto, ya que los programas de algunos capítulos
utilizan instrucciones de BASIC que se explican en los anteriores.
A partir de ahora ya no le recordaremos que debe pulsar <ENTER> cada vez que
termine de escribir una línea de programa o una orden directa. Además, le dejare­
mos en libertad para utilizar AUTO o RENUM, así como las demás ayudas de edi­
ción del Amstrad, como usted estime oportuno.
Por último, le recordaremos que existen diferentes formas de escribir los progra­
mas para que realicen una misma tarea concreta. Los ejercicios propuestos no tie­
nen una solución única, sino varias; por eso no hemos creído conveniente incluir un
apéndice con la lista de soluciones. Si su programa funciona, la solución es correc­
ta. Más adelante veremos cómo podemos simplificar la elaboración de programas
largos mediante sistemas de planificación. Pero, por el momento, utilice su propia
intuición y páselo bien.
3

Dibujos

LA PANTALLA GRÁFICA

En el capítulo 2 vimos que el Amstrad puede situar el texto en cualquier lugar de


la pantalla utilizando las coordenadas de texto. El ordenador también puede dibu­
jar líneas, pero tenemos que indicarle dónde comienzan y acaban éstas. La pantalla
gráfica se divide en 640 puntos en sentido horizontal y 400 en vertical.
Podemos identificar la posición de cualquier punto de la pantalla especificando
sus coordenadas.
La posición del punto de la figura es (200, 300). El primer número es la coordena­
da X del punto (posición en el eje horizontal); el segundo es la coordenada Y (posi­
ción en el eje vertical).
Observe que las coordenadas gráficas se miden a partir del extremo inferior iz­
quierdo de la pantalla, y que el punto situado en esa posición tiene las coordenadas

399

300

200 639

Figura 10. El punto (200, 300) en la pantalla gráfica.

42
Dibujos 43

(0,0). Esto puede prestarse a confusión, ya que las coordenadas de texto funcionan
de modo completamente diferente: se miden a partir del extremo superior izquierdo,
el cual tiene las coordenadas (1,1). Observe también que la numeración de los pun­
tos empieza por 0, y que por lo tanto el extremo superior derecho de la pantalla grá­
fica tiene las coordenadas (639,399), no las coordenadas (640,400) como cabría
pensar. Pruebe el siguiente programa:

10 MODE 1
20 MOVE 124,156
30 DRAW 300,300
40 DRAW 200,400
50 DRAW 124,156

Cuando usamos las órdenes de gráficos del Amstrad, utilizamos el cursor gráfico
para trazar líneas sobre la pantalla. Normalmente, el cursor gráfico y el de texto
permanecen juntos, pero tan pronto como ejecutamos una orden gráfica, entra en
acción el cursor invisible de gráficos.
La orden MOVE de la línea 20 hace que el cursor de gráficos se desplace invisible­
mente al punto (124, 156). La orden DRAW hace que el cursor se desplace desde
la posición (124,156) hasta el punto de coordenadas (300, 300) trazando una recta
entre ambos puntos. Las restantes ordenes DRAW de las líneas 40 y 50 trazan los
otros dos lados del triángulo.
En resumen, MOVE x,y hace que el cursor de gráficos se desplace hasta el punto
x, y sin dibujar a su paso, mientras que DRAW x,y dibuja una recta desde el último
punto visitado (como resultado de una orden MOVE o DRAW) hasta punto x, y.

Los diferentes modos de pantalla

Aunque la pantalla de gráficos conste de 640 puntos horizontales y 400 verticales,


lo cierto es que el Amstrad no puede dintinguirlos todos ellos. En el capítulo 1 vi­
mos que hay tres modos de pantalla, y que en cada modo el tamaño de los caracteres
es diferente. Sin embargo, la pantalla gráfica es la misma para los tres modos, aun­
que el Amstrad distingue mejor unos puntos de otros según el modo que se utilice.
Ejecute de nuevo el programa anterior, después de haber cambiado la línea 10 como
sigue:

10 MODE 0

Observará que el dibujo sigue teniendo la misma forma, pero con las líneas más
gruesas. Pruebe ahora:

10 MODE 2

Ahora las líneas se han hecho muy finas. El modo 2 es el denominado modo de
alta resolución, ya que en él el ordenador puede distinguir 640 puntos en horizontal
44 Programación BASIC con Amstrad

y 200 en vertical; a esto se debe el que cuando usamos la instrucción DRAW las rec­
tas resultantes sean tan finas. En modo 2, el Amstrad no puede establecer diferen­
cias entre puntos que se encuentren muy juntos en el plano vertical. Por ejemplo,
no puede distinguir entre el punto (10,10) y el (10, 11). Los tres modos, 0, 1 y 2,
dan la misma resolución vertical, pero la resolución horizontal del 2 es muy supe­
rior. Escriba:

10 MODE 1

y vuelva a ejecutar el programa. El modo 1 es el de resolución media-, en este modo


el Amstrad sólo puede distinguir 320 puntos en horizontal. Esto quiere decir que,
por ejemplo, los puntos (200, 300), (200, 301), (201,300) y (201, 301) son tratados
como si fuesen uno solo. Escriba ahora:

10 MODE 0

y ejecute el programa por tercera vez. El modo 0 es el de baja resolución y sólo


puede discriminar 160 puntos en el eje horizontal.
Quizá se pregunte usted por qué querríamos utilizar un modo de pantalla que pro­
duce dibujos tan toscos, cuando se puede usar el modo 2 de alta resolución. La ra­
zón es la siguiente: aunque en modo 0 la resolución sea tan baja, puede visualizar
hasta 16 colores diferentes al mismo tiempo.
Esto no es posible con los modos 1 y 2.

Número de colores
Resolución gráfica visualizadles
simultáneamente

Modo 0 160x200 16
Modo 1 320x200 4
Modo 2 640x200 2

Figura 11. Grados de resolución y número de colores disponibles en los diversos modos.

No olvidemos que la memoria del ordenador tiene sus límites. En la RAM sólo
se puede almacenar cierta cantidad de información acerca de la pantalla. En infor­
mática todo tiene un precio. Podemos utilizar la RAM para almacenar detalles de
muchos puntos en dos colores, menos detalles en 4 colores y muchos menos en 16
colores. El Amstrad nos permite elegir lo que más convenga en cada aplicación
concreta.
Dibujos 45

Ejercicios

1. Escriba un pequeño programa que dibuje un rectángulo utilizando las instruccio­


nes MOVE y DRAW.
2. Dibuje la cabeza de un robot utilizando las instrucciones MOVE y DRAW:

Figura 12. La cabeza de un robot.

3. Escriba un programa que dibuje los siguientes triángulos:

Figura 13. Triángulos.


46 Programación BASIC con Amstrad

La instrucción PLOT

El Amstrad también puede representar puntos aislados en la pantalla, aunque en


modo 2 un punto solo es difícil de ver. El siguiente programa dibuja 6 puntos
diferentes:

10 MODE 0
20 PLOT 160,200
30 PLOT 320,200
40 PLOT 324,200
50 PLOT 328,200
60 PLOT 332,200
70 PLOT 480,200

En modo 0 la resolución es tan baja, que los cuatro puntos dibujados por las lí­
neas 30 a 60 se funden para formar un segmento de recta. En modo 1 se pueden
distinguir todos los puntos, mientras que en modo 2 los puntos son tan finos que
quizás no pueda usted ni verlos.
PLOT funciona del mismo modo que MOVE y DRAW. Tiene que ir seguido de
las coordenadas X e Y de los puntos que deseamos representar. En realidad, cada
“punto” se compone de cierto número de puntos de luz, porque ni siquiera el modo
2 es lo suficientemente preciso como para distinguir todos los puntos físicos de la
pantalla. El grupo de puntos más pequeño que se puede identificar en la pantalla
en los diferentes modos es lo que se denomina un pixel.

Figura 14. Tamaños de los pixels en los diversos modos de pantalla.


Dibujos 47

Variables y programas gráficos

El siguiente programa dibuja el contorno de una casa, incluido el techo:

10 MODE 1
20 REM dibuja un rectángulo que es la fachada de
la casa
30 MOVE 120,100
40 DRAW 500,100
50 DRAW 500,300
60 DRAW 120,300
70 DRAW 120,100
80 MOVE 120,300
90 DRAW 185,380
100 DRAW 435,380
110 DRAW 500,300

Este programa contiene una instrucción nueva, REM, abreviatura de REMmark,


que en inglés significa “nota” u “observación”. Permite hacer anotaciones que
ayudan a seguir el hilo de los programas. Como nuestros programas se van hacien­
do cada vez más largos, las incluiremos para explicar sus diferentes partes. Cuando
el Amstrad se encuentra una instrucción REM, ignora absolutamente todo el resto
de la línea. Esta instrucción no sirve más que para facilitar la tarea del progra­
mador.
Por otra parte, los programas largos presentan otro problema ya que al listarlos
no caben enteros en la pantalla. No obstante, podemos listar cualquier parte de un
programa tecleando, por ejemplo,

list 10-30

Esta orden lista las líneas comprendidas entre la 10 y la 30, ambas inclusive.
Podemos hacer los programas más interesantes utilizando variables, cuyos valores
se pueden cambiar fácilmente:

10 MODE 1
20 REM coordenadas de la fachada
30 casaizquierda=120
40 casaabajo=100
50 casaderecha=500
60 casaarriba=300
70 REM dibujar la fachada
80 MOVE casaizquierda,casaabajo
90 DRAW casaderecha,casaabajo
100 DRAW casaderecha,casaarriba
110 DRAW casaizquierda,casaarriba
120 DRAW casaizquierda,casaabajo
48 Programación BASIC con Amstrad

130 REM coordenadas del tejado


140 tejadoizquierda=l85
150 tejadoarriba=380
160 tejadoderecha=435
170 REM dibujar el tejado
180 MOVE casaizquierda,casaarriba
190 DRAW tejadoizquierda,tejadoarriba
200 DRAW tejadoderecha,tejadoarriba
210 DRAW casaderecha,casaarriba

Observe que, puesto que muchos pares de coordenadas se utilizan dos veces, no
necesitamos tantas variables como en principio sería de temer. Ahora podemes re­
ducir la altura de la casa sin más que cambiar la línea 60 para darle una coordenada
Y menor; por ejemplo, 200. O bien podemos subir el tejado modificando la línea
50. Esto nos demuestra la gran potencia e interés que tienen las variables. Si hubié­

semos dibujado la casa utilizando números concretos, habríamos tenido que cam­
biar muchas líneas para probar las mismas modificaciones. ¿Cómo podemos estre­
char la casa? ¿Por qué tenemos que cambiar dos variables en vez de una? ¿Qué
hará el Amstrad si le damos una coordenada demasiado grande, como podría ser
500 en la línea 150?
Dibujos 49

Cuando trabajamos con gráficos, hay muchas formas de producir el mismo efec­
to. Vale la pena que dediquemos algún tiempo a pensar el dibujo que queremos ob­
tener, pues podemos acortar el programa considerablemente si pasamos por las es­
quinas o ángulos del dibujo en el orden correcto. La figura 15 muestra el orden en
que se ha dibujado la casa.

Ejercicios

1. El programa con que hemos dibujado la casa emplea 9 instrucciones MOVE y


DRAW. ¿Podría acortarlo usted a 8 trazando las líneas en un orden más eficaz?
2. Escriba un programa que realice el siguiente dibujo:

Figura 16. Ventana.

La instrucción INPUT en los gráficos

La utilización de la instrucción INPUT nos causa problemas, como podrá ver si bo­
rra las líneas 30 a 60 y las sustituye por:

30 INPUT "Coordenada x del lado izquierdo ";casa


i z qui erda
40 INPUT "Coordenada x del lado derecho "jcasade
recha
50 INPUT "Coordenada y del suelo "¡casaabajo
60 INPUT "Coordenada y de la base del tejado ";c
asaarri ba
50 Programación BASIC con Amstrad

Los apuntadores y los valores tecleados estropean el dibujo. Para evitar que esto
ocurra, podemos pedir al Amstrad que dedique a los textos sólo una parte de la pan­
talla. Esto se logra fácilmente con la instrucción WINDOW:

10 MODE 1
20 REM coordenadas de la -fachada
25 WINDOW 1,40,20,25
30 INF'UT "Coordenada x del lado izquierdo ";casa
izquierda
40 INF'UT "Coordenada x del lado derecho "jcasade
recha
50 INF’UT "Coordenada y del suelo "jcasaabajo
60 INF'UT "Coordenada y de la base del tejado ";c
asaarr i ba
70 REM dibujar la -fachada
80 MOVE casaizquierda,casaabajo
90 DRAW casaderecha,casaabajo
100 DRAW casaderecha,casaarriba
110 DRAW casaizquierda,casaarriba
120 DRAW casaizquierda,casaabajo
130 REM coordenadas del tejado
140 tejadoizquierda=185
150 tejadoarriba=380
160 tejadoderecha=435
170 REM dibujar el tejado
180 MOVE casaizquierda,casaarriba
190 DRAW tejadoizquierda,tejadoarriba
200 DRAW tejadoderecha,tejadoarriba
210 DRAW casaderecha,casaarriba

Podemos elegir la posición y tamaño de la ventana a la que relegamos el texto;


para ello hemos de especificar los números de columna y de fila de sus cuatro bordes
en el siguiente orden: columna izquierda, columna derecha, fila superior, fila infe­
rior. Como estamos definiendo una ventana de texto, tendremos que utilizar coor­
denadas de texto para describirla.
La ventana continúa activa aunque haya terminado el programa, como se puede
comprobar listándolo. Para que todo vuelva a la normalidad, ejecute una orden
MODE. Si lo desea, también puede completar el programa cambiando las líneas
140 a 160 de forma que las coordenadas del tejado se introduzcan también por el
teclado.
También podríamos poner la ventana en la parte superior de la pantalla:

WINDOW 1,40,1

Trate de ajustar la ventana para que quede a la derecha del dibujo.


Quizá se haya dado cuenta de que si el tamaño de la ventana no es el adecuado,
Dibujos 51

Figura 17. La zona sombreada representa la ventana de texto que se define


con WINDOW 1,40,20,25.

el texto puede ser difícil de seguir. Para evitar problemas, vale la pena dedicar algún
tiempo a planificar qué parte de la pantalla vamos a utilizar para texto y qué parte
para gráficos.
Observe que al establecer una ventana de texto no afectamos en nada a la pantalla
gráfica. Las líneas que dibujemos pueden superponerse al texto si la ventana de tex­
to no está en el lugar correcto; por ejemplo, si la hemos puesto en el centro de la
pantalla.

Ejercicios

1. Escriba un programa que capte tres pares de coordenadas y dibuje con ellos un
triángulo.
2. Escriba un programa que capte cuatro pares de coordenadas y dibuje con ellos
una flecha.

UN TOQUE DE COLOR

Al conectarlo, el Amstrad selecciona automáticamente el color amarillo para el tex­


to y los gráficos y el azul para el fondo. El total de colores diferentes es de 27, aun­
que algunos de ellos no son fáciles de distinguir (en particular, por supuesto, cuando
se está utilizando el ordenador con un monitor monocromático). Cada color se
identifica por un número, denominado número de INK (tinta). Véase la figura 18.
52 Programación BASIC con Amstrad

Número de tinta Color

0 Negro
1 Azul
2 Azul intenso
3 Rojo
4 Magenta (rojo + azul)
5 Malva
6 Rojo intenso
7 Morado
8 Magenta intenso
9 Verde
10 Cyan
11 Azul celeste
12 Amarillo
13 Blanco
14 Azul pastel
15 Anaranjado
16 Rosado
17 Magenta pastel
18 Verde intenso
19 Verde marino
20 Cyan intenso
21 Verde lima
22 Verde pastel
23 Cyan pastel
24 Amarillo intenso (dorado)
25 Amarillo pastel
26 Blanco intenso

Figura 18. Los 27 colores de tinta que se pueden utilizar en el Amstrad.

Al llegar a este punto, conviene advertir, por si el lector no lo hubiera observado,


que el ordenador no utiliza toda la pantalla al escribir o al dibujar gráficos. El Ams­
trad trabaja en un gran rectángulo, alrededor del cual queda una zona que no puede
utilizar: el borde. Véase la figura 19.
Aunque el Amstrad no utiliza este borde, el usuario puede controlar su color. El
ordenador tiene que dedicar buena parte de su memoria a almacenar la información
sobre el contenido de la pantalla (qué letras hay en ella, en qué posiciones, forma
y color de las líneas, etc). Aunque no lo parezca, la imagen se está actualizando
continuamente; de hecho, el Amstrad la redibuja 50 veces por segundo, consultando
cada vez la zona de memoria dedicada a la pantalla.
El borde es otra cosa. Como el ordenador no lo utiliza para dibujar ni escribir,
le basta con controlar su color. Éste es el único dato que el ordenador necesita para
redibujar el borde.
Debido a esta diferencia, el borde recibe un tratamiento distinto en lo que a colo-
Dibujos 53

res respecta. Al borde se le puede asignar cualquier color en cualquier modo, sin
restricción alguna. En modo 2 sólo se pueden visualizar 2 colores al mismo tiempo
dentro del rectángulo principal de la pantalla, pero en cambio el borde puede tener
cualquier color que deseemos. Escriba:

MODE 2
BORDER 0

Si consulta la figura 18, verá que el 0 es el número de tinta del color negro. Con
la orden BORDER 0 estamos haciendo que el Amstrad que exhiba un borde negro.
Dé diferentes colores al borde. Puede utilizar cualquier número del 0 al 26, es decir,
27 en total. Por ejemplo, BORDER 26 establece un borde de color blanco.
En los modos 0 y 1 el color del borde se elige de la misma manera. Los cambios
de modo de pantalla no afectan al color del borde. Al encender el ordenador se es­
tablece automáticamente el color 1 (azul). Usted puede incluir una orden BORDER
en cualquiera de los programas que hemos escrito hasta ahora. No afectará al fun­
cionamiento del programa, sino sólo a la estética de la pantalla.

Los colores de PEN y PAPER

Como era de esperar, también podemos modificar los colores con los que se forma
el rectángulo principal de la pantalla. Aquí es donde se aprecian las limitaciones
impuestas por la RAM, relativas el número de colores que se pueden visualizar si­
multáneamente en función del grado de resolución.
Para cambiar el color que el Amstrad utiliza para “escribir” necesitamos una or­
den PEN (pluma). Escriba:
54 Programación BASIC con Amstrad

MODE 0
PEN 4

De la lista de la figura 18 el lector podría esperar que esta orden produjese caracte­
res de color magenta, pero ya hemos advertido que los colores de la pantalla no se
controlan de la misma manera que los del borde. Con PEN 4 no se seleccniona el
color número 4, sino la pluma número 4. Podemos imaginar que el Amstrad traba­
ja con varias plumas, que podemos cargar en diferentes tinteros. La orden PEN
selecciona una de las plumas, mientras que cada orden INK carga una pluma en un
tintero especificado. En la figura 20 se da una lista de las tintas con que está carga­
da cada una de las 16 plumas posibles en el momento de encender el ordenador. Co­
mo se puede ver, la pluma número 4 está cargada con tinta de color 26 (blanco).
Si ahora escribimos

PEN 1

seleccionamos una pluma que está cargada con tinta negra. Incluso podemos selec­
cionar una pluma cargada con dos colores mediante la orden:

PEN 14

que produce un efecto de parpadeo entre los colores azul y amarillo.

Número de
PEN o Modo 0 Modo 1 Modo 2
PAPER

0 1 1 1
1 24 24 24
2 20 20 1
3 6 6 24
4 26 1 1
5 0 24 24
6 2 20 1
7 8 6 24
8 10 1 1
9 12 24 24
10 14 20 1
11 16 6 24
12 18 1 1
13 22 24 24
14 1/24 20 1
15 16/11 6 24

Figura 20. Colores asignados a las distintas plumas (PEN) y papeles (PAPER)
en los distintos modos antes de modificarlos con instrucciones INK.
Dibujos 55

Como hemos dicho, el máximo número de plumas disponibles es 16, aunque no


todas ellas se pueden utilizar simultáneamente en todos los modos. Observe en la
figura 20 que una pluma que en modo 0 escriba con un color determinado puede
hacerlo con un color diferente en los modos 1 y 2, de modo que un programa gráfico
que funcione correctamente en modo 0 puede no producir ningún efecto en modo 2.
Como puede observar en la figura 20, las 16 plumas del modo 2 no sirven de mu­
cho, ya que 8 están cargadas con tinta amarilla y las otras 8 con tinta azul.
La instrucción INK cambia el color de la tinta con que está cargada una pluma
determinada. Por ejemplo, con la instrucción INK 1,15, la pluma 1, que original­
mente estaba cargada con color 24 (amarillo), se carga con color 15 (anaranjado).
Para ver, por ejemplo, el color rosa, pase a modo 0 y escriba lo siguiente:

PEN 11

Cuando nos ponemos a jugar con los colores, es fácil que nos encontremos con
que no podemos ver lo que estamos tecleando, bien porque los colores de pluma y
de papel sean iguales o porque no sean suficientemente contrastados. Cuando se
encuentre en esta situación, puede teclear una orden PEN aunque no vea aparecer
en la pantalla las letras que escribe. Si está demasiado confuso, siempre puede reini-
cializar la máquina accionando las teclas <CTRL> y <SHIFT) y pulsando, antes de
soltarlas, la tecla <ESC>. Tenga en cuenta, no obstante, que la reinicialización bo­
rra completamente la RAM, con la consiguiente pérdida del programa.
Dicho sea de paso, en cualquier momento puede ocurrir que ejecutemos un pro­
grama que el ordenador no puede acabar. Siempre que parezca que el ordenador
se ha “atascado”, se puede interrumpir el programa pulsando la tecla <ESC>. Con
una pulsación, el programa se detiene momentáneamente; si a continuación se pulsa
cualquier otra tecla, el programa se reanuda. Pulsando dos veces seguidas la tecla
<ESC>, el programa se interrumpe definitivamente. (Para reanudarlo se puede eje­
cutar la orden CONT, a condición de que durante la interrupción no se haya modifi­
cado ninguna línea si introducido otras nuevas.)
También se puede cambiar el color del fondo, utilizando para ello la orden
PAPER, que funciona de forma similar a la PEN. Reinicialice el ordenador con
(CTRL) (SHIFT) (ESC). Pase al modo 0 y escriba:

PAPER 3

Observará que los caracteres que aparecen a continuación están sobre fondo rojo.
Puede cambiar toda la zona interior de la pantalla a este nuevo color escribiendo:

CLS

En modo 0 el papel (fondo) puede ser de los mismos 16 colores que las plumas.
Así, lo mismo que PEN 14 nos daba caracteres de color que alterna entre el azul
y el amarillo, PAPER 14 nos da un fondo de los mismos colores. La figura 20 le
ayudará a seleccionar los colores de pluma y papel. Por ejemplo, para obtener ca­
racteres rojos sobre fondo blanco en modo 0, escriba:
56 Programación BASIC con Amstrad

PEN 3
PAPER 4
CLS

Naturalmente, las órdenes PEN y PAPER se pueden utilizar también incluidas


en líneas de programa:

10 MODE 0
20 LOCATE 2,7
30 PEN 3
40 PAPER 5
50 PRINT "Rojo sobre negro"
60 LOCATE 2,13
70 PEN 6
80 PAPER 3
90 PRINT "Azul sobre rojo"
100 LOCATE 2,19
110 PEN 5
120 PAPER 6
130 PRINT "Negro sobre azul"
140 REM devolver PEN y PAPER a lo normal
150 PEN 1
160 PAPER 0

Si ejecuta este programa en los otros dos modos, cambiando la línea 10, observará
que se obtiene resultados extraños, puesto que las plumas están cargadas con tintas
diferentes en los otros modos. También es posible utilizar variables para seleccionar
plumas y papeles:

10 MODE 0
20 plumarojaenmodo0=3
30 papelnegroenmodo0=5
40 PEN plumarojaenmodo0
50 PAPER papelnegroenmodo0-
60 CLS
70 LOCATE 8,12
80 PRINT "Hecho!"
90 REM devolver PEN y PAPER a lo normal
100 PEN 1
110 PAPER 0

Las dos últimas líneas de este programa hacen que el ordenador vuelva a los colo­
res normales, para que no se encuentre usted con una combinación ilegible como,
por ejemplo, amarillo sobre blanco.
Dibujos 57

Ejercicios

1. Cambie el programa de la página anterior para que escriba los tres mensajes en
verde sobre blanco, rojo sobre amarillo y blanco sobre negro. Ponga el borde
color de cyan.
2. También se puede escribir cada letra de una palabra con un color diferente. Uti­
lice la instrucción LOCATE para desplazarse hasta el punto adecuado y cambie
las plumas antes de escribir cada letra. Escriba las palabras ARCO IRIS en
modo 0 aplicando un color diferente a cada letra.
3. Escriba un programa que capte por el teclado los números de PEN y PAPER
que se han de utilizar, que borre la pantalla y que escriba la frase “Nuevos colo­
res” en el centro. (Los números de PEN y PAPER se deberán captar mediante
instrucciones INPUT referidas a variables numéricas, no a variables literales.)

Gráficos y colores

Dibujar en color es muy fácil con el Amstrad. Ya hemos utilizado las órdenes MO­
VE y DRAW en algunos programas. Tal como las conocemos, estas órdenes dibu­
jan rectas con la pluma número 1, cualquiera que sea el modo en que estemos. Así
pues, todos los programas de gráficos que hemos visto hasta ahora han producido
líneas trazadas con PEN 1. PEN 1 contiene la tinta número 24 en todos los modos
(a no ser que la haya cambiado con una orden INK), de forma que todas las líneas
han sido de color amarillo intenso (vea las figuras 18 y 20 si no está usted seguro
sobre este particular).
Para dibujar líneas con colores diferentes se debe emplear una generalización de
la orden DRAW. Reinicialice el ordenador y escriba:

MOVE 102,13(3
DRAW 300,300,2

El Amstrad ha dibujado una recta que une los puntos (100,100) y (300, 300) utili­
zando la pluma número 2, la cual está cargada con tinta número 20 (cyan intenso)
en modo 1. Escriba:

DRAW 400,0,3

El ordenador ha dibujado una recta de (300,300) a (400,0) con la pluma 3, que esta
cargada con tinta número 6 (roja) en modo 1. (Esta línea puede no ser muy visible
sobre el fondo azul.)
Estas órdenes se utilizan con la misma facilidad dentro de los programas. Recuer­
de que un programa que funcione correctamente en un modo, puede no hacerlo en
otro, debido a que los colores de las tintas dependen del modo de pantalla. El si­
guiente programa dibuja un rectángulo en modo 1, con un lado en amarillo, otro
en cyan y los dos restantes en rojo:
58 Programación BASIC con Amstrad

10 MODE 1
20 MOVE 100,100
30 DRAW 400,100
40 DRAW 400,300.
50 DRAW 100,300,
60 DRAW 100,100,

Observe que en la línea 30 no se especifica PEN, de forma que el ordenador utiliza


PEN 1 automáticamente, dibujando una línea amarilla. Ejecute el programa por
segunda vez. Quizá le sorprenda ver que la línea amarilla ha desaparecido.
Si no especificamos ningún número de pluma, como ocurre en la línea 30, el orde­
nador utiliza la pluma número 1 sólo cuando se trata de la primera orden de dibujar
que obedece. En cualquier otro caso, utilizará la pluma correspondiente a la última
orden de dibujar que haya ejecutado. Cuando termina la primera ejecución del pro­
grama, la última pluma que se ha utilizado es la 3. En la segunda ejecución, al llegar
a la línea 30 la recta se dibuja con la pluma 3, ya que la instrucción DRAW de esa
línea no especifica otra cosa.
La ventaja que esto ofrece consiste en que cuando se ha establecido un número
de pluma en una orden de dibujo, todas las líneas que se trazan a continuación apa­
recen en el color de esa pluma mientras no se especifique otra distinta:

10 MODE 1
20 MOVE 200,100
30 DRAW 400,200,2
40 DRAW 100,350
50 DRAW 200,100

Ejecute este programa también en modo 2, en el cual la pluma 2 está cargada con
un color diferente.
El modo 0 es el más apropiado para dibujar en colores, siempre que no se exija
demasiada resolución:

10 REM dibuja una bandera en 10 colores diferent


es
20 MODE 0
30 PAPER 1
40 CLS
50 REM coordenadas del asta
60 astaizquierda=100
70 astaderecha=120
80 astaabajo=50
90 astaarriba=350
100 topeizquierda=80
110 topederecha=140
120 topearriba=370
130 REM dibujar el asta
Dibujos 59

140 MOVE astaizquierda, astaaba.jo


150 DRAW astaizquierda,astaarriba,
160 DRAW topeizqui erda, topear-riba
170 DRAW topederecha,topearriba
180 DRAW astaderecha,astaarriba
190 DRAW astaderecha,astaabajo
200 REM coordenadas de la bandera
210 banderecha=500
220 banarri ba=240
230 MOVE astaderecha,bañarriba
240 DRAW banderecha,banarriba,2
250 DRAW banderecha,banarriba-100,
260 MOVE banderecha,banarriba
270 banarri ba=banarri ba-10
280 DRAW astaderecha,banarriba,3
290 banarri ba=banarriba-10
300 DRAW banderecha,banarriba,4
310 bañarri ba=banarri ba-10
320 DRAW astaderecha,banarriba,5
330 banarri ba=banarriba-10
340 DRAW banderecha,banarriba,6
350 bañarri ba=banarri ba-10
360 DRAW astaderecha,banarriba,7
370 bañarriba=banarriba-10
380 DRAW banderecha,banarriba, 8
390 banarriba=banarriba-10
400 DRAW astaderecha,banarriba,9
410 banarriba=banarriba-10
420 DRAW banderecha,banarriba,10
430 banarriba=banarriba-10
440 DRAW astaderecha,banarriba, 11
450 bañarriba=banarriba-10
460 DRAW banderecha,banarriba,12
470 DRAW astaderecha,banarriba, 2
480 REM devolver el fondo a normal
490 PAPER 0

Puede bajar la bandera a media asta sin más que modificar la línea 220.

Ejercicios

1. Dibuje una puerta de color verde sobre fondo blanco. Escriba sobre la puerta
el número 12 en caracteres azules y dibuje también un buzón en negro, todo ello
en modo 0.
60 Programación BASIC con Amstrad

2. Modifique el programa anterior para que represente la misma escena, con colores
diferentes, en modo 1. (Tendrá que utilizar plumas diferentes, pues puede ocu­
rrir que las plumas que ha seleccionado para el primer programa estén todas car­
gadas con el mismo color en modo 1).
3. Volviendo al programa de la casa que vimos al principio de este capítulo, modifí-
quelo de manera que pueda captar por el teclado los colores con que se quiera
dibujar las líneas.

Ventanas de colores

Ya hemos visto en este mismo capítulo lo útil que puede resultar la ventana de texto
cuando utilizamos instrucciones INPUT. La instrucción WINDOW tiene otras
aplicaciones relacionadas con el tratamiento de los gráficos. Se puede trabajar con
varias ventanas simultáneamente:

10 MODE 1
20 REM definir ventana #0 arriba a la izquierda
30 WINDOW 1,20,1,12
40 REM definir otra ventana abajo a la derecha
50 WINDOW #1,21,40,13,25
60 PRINT "Esto va a la ventana principal de text
o"
70 PRINT #l,"y esto va a la otra."

La ventana de texto “principal” es aquélla a la que se dirigen todas las órdenes


tales como PRINT y CLS. Por ejemplo,

?"Hola"

escribe en la ventana principal de texto. Pero en cambio

?#1,"Hola"

hace que el mensaje aparezca en la otra ventana. Cada ventana tiene asociado un
número; el de la ventana principal es el #0. En la línea 50 del programa hemos defi­
nido la ventana número 1 mediante la instrucción WINDOW #1. La línea 70 escri­
be en esta ventana gracias a la instrucción PRINT #1. Para escribir en la ventana
principal de texto se puede especificar PRINT #1, o sencillamente PRINT. Pruebe
lo siguiente:

?#0,"Esta es la ventana #0"


?"Esta también es la ventana #0"

La cláusula ‘#0’ es opcional cuando trabajamos con la ventana principal de texto.


Si no mencionamos ningún número de ventana, el ordenador entiende siempre que
nos estamos refiriendo a la ventana #0, o sea, a la ventana principal.
Dibujos 61

Si en algún momento llega a sentirse perdido con esto de las ventanas, vuelva a
la situación normal ejecutando una orden MODE.
Lo más interesante de las ventanas es que no sólo se puede escribir en ellas, sino
que también se les puede aplicar diferentes colores de PAPER y PEN. Añada las
siguientes líneas al programa:

51 REM escribir en la pantalla principal


52 PAPER 3
54 CLS
56 PEN 1
60 PRINT "Esto va a la ventana principal de text
o"
61 REM ahora escribe en la segunda ventana
62 PAPER #1,2
64 CLS #1
66 PEN #1,0

En la ventana #0, esto es, en la ventana principal, se escribe ahora en caracteres


amarillos sobre fondo rojo, mientras que en la #1 se escribe texto azul sobre fondo
cyan. Al seleccionar los números de PEN y PAPER para una ventana, es necesario
especificar el número de ventana. Ésta es la razón por la que las instrucciones de
las líneas comprendidas entre la 62 y la 70 contienen ‘#1’, como por ejemplo PEN
#1,0 en la línea 66. De esta forma seleccionamos PEN 0, que contiene tinta azul,
para escribir sólo en la ventana # 1. Repetimos que, tratándose de la ventana princi­
pal, el ‘#0’ es opcional en lo relativo a las instrucciones PEN y PAPER. También
podíamos haber escrito las líneas 52 a 56 de la siguiente forma:

52 PAPER #0,3
54 CLS #0
56 PEN #0, 1

obteniendo exactamente el mismo resultado al ejecutar el programa. Observe que


todas las órdenes de manejo de texto que ya conocemos pueden ser aplicadas a ven­
tanas distintas de la principal. Escriba:
CLS#1

y verá cómo la ventana número 1 se vuelve de color cyan.


Observe que, aunque la instrucción CLS va dirigida a la ventana número 1, los
mensajes tales como “Ready” siguen apareciendo en la ventana principal, o sea, en
la número 0. Si lo desea, puede enviar el listado del programa a una ventana distin­
ta de la #0:
LIST#1

Escriba:

PEN# 1
62 Programación BASIC con Amstrad

Aunque no parece que haya ocurrido nada, hemos cambiado la pluma de la ventana
#1. Ahora está preparada para escribir con la pluma número 3, lo que se hará evi­
dente cuando le enviemos algún texto:

PRINTttl,"Texto rojo en #1"

Podemos cambiar el color de fondo con:

PAPER#!,1

Tampoco ahora parece que haya ocurrido nada, mientras no escribamos en la


ventana:

PRINTttl,"Fondo amarillo"

Con la orden

CLSttl

cambiamos el fondo de toda la ventana # 1, que pasa a ser ahora de un color amari­
llo intenso.

Ejercicios

1. Defina dos ventanas de texto, una en la parte superior de la pantalla y otra en


la inferior, y escriba su nombre en una y su apellido en la otra.
2. Defina dos ventanas de texto en modo 0 y el mensaje ‘WINDOW #0’ en verde
sobre fondo blanco en la ventana principal, y después ‘WINDOW # 1 ’ en negro
sobre fondo rojo en la otra ventana.

Gráficos y ventanas

Podemos hacer incluso que las ventanas se solapen (es decir, que se superpongan
parcialmente):

10 MODE 1
20 REM definir la ventana principal
30 WINDOW 1,20,8,16
40 PAPER 3
50 CLS
60 REM segunda ventana que se solapa con la prin
ci pal
70 WINDOW #1,11,30,10,18
80 PAPER #1,2
90 CLS #1
Dibujos 63

Observe que la ventana # 1 está delante de la ventana #0. Cuando las ventanas
se solapan, la que se borra en último lugar queda en primer plano; de las restantes
se borra la parte que tengan en común con ésta. Si añade al programa la línea

100 CLS

y borra la línea 50, verá que la ventana #0 predomina, por ser la última borrada,
sobre la # 1. En este aspecto, no hay más predominio entre ventanas que el impuesto
por el orden en que se las borra y por la superficie que tengan en común.
Por si el solapado de ventanas no fuese bastante complicado, el Amstrad nos per­
mite definir y manejar hasta 8 ventanas de texto distintas, numeradas del 0 al 7:

10 MODE 0
20 WINDOW 1,20,23,25
30 INPUT "Dar cuatro colores de pluma (0-16)";pe
ni,pen2,pen3,pen4
40 INPUT "Ahora cuatro coloresde fondo";paper 1,p
aper2,paper3,paper4
50 REM definir las ventanas y asignarles papel y
pluma
60 WINDOW #1,6,15,13,22
70 CLS #1
80 PEN #l,penl
90 PAPER #1,paper 1
100 CLS #1
110 REM llevar el cursor al centro de la ventana
120 LOCATE #1,5,5
130 PRINT #1,"1"
140 WINDOW #2,1,8,7,16
150 PEN #2,pen2
160 PAPER #2,paper2
170 CLS #2
180 LOCATE #2,4,5
190 PRINT #2,"2"
200 WINDOW #3,7,14,1,10
210 PEN #3,pen3
220 PAPER #3,paper3
230 CLS #3
240 LOCATE #3,4,5
250 PRINT #3,"3"
260 WINDOW #4,13,20,6,15
270 PEN #4,pen4
280 PAPER #4,paper4
290 CLS #4
300 LOCATE #4,4,5
310 PRINT #4,"4"
64 Programación BASIC con Amstrad

Este programa demuestra la utilidad que puede llegar a tener la instrucción WIN-
DOW, al proporcionarnos una forma tan fácil y rápida de rellenar con colores zonas
rectangulares.
En la línea 120 se utiliza por primera vez la orden LOCATE referida a una venta­
na. Las coordenadas de texto que se usan con esta instrucción LOCATE están basa­
das en la nueva ventana. Los ángulos superiores izquierdos de las ventanas tienen
coordenadas (1,1); cada rectángulo tiene una anchura de 7 caracteres y una profun­
didad de 9, de modo que el centro de cada ventana se encuentra en (4,5).
Este programa nos demuestra una vez más las ventajas que ofrecen las variables,
y además nos recuerda que cuando tengamos que utilizar números, podemos hacer
el programa más flexible asignándolos a variables.
El programa de gráficos que vimos antes no es el óptimo, ya que no disponemos
de medios para rellenar zonas de color, aunque sí podemos trazar líneas de diversos
colores. Ahora podemos combinar las instrucciones MOVE, DRAW y WINDOW
para producir representaciones gráficas muy vistosas. (Recuerde que la pantalla de
gráficos nunca se ve afectada por las ventanas de texto y que aquélla ocupa siempre
toda la pantalla. Las coordenadas gráficas no dependen, por supuesto, de las venta­
nas que hayamos definido.)

10 MODE. 0
11 REM crear techo rojo
20 WINDOW 3,18,1,5
30 PAPER 3
40 CLS
41 REM crear -fachada marrón
50 WINDOW #1,3,18,6,20
60 PAPER #1,9
70 CLS #1
71 REM crear puerta verde
80 WINDOW #2,10,12,15,20
90 PAPER #2,12
100 CLS #2
101 REM crear ventana amarilla
110 WINDOW #3,6,8,9,12
120 PAPER #3,6
130 CLS #3
131 REM crear segunda ventana azul
140 WINDOW #4,14,17,9,12
150 PAPER #4,6
160 CLS #4
161 REM dibujar vidrios de la ventana
170 MOVE 208,208
180 DRAW 208,272,1
190 MOVE 160,240
200 DRAW 256,240
201 REM dibujar vidrios de la otra ventana
Dibujos 65

210 MOVE 416,240


220 DRAW 544,240
230 MOVE 480,208
240 DRAW 480,272
241 REM adornar la puerta
250 MOVE 296,88
260 DRAW 296,168,5
270 DRAW 372,168
280 DRAW 372,88
290 DRAW 296,88

Figura 21. En modo 0, el espacio dedicado a cada carácter es de 32 puntos


de ancho por 16 de alto. El diagrama muestra la relación entre coordenadas
de texto y coordenadas gráficas.

Al combinar ventanas con instrucciones de dibujo nos encontramos con el peque­


ño problema que plantea la utilización de diversos sistemas de coordenadas. Para
dibujar con precisión dentro de una ventana, tenemos que calcular en qué coordena­
das gráficas empieza la ventana de texto. Si superponemos las coordenadas gráficas
y de texto en modo 0, está claro que el espacio ocupado por cada carácter tiene 32
puntos de ancho y 16 de alto (Fig. 21), de lo que se deduce que, para el modo 0,
las fórmulas que dan las coordenadas del extremo inferior izquierdo de cualquier
carácter:
graficosx=(textox -1) * 32
graficosy=(25 - textoy) * 16
Por ejemplo, la puerta verde del programa anterior se ha formado mediante una
instrucción WINDOW en la línea 80; el carácter del extremo inferior izquierdo de
la ventana tiene las coordenadas (10,20). De esto se deduce que las coordenadas
gráficas del punto extremo inferior izquierdo del interior de la puerta es:
graficosx=(10-l)*32=9*32=288
graficosy=(25—20) *16=5*16=80
66 Programación BASIC con Amstrad

o sea, (288, 80). Sabiendo que la esquina inferior izquierda de la puerta está en
(280, 80) podemos decidir ya qué coordenadas necesitan las órdenes MOVE y
DRAW. Por ejemplo, el dibujo del contorno interior de la puerta comienza en la
línea 250 con una instrucción MOVE que lleva el cursor gráfico al punto (296, 88).
Se escogió este punto porque sabemos que (296, 88) se encuentra algo más arriba
y hacia la derecha del ángulo inferior, (280, 80), de la puerta.
Si esto le parece complicado, no se preocupe demasiado. Las conversiones de
coordenadas de texto a coordenadas gráficas sólo se necesitan cuando deseamos uti­
lizar ambos tipos de coordenadas para una representación especial en pantalla. Más
adelante veremos que estas conversiones son necesarias para la preparación de dia­
gramas o gráficos mezclados con texto, pero también veremos que hay sistemas más
fáciles que el arriba descrito.

Ejercicios

1. Defina cuatro ventanas de diferentes colores de tal forma que se obtenga el si­
guiente diseño:

cyan

Figura 22. Ventanas de colores.

2. Dibuje en modo 0 un coche rojo con ventanas azules, “ruedas” cuadradas negras
y tapacubos blancos.
Intente añadir algunos otros detalles utilizando órdenes MOVE y DRAW.
3. Modifique el programa anterior de modo que el color del coche y la posición en
que se lo deba dibujar sean datos que se capten por el teclado.
4. Programe el dibujo de un hombre asomado a la ventana de una casa y saludando
con la mano. Utilice las instrucciones WINDOW, MOVE y DRAW.
Dibujos 67

Figura 23. Coche para el ejercicio 2.


4

Bucles

REPETICIÓN DE TAREAS

Todos los programas que hemos visto hasta ahora tenían una cosa en común: al eje­
cutar el programa, el ordenador obedecía las instrucciones por orden ascendente de
números de línea, empezando por el más bajo y terminando por el más alto. No
obstante, en algunos casos esto puede tener desventajas, pues puede haber instruc­
ciones que nos gustaría que el ordenador repitiese. Cualquier programa que escri­
bamos contendrá grupos de instrucciones que se ejecutarán linealmente, pero tam­
bién es probable que contenga grupos de instrucciones cuya ejecución deba repetirse
cierto número de veces. Un programa que nos ofrezca la posibilidad de repetir ins­
trucciones será siempre mucho más útil, como demuestra el siguiente:

10 MODE 1
20 FQR cuenta=i TQ 100
30 PRINT cuenta
40 NEXT

La línea 20 establece un bucle de instrucciones. La variable ‘cuenta’ se utiliza pa­


ra llevar la cuenta del número de veces que se ha repetido el bucle. En este caso,
la ‘cuenta’ comienza por 1. En la línea 30 se escribe el valor de la variable, que es
1 en la primera ejecución del bucle.
Cada vez que el programa llega a la línea 40, la instrucción NEXT suma 1 a ‘cuen­
ta’. A continuación se inicia la siguiente pasada por el bucle, en la que se vuelven
a ejecutar todas las instrucciones comprendidas entre FOR ... TO y NEXT, a con­
dición de que ‘cuenta’ no haya alcanzado el valor límite, 100, establecido en la línea
20. ‘Cuenta’ es lo que se denomina variable de control o también variable del conta­
dor del bucle.
Todas las instrucciones contenidas entre el FOR de la línea 20 y el NEXT de la
40, serán obedecidas 100 veces. Inserte otra instrucción entre los dos extremos del
bucle:
10 MODE 1
20 FOR cuenta=l TO 100
30 PRINT cuenta
35 PRINT "Hola"
40 NEXT

68
Bucles 69

En cada pasada por el bucle, el ordenador escribirá el valor de ‘cuenta’ al llegar a


la línea 30, y la palabra “Hola” de la línea 40. Si se modifica la línea 20 de la si­
guiente forma:

10 MODE í
20 FOR cuenta=5 TO 9
30 FRINT cuenta
35 FRINT "Hola"
40 NEXT

verá que el bucle cuenta de 5 a 9. El ordenador ejecuta las líneas 30 y 40 cinco veces
en total antes de dar por terminado el bucle. Para mejor fijar esta idea, modifique
la línea 20 para que la variable del contador empiece por 3 y termine cuando su valor
llegue a 15.
Veamos un pequeño programa que nos da una idea de lo que se puede llegar a
hacer con los bucles:

10 MODE 1
20 FRINT
30 INPUT "Tabla de multiplicar del ",tabla
40 FRINT
50 FOR cuenta=l TO 10
60 FRINT cuenta;"por";tabla;"es";cuenta*tabla
70 NEXT

Este programa escribe la tabla de multiplicar de cualquier número que introduzca­


mos en respuesta a la línea 20. La variable de control se puede utilizar siempre en
instrucciones internas al bucle, generalmente teniendo cuidado de no modificarla:

10 MODE 2
20 FOR coordenadax=l TO 60
30 FRINT TAB (coordenada:;) ; "TAB en un bucle"
40 NEXT

(Lo llamativo en este programa es que, al llenarse la pantalla, la primera línea desa­
parece y las restantes suben para dejar hueco para una nueva.) La variable de con­
trol se puede utilizar también en instrucciones LOCATE:

10 MODE 1
20 FOR x = 10 TO 30
30 LOCATE x,8
40 PRINT "*";
41 LOCATE x,17
42 FRINT
50 NEXT
60 FOR y=9 TO 16
70 Programación BASIC con Amstrad

70 LOCATE 10,y
80 PRINT "*";SPC(19);
90 NEXT

Veamos un par de ejemplos más interesantes:

10 MODE 1
20 LOCATE 20, 1
30 PRINT
40 FOR y=2 TO 10
50 LOCATE 21-y,y
60 PRINT
70 LOCATE 19+y,y
80 PRINT
90 NEXT
100i LOCATE 10,11
110 FOR cuenta=l TO 21
120 PRINT
130 NEXT

10 MODE 0
20 FOR color=0 TO 15
30 PEN color
40 PRINT "Amstrad"
50 NEXT
60 REM vuelta a pluma normal
70 PEN 1

En este último programa, la línea 30 cambia de pluma en cada pasada por el bucle,
a medida que se va incrementando la variable ‘color’. Los bucles producen efectos
asombrosos en los programas gráficos. El siguiente dibuja una serie de triángulos
concéntricos:

10 MODE 1
20 izqx = 100
30 fondoy=0
40 derx=500
50 medx=300
60 arribay=300
70 FOR cuenta=l TO 31
80 MOVE izqx,íondoy
90 DRAW derx,fondoy
100 DRAW medx,arribay
110 DRAW i z qx ,-fondoy
120 izqx=izqx + 10
130 fondoy=fondoy+10
Bucles 71

140 derx=derx-10
150 arribay=arribay-10
160 NEXT

Los bucles facilitan la programación de totalizadores:

10 MODE 1
20 totalgastos=0
30 FOR mes=l TO 12
40 F'RINT "Cuanto ha gastado en el mes"; mes;
50 INPUT gastos
60 totalgastos=totalgastos+gastos
70 NEXT
80 F'RINT "Pues ha gastado" ; total gastos; "pesetas
en total"

Ejercicios

1. Diseñe un programa que escriba su nombre repetidamente hasta llenar la pantalla


en modo 1.
2. Diseñe un programa que escriba una M grande formada por asteriscos.
3. Amplíe el programa de “totalgastos” para que se ocupe también de llevar cuenta
de sus ahorros mensuales y calcule el total de ahorros anuales.
4. Escriba un programa que dibuje una serie de pentágonos concéntricos. Los colo­
res de los pentágonos y la “velocidad de decrecimiento” del tamaño de los pentá­
gonos deben ser captados por el teclado al comienzo del programa.
5. Diseñe un programa que escriba la palabra “Amstrad” en amarillo sobre los 16
colores de PAPER disponibles en modo 0.

Cómo controlar los bucles

Los valores extremos de la variable del contador de un bucle pueden a su vez ser
variables que el programa puede controlar. Con un bucle podemos definir cómoda­
mente una serie de ventanas:

10 MODE 0
11 WINDOW 1,20,20,25
20 INPUT "Cuantas ventanas";ventanas
30 FOR cuenta=l TO ventanas
40 WINDOW ttcuenta,cuenta,cuenta+5,cuenta,cuenta+
4
50 PAPER Scuenta,cuenta
60 CLS »cuenta
70 NEXT
72 Programación BASIC con Amstrad

En la línea 30 el límite superior del bucle es una variable. En la línea 40 se definen


las ventanas en posiciones que dependen del valor de la variable del contador. Trate
de modificar este programa para que defina ventanas de tamaño variable. He aquí
otro ejemplo en el que el límite superior del bucle capta por el teclado:

10 MODE 1
20 INF’UT "Cuantas lineas quiere lineas
30 FOR cuenta=l TO lineas
40 MOVE cuenta*10,0
50 DRAW 320,350
60 NEXT

En respuesta a la línea 20 se puede introducir cualquier número, pero un valor


demasiado alto hará que el programa tarde lo suyo en terminar. En la línea 50 el
segundo extremo de las rectas es fijo, pero también podríamos hacerlo aleatorio, o
incluso dependiente de la variable del contador:

10 MODE 1
20 INPUT "Cuantas lineas quiere "jlineas
30 FOR cuenta=l TO lineas
40 MOVE cuenta*10,0
50 DRAW 500,cuenta*10
60 NEXT

Cuando se trabaja con coordenadas gráficas, no nos interesa que la variable de


control del bucle avance de 1 en 1, porque eso es demasiado lento. En el programa
anterior hubo que multiplicar la variable por 10 para conseguir que los extremos de
las rectas estuviesen suficientemente separados unos de otros. En efecto, comprue­
be qué ocurre si sustituye ‘cuenta* 10’ por ‘cuenta’ en las líneas 40 y 50.
Podemos controlar la tasa de variación de la variable del contador incluyendo en
la definición del bucle la cláusula STEP (paso):

10 REM dibujar 9 rectángulos


20 MODE 0
30 FOR cuenta=0 TO 500 STEP 60
40 MOVE cuenta, 0
50 DRAW cuenta+50,0
60 DRAW cuenta+50,200
70 DRAW cuenta,200
80 DRAW cuenta,0
90 NEXT

En la línea 30 damos a ‘cuenta’ un valor incial de 0; al llegar a la línea 90, este valor
no aumenta de 1 en 1, sino de 60 en 60, que es el valor del paso. Observe que el
extremo superior del bucle no tiene por qué ser un múltiplo del valor del paso. En
este ejemplo, ‘cuenta’ recorre los valores 0, 60, 120, 180, 240, 300, 360, 420 y 480.
Bucles 73

Al llegar a 540, el bucle ya no se repite porque este valor es mayor que 500. El valor
del paso también puede ser una variable. Incluya en el programa anterior una ins­
trucción INPUT que capte el valor del paso. Pruebe con diferentes valores y obser­
ve los resultados.
El siguiente programa es similar, pero más interesante. Dibuja una serie de cua­
drados que pueden solaparse. Pruébelo, por ejemplo, con los valores 5 y 50.

Ejercicios

1. Escriba un programa que dibuje una malla rectángular. (Para ello serán necesa­
rios dos bucles: uno que dibuje las rectas verticales y otro que dibuje las horizon­
tales.)
2. Escriba un programa que acepte como entrada las ventas de varios meses y dibuje
(en modo 0) un gráfico de barras en el que se representen las ventas de cada mes
en un color diferente. (Si dibuja las columnas con órdenes DRAW, sólo podrá
trazar los perfiles; si las dibuja con ventanas de texto, podrá rellenarlas, pero la
precisión será bastante menor.)
3. Nuestro viejo amigo, el propietario del restaurante, ya ha oído hablar de los bu­
cles y ahora se le ha antojado un programa que acepte como entrada el número
de artículos que ha vendido y el precio de cada uno y que calcule el importe total,
que calcule el 12 por ciento de IVA y que lo sume para escribir la cantidad que
debe pagar el cliente. Escríbale usted el programa.
4. Escriba un programa que dibuje un triángulo formado por asteriscos en cual­
quier lugar de la pantalla en el color que se introduzca por el teclado en respuesta
a una instrucción INPUT.

Control con STEP

El valor del paso que se pone tras STEP en los bucles FOR ... NEXT puede ser
negativo o incluso fraccionario. Si utilizamos pasos negativos el valor de partida
del bucle FOR ... NEXT ha de ser mayor que el de parada:

10 MODE 1
20 FOR cuentaatras=10 TO 1 STEP-1
30 PRINT cuentaatras
40 NEXT
50 PRINT "IGNICION!!!!!!!!!!!!!! !

Los pasos con decimales se utilizan con frecuencia en los programas de gráficos en
que los figuras que se dibujan no son simples triángulos ni rectángulos, sino polígo­
nos más complicados. Las coordenadas de los vértices se calculan fácilmente utili­
zando senos y cosenos, cuyos valores son menores que 1.
74 Programación BASIC con Amstrad

El siguiente programa nos permite trazar cualquier figura poligonal, desde un


triángulo hasta una pseudo-circunferencia. El usuario introduce por el teclado la
posición del centro de la figura, el radio y el número de lados:

10 MODE 1
20 INF'UT "Radio de la -f i gura" ; radi o
30 INPUT "Coordenadas X e Y del centro" ; centro::,
centroy
40 INPUT "Numero de lados";lados
50 CLS
60 paso=2*PI/lados
70 MOVE centro:-:,centroy+radi o
80 FOR anguio=0 TO 2*FT STEP paso
90 DRAM centrox+radio*SIN (angui o),centroy+radio*
COS(ángulo)
100 NEXT
110 DRAW centrox,centroy+radi o

Ejercicios

1. Escriba un programa de IGNICION!!! en modo 0, en el que los números de la


cuenta atrás aparezcan dentro de columnas de tamaño decreciente, proporcional
al valor de la variable del contador.
2. Modifique el programa del polígono para que dibuje dos polígonos concéntricos
de colores diferentes.

Datos dentro del programa

Supongamos que queremos escribir un programa que tome los nombres y las notas
de un grupo de alumnos, realice con ellas los cálculos necesarios y escriba las notas
finales. Podría tratarse de un grupo de 100 alumnos, por lo que no parece adecuado
tener que suministrar al ordenador por el teclado los nombres y las notas cada vez
que ejecutemos el programa. Tampoco es aconsejable utilizar una variable para ca­
da dato cuando éstos son muy numerosos. BASIC da una solución a este problema:
los datos se pueden guardar en líneas de programa, precedidos de la palabra clave
DATA, para luego ser leídos por una instrucción READ:

10 MODE 1
20 FOR alumno=l TO 5
30 READ nombrealumno$,notai,nota2
40 notalporciento=notal/60*100
50 nota2porciento=nota2/80*100
60 promedi o=(nota1porci ento+nota2porciento)/2
70 F'RINT nombrealumno$;notalporciento;nota2porci
ento;promedio
Bucles 75
80 NEXT
90 DATA Garcia,40,20,Sanchez, 10, 16
100 DATA Ramos
110 DATA 7,34,Rojo,55
120 DATA 76,Lopez,58,71

La salida de este programa es bastante confusa. Más tarde la arreglaremos, ahora


vamos a estudiar el funcionamiento de las instrucciones que acabamos de presentar.
La instrucción READ de la línea 30 hace que el ordenador examine el programa has­
ta que encuentre una línea encabezada con la palabra ‘DATA’. La primera de estas
líneas es la 90. A continuación lee el primer elemento de la lista de datos, que es
‘García’, y lo asigna a la primera variable de la línea 30, ‘nombrealumnoS’.
Pero en la instrucción READ figuran otras dos variables, de modo que el ordena­
dor tiene que seguir leyendo datos. El número 40 lo asigna a la variable notal, y
el 20 a nota2.
Como nota 1 es una puntuación sobre un total de 60 puntos, la línea 40 la convier­
te a su equivalente sobre 100 puntos. Análogamente actúa la línea 50. La nota me­
dia se calcula en la línea 60, y en la 70 se escriben los datos y los resultados de los
cálculos.
La línea 80 es una instrucción NEXT que hace que el programa vuelva al principio
del bucle, línea 20, tras incrementar la variable del contador. En esta segunda pasa­
da por el bucle la línea 30 actúa de forma diferente: cuando el ordenador ejecuta
por segunda vez una instrucción READ, ya sabe dónde encontrar los datos; de he­
cho, lleva la cuenta de cuántos datos ha leído para saber cuál es el que tiene que
leer a continuación. Así, en la segunda ejecución de la línea 30 lee ‘Sánchez’ y asig­
na esta cadena literal a la variable ‘nombrealumnoS’.
El proceso se repite hasta que se han leído todos los nombres y notas y el bucle
termina. Nótese que, cada vez que se agotan los datos de una línea, el ordenador
busca la siguiente línea DATA y continúa leyendo en ella. Los datos deben estar
separados por comas. El programa funciona igual si los datos se colocan de forma
más organizada:

90 DATA García,40,40
95 DATA Sánchez,10, 16
100 DATA Ramos,7,34
110 DATA Rojo,55,76
120 DATA López,58,71

Para detectar y corregir errores es preferible que las líneas DATA no sean demasia­
do largas. Por otra parte, las líneas DATA pueden estar en cualquier lugar del pro­
grama, no necesariamente antes de las instrucciones READ que leen los datos. El
ordenador ignora las líneas DATA hasta el momento de ejecutar una instrucción
READ. Así pues, las líneas DATA pueden estar al principio del programa, aunque
es más frecuente ponerlas al final; lo que no es recomendable es desperdigarlas por
todo el programa.
En ocasiones un mismo grupo de datos ha de ser utilizado varias veces por el pro­
76 Programación BASIC con Amstrad

grama. Por ejemplo, en un programa como el anterior, podríamos necesitar escri­


bir los nombres y las notas en dos fases del programa. No es necesario duplicar las
líneas DATA, ya que al ordenador le podemos decir dónde debe empezar a leer los
datos mediante la orden RESTORE. Si añadimos la línea
25 RESTORE 95

al programa anterior, veremos que sólo lee el nombre y las notas de ‘Sánchez’. La
instrucción RESTORE 95 obliga a iniciar la lectura de datos en la línea 95; cada vez
que se repite el bucle, el ordenador lee los mismos datos que en la pasada anterior.
Borre la línea 25 e introduzca la siguiente:

15 RESTORE 100

Ahora, al entrar en el bucle, el ordenador sabe que tiene que leer los datos empezan­
do por la línea 100. En la segunda pasada lee los de la 110; en la tercera, los de
la 120. Pero en la cuarta pasada ya no queda ninguna línea posterior por leer y el
ordenador emite un mensaje de error.
La instrucción RESTORE a secas, sin número de línea, hace que el “puntero de
datos” se sitúe señalando la primera línea DATA del programa.
El siguiente programa utiliza la instrucción RESTORE para dibujar una serie de
monigotes en diferentes lugares de la pantalla:

10 MODE 1
20 FOR cuenta=100 TO 500 STEP 100
30 RESTORE
40 READ piernax,piernay,inglex,ingley,piernax1,p
i ernay1
50 READ brazox,brazoy,mediox,medioy,brazox1,braz
oyl
60 READ cabezax,cabezay,oídox,oidoy,oidox1,oí doy
1
70 MOVE piernax+cuenta,piernay:DRAW inglex+cuent
a,i ngley
80 MOVE piernax1+cuenta,piernayl: DRAW inglex+cue
nta,i ng1ey
90 DRAW mediox+cuenta,medioy: DRAW brazox+cuenta,
brazoy
100 MOVE brazox1+cuenta,brazoy1 : DRAW mediox+cuen
ta,medi oy
110 DRAW cabezax+cuenta,cabezay:DRAW oidox+cuent
a,oidoy:DRAW oidox1+cuenta,oidoy:DRAW cabeza
x+cuenta,cabez ay
120 NEXT
130 DATA 35,105,70,150,90,110
140 DATA 60,170,80,180,95,160
150 DATA 80,190,65,205,85,210
Bucles 77

Organización de los cálculos aritméticos

Volviendo al programa de cálculo de las notas medias, podemos mejorarlo en diver­


sos sentidos. En primer lugar, es evidente que tenemos que arreglárnoslas para re­
dondear las notas. El BASIC del Amstrad dispone de varias instrucciones de redon­
deo. Una de ellas es INT, que redondea “hacia abajo”, esto es, al primer número
entero que es menor que el dado:

40 notalporciento=INT(notal/60*100)
50 nota2porci enta;=INT (nota2/80*100)
60 promedio=INT((notalporciento+nota2porciento)/
2)

Observe el número que queremos redondear lo escribimos entre corchetes a la dere­


cha de INT. Este método de redondeo es injusto para los alumnos porque, en caso
de que la nota media no sea un número entero, siempre salen perdiendo. Es preferi­
ble, pues, utilizar con la instrucción CINT, que da el número entero más próximo
al que se desea redondear. De esta forma, 3.4 se redondea hacia abajo, mientras
que 3.5 se redondea hacia arriba:

40 notalporciento=CINT(nota 1/60*100)
50 nota2porciento=CINT(nota2/S0*100)
60 promedio=CINT(<notaIporciento+nota2porciento)
/2)

Ejercicios

1. Mejore el programa de las notas medias organizando mejor la salida, esto es,
ordenando la información en columnas y poniendo una cabecera en cada
columna.
2. Modifique el programa de representación gráfica de las cifras de ventas de
forma que lea los datos en líneas DATA antes de dibujar el gráfico de
barras.
3. Escriba un programa que lea en líneas DATA las coordenadas de texto y los
números de PAPER de siete ventanas antes de definir las ventanas.
4. Escriba un programa que lea las coordenadas gráficas y los números de PEN
de una serie de rectas y que luego las trace para formar el dibujo de un
barco.

NÚMEROS ALEATORIOS

Aprovechando que ya conocemos las funciones INT y CINT, es hora de presentar


una función que es extraordinariamente útil en los programas de juegos. Se trata
de RND, que genera números aleatorios. Escriba:
78 Programación BASIC con Amstrad

?rnd

El ordenador ha escrito un número, elegido al azar, igual o mayor que 0 y menor


que 1. Si vuelve a escribir lo mismo obtendrá un número completamente diferente.
Pero los números aleatorios menores que 1 no tienen demasiado interés en los jue­
gos. Por ejemplo, si tratamos de simular el lanzamiento de una pareja de dados,
necesitamos números aleatorios que sean enteros y puedan oscilar entre 0 y 12, así
que tendremos que transformar los números generados por RND para que sean del
tipo y margen deseados. El método general es el siguiente:
1) Generar el número aleatorio (con RND).
2) Restar el extremo inferior del margen del extremo superior y sumar 1.
3) Multiplicar el número así obtenido por el número aleatorio.
4) Sumar a este el resultado el extremo inferior del margen.
5) Redondear el nuevo resultado con INT.
Por si el método le parece confuso, aquí tiene un programa que se lo aclara:

10 MODE 1
20 INPUT "Minimo numero aleatori o"; menor
30 INPUT "Maximo numero aleatori o"; mayor
31 REM Escribir 20 números aleatorios entre los
dos
40 POR cuenta-1 TO 20
50 numaleat=INT(RND*(mayor—menor+1)+menor)
60 PRINT numaleat
70 NEXT

Como decíamos, los números aleatorios son la base de muchos juegos. El siguiente
programa simula el lanzamiento de dos dados:

10 MODE 1
20 INPUT'"Cuantas veces echo los dos dados";tira
das
30 FOR cuenta=l TO tiradas
40 dadol=INT(RND*6+1)
50 dado2=INT(RND*6+1)
60 totaldados=dadol+dado2
70 PRINT "En la ti radacuenta;"sal ierontotald
ados;"dados"
80 NEXT

También resulta divertido introducirlos en programas gráficos. El siguiente progra­


ma dibuja un número aleatorio de triángulos en posiciones elegidas aleatoriamente:

10 MODE 0
20 numdetriang=INT(RND*100+1>
Bucles 79

30 FOR cuenta=l TO numdetriang


40 izqx=INT(RND*640)
50 derx=INT(RND*640)
60 medx=INT(RND*640)
70 izqy=INT(RND*400)
80 dery=INT(RND*400)
90 medy=INT(RND*400)
100 color=INT<RND*16)
110 MOVE izqx,izqy
120 DRAW derx,dery,color
130 DRAW medx,medy
140 DRAW izqxjizqy
150 NEXT

Observe en este programa que, dado que el extremo inferior del margen de las coor­
denadas gráficas es 0, no hay nada que sumar en la etapa 4) del método de obtención
de números aleatorios enteros. Por eso las expresiones que generan las coordenadas
gráficas, líneas 40 a 90, son más sencillas.

Ejercicios

1. Diseñe un programa que escriba en la pantalla una serie de números aleatorios


enteros comprendidos entre 1 y 10.
2. Modifique el programa de los triángulos aleatorios para que dibuje también rec­
tángulos o algún otro polígono. Puede incluir ventanas, pero no olvide que los
márgenes de las coordenadas de texto son distintos de los de las coordenadas
gráficas.
3. Utilice números aleatorios como parámetros de LOCATE para escribir 100 aste­
riscos de colores aleatorios (en modo 0).

Matemáticas con números aleatorios

Otra aplicación frecuente de los números aleatorios son los problemas de aritmética,
en este caso las tablas de multiplicar:

10 MODE 1
20 FOR preguntas=l TO 10
30 numerol=INT(RND*12+1)
40 numero2=INT(RND*12+1)
50 PRINT"Cuanto es";numerol;"por";numero2;
60 INF'UT respuesta
70 NEXT
80 Programación BASIC con Amstrad

Desde luego, sería preferible que el ordenador pudiese decir si la respuesta es correc­
ta; de no serlo, prodríamos repetir la pregunta para dar otra oportunidad antes de
pasar a la pregunta siguiente. Eso de “repetir” nos hace pensar en un bucle, ¿ver­
dad? Lo que ocurre es que el tipo de bucle que conocemos no sirve en esta situa­
ción. El bucle FOR ... NEXT siempre termina como resultado de una operación
de contar. El ordenador cuenta el número de veces que se ha ejecutado el bucle y
lo interrumpe cuando ese número ha alcanzado cierto valor preestablecido.
Sin embargo, hay ocasiones en las que no sabemos de antemano cuántas veces de­
be ser ejecutado el bucle. El ejemplo anterior, en el que se debe repetir una pregunta
hasta que la respuesta sea correcta, es una de ellas; necesitamos un bucle, pero no
del tipo FOR ... NEXT.

EL BUCLE WHILE ... WEND

El bucle de tipo WHILE ... WEND tiene la solución para nuestro problema. Lo
que lo distingue del bucle FOR ... NEXT es que el bucle WHILE ... WEND termi­
na cuando se cumple cierta condición, no cuando se lo ha ejecutado cierto número
de veces. Su mecanismo es el siguiente:
WHILE (mientras que) la respuesta sea incorrecta
formular otra vez la pregunta
wend (fin de while)
Veamos un pequeño programa que hace una pregunta y la repite hasta que la res­
puesta sea correcta:

10 MODE .1
20 respuesta=0
30 numerol-INT(RND*12+1)
40 numero2=INT(RND*12+1)
50 WHILE respuesta<>numerol*numero2
60 PRINT "Cuanto es";numerol;"por";numero2;
70 INPUT respuesta
80 WEND

En la línea 50 se incluye un signo O, que puede ser desconocido para el lector.


Significa “distinto de”. Así, para la línea 50 se podría leer de la siguiente forma:
“mientras la respuesta sea distinta del producto de numero 1 por numero 2, repetir
las instrucciones siguientes”. El final del grupo de instrucciones que forman el bu­
cle está señalado por la palabra clave WEND (contracción de WHILE y END), línea
80. Obsérvese la diferencia con respecto a FOR ... NEXT. Aquí no tenemos idea
de cuándo terminará el bucle, pero sí sabemos qué tiene que ocurrir para que
termine.
El bucle WHILE ... WEND se programa cuando se desea restringir la entrada
por el teclado a un margen de valores determinado. Uno de los problemas de la pro­
Bucles 81

gramación es que del usuario hay que esperar siempre lo peor. Si un programa pide
al usuario que teclee un número menor que 10, es casi seguro que introducirá un
número mayor “para ver qué pasa”. Si el programa está bien diseñado, examinará
la respuesta y, si ésta está fuera del margen permitido, la rechazará y solicitará otra.
Esto es muy fácil de programar con un bucle WHILE:

10 MODE 1
20 respuesta^11
30 WHILE respiiesta>10
40 INPUT "Por favor, un numero menor que 10: ",r
espuesta
50 WEND

Este programa contiene algunas novedades. En la línea 30 aparece el signo >, que
significa “mayor que”. Así pues, la línea se lee: “mientras la respuesta sea mayor
que 10, repetir las instrucciones siguientes”. Al ejecutar el programa, el ordenador
solicita el número incansablemente, hasta que el usuario decide portarse bien, mo­
mento en el que el bucle termina.
En la línea 20 se hace la variable ‘respuesta’ igual a 11. Es muy importante, cuan­
do se va a entrar en un bucle WHILE, asegurarse de que en el punto de entrada la
condición no se cumple, de modo que el bucle se ejecute al menos una vez. Si no
fuera por la línea 20, al ejecutar el programa no se observaría ningún efecto. Esto
es debido a que BASIC considera que todas las variables valen 0, a menos que se
les haya asignado otro valor; si no se hubiera declarado ningún valor para ‘respues­
ta’, al llegar a la línea 30 la condición se cumpliría, ya que 0 es menor que 10, y
el bucle no llegaría a ejecutarse ni siquiera una vez.
WHILE permite realizar con facilidad bucles infinitos que el usuario puede inte­
rrumpir cuando desee sin más que introducir un valor apropiado. Por ejemplo, con
un bucle FOR ... NEXT podemos construir un programa que sume nuestros gastos
mensuales:
10 MODE 1
20 totalgastos=0
30 INPUT •"Cuantos objetos ha comprado"; objetos
40 FOR cuenta-1 TO objetos
50 PRINT "Cuanto ha costado el objeto";cuenta;
60 INPUT gasto
70 totalgastos=totalgastos+gasto
80 NEXT
90 PRINT "El gasto total -fue de"; total gastos; "pe
setas"

Pero si lo diseñamos con WHILE ya no necesitamos decirle al ordenador cuántos


datos vamos a suministrarle:
10 MODE 1
20 totalgastos=0
82 Programación BASIC con Amstrad

30 respuesta$="S"
40 WHILE respuesta$="S"
50 INPUT "Importe del gasto: ", gasto
60 totalgastos=totalgastos+gasto
70 INPUT "Algo mas (S/N)"; respuesta!
80 WEND
90 PRINT "El gasto total -fue de" ; total gastos; "pe
setas"

Si estamos leyendo datos almacenados en líneas DATA, podemos incluir un termi-


nador de datos para que el bucle sepa cuándo debe dejar de leerlos:

10 MUDE 1
20 READ nombre!, numtel e-f $
30 WHILE nombre!<>"XXX"
40 PRINT nombre!,numtelef$
50 READ nombre!, numtele-f$
60 WEND
70 DATA Alberto,923 234557,Isabel,911 221339,Jai
me,245 4633,Di ana,241 4358
80 DATA Rol ando,733 3234,Pi 1 i,865 2148,Pepe,933
433 833,XXX,YYY

El terminador de datos es un valor que ponemos al final de los datos; tiene que ser
radicalmente distinto de los datos normales para que no quepa la posibilidad de que
el programa interprete como terminador lo que en realidad es un dato. En este caso
el terminador es ‘XXX’. La línea 30 lee nombres y números de teléfono hasta que
el nombre leído sea XXX. Lo que ocurre es que, como la línea 50 lee los datos de
dos en dos, después de XXX tenemos que incluir algo para evitar el error ‘DATA
exhausted’ (“datos agotados”) que de otra forma se produciría. Aquí hemos pues­
to ‘YYY’, pero habría valido cualquier otra cosa.
Volviendo a la cuestión de la elección de terminadores, hay que evitar a toda costa
que el programa los confunda con los datos. Por ejemplo, en un programa de pro­
ceso de notas de examen, no sería aconsejable utilizar el cero como terminador; al­
guien podría habérselas ingeniado para sacar un cero, y entonces la lectura de los
datos terminaría prematuramente. En un caso como éste, un terminador adecuado
sería, por ejemplo, -99.
Algunos aspectos del último programa pueden haberle llamado la atención. ¿Por
qué hay una operación de lectura fuera del bucle (línea 20)? Esto nos resuelve dos
problemas. En primer lugar, puede ocurrir que en las líneas DATA no haya más
datos que el terminador. La línea 20 garantiza entonces que el bucle no llegue a eje­
cutarse, pues la condjción de terminación del bucle se cumple en el mismo momento
en que se intenta iniciarlo.
El segundo problema es el siguiente: si no fuera por la línea 20, el terminador apa­
recería en la lista de salida al final de los nombres. Compruébelo con el siguiente
programa, más sencillo y a primera vista tan bueno como el anterior:
Bucles 83
10 MODE 1
30 WHILE nombre$<>"XXX"
40 READ nombreS,numtelef$
50 F'RINT nombreS, numtel e-f $
60 WEND
70 DATA Alberto,925 234557,Isabel,911 221339,dai
me,245 4633,Diana,241 4358
80 DATA Rolando,733 3234,Pi 1i,865 2148,Pepe,933
433 833,XXX,YYY

Esto evidencia un detalle que hay que cuidar en la programación de bucles WHILE:
si se utiliza como condición para terminar el bucle, el hecho de que una variable to­
me un determinado valor, hay que cerciorarse de que la variable tome ese valor al
final del bucle. En este último ejemplo, leíamos la variable nombre$ al principio
del bucle y por eso la línea 50 puede escribir ‘XXX’. En cambio, en el anterior,
la lectura la realizábamos al final.

Ejercicios

1. Escriba un programa que lea en listas de datos los nombres, edades y fechas de
nacimiento de sus amigos y los escriba ordenadamente en la pantalla. Utilice un
terminador adecuado.
2. Escriba un programa que permita dibujar directamente con el teclado. El pro­
grama dibujará rectas desde el último punto visitado hasta un punto cuyas coor­
denadas debe suministrar el usuario. Defina una ventana de texto a través de
la cual el usuario pueda introducir los sucesivos pares de coordenadas X, Y-.
(Por este procedimiento no será posible “levantar la pluma” al dibujar.) Utilice
un bucle WHILE como núcleo del programa; haga que el bucle termine cuando
el usuario responda con ‘N’ a la pregunta ‘¿Más coordenadas?’.

AND y OR

A veces la condición de terminación del bucle WHILE ... WEND no puede ser sen­
cilla, sino combinación de varias. En un programa en el que hacemos preguntas y
esperamos una respuesta del usuario, podemos querer que la pregunta se repita inde­
finidamente hasta que la respuesta sea correcta. Pero parece más lógico repetirla
solamente un pequeño número de veces, el número de oportunidades que queramos
dar al usuario. La forma de especificar el bucle podría ser: “WHILE (mientras)
la repuesta sea incorrecta AND (y además) el número de intentos sea igual o menor
que 3 ... ”. Veamos un ejemplo:

10 intentos=0
20 respuesta=0
84 Programación BASIC con Amstrad

30 pr i mnum=INT (F;ND* 12+1)


40 segnum=INT<RND*12+1)
50 WHILE respuesta-i. >primnum*segnum AND intentos-i

60 F'RINT "Cuanto es" ; pri mnum; "por " ; segnum;


70 INPUT'respuesta
80 intentos=intentos+1
90 WEND

En el bucle hemos incluido un contador de intentos, líneas 10, 50 y 80. La línea


50 especifica en qué condiciones se puede ejecutar el bucle. En este caso, se tiene
que cumplir que la respuesta sea incorrecta y que además el número de intentos sea
menor que 3. Para que el ordenador pueda ejecutar las instrucciones del bucle es
necesario que se cumplan las dos condiciones. Ejecute el programa varias veces y
compruebe que el bucle se interrumpe solamente cuando se da la respuesta correcta
o cuando se han dado tres respuestas incorrectas.
Las líneas 10, 50 y 80, que son las que tienen que ver con el contador de intentos,
son muy importantes. Es muy fácil confundirse al preparar un contador; con fre­
cuencia ocurre que termina demasiado tarde, o demasiado pronto, o que no termina
nunca. Aquí el contador parte de 0, línea 10; cada intento se contabiliza después
de producirse, línea 80. Después del tercer intento, la variable ‘intentos’ es igual
a 3 y el bucle ya no puede repetirse porque entonces ya no se cumple una de las con­
diciones de la línea 50.
Para fijar las ideas, observe qué ocurre si en la línea 10 se hace el número de inten­
tos igual a 1, lo que no deja de ser un número razonable ya que se va a hacer el
primer intento. Verá que entonces tiene que cambiar las condiciones de la línea 50.
El siguiente programa es un juego en el que se dan 8 oportunidades para acertar
un número aleatorio entero comprendido entre 1 y 100.

10 MODE 1
20 intentos=l
30 numaleat=INT(RND*100+l)
40 adiv=0
50 WHILE adivOnumaleat AND intentos<9
60 PEN 1
70 F'RINT
80 F'R I NT"Opor tuni dad " ;
90 F'EN 3
100 F’RINT i ntentos; : F'EN 1: F'RINT"para adivinar un
numero"
110 F'EN 2
120 F'RINT
130 INPUT "Escriba un numero:adiv
140 IF adivCnumaleet THEN PRINT"demasiado bajo"
150 IF adi v>numal eat THEN F'R I NT " demasi ado alto"
160 intentos=intentos+1
170 WEND
Bucles 85

Las líneas 140 y 150 dan un anticipo de lo que vamos a ver en el siguiente capítulo.
Hemos incluido un poco de color para hacer más atractivo el programa. En esta
ocasión el número de intentos se iguala a 1, no a 0, en la línea 20. No es que quera­
mos complicar las cosas; si no comprende por qué lo hemos hecho, ponga un 0 en
la línea 20 y observe qué ocurre. Dicho sea de paso, y aunque parezca mentira, el
número se puede adivinar siempre en 8 intentos o menos, a condición de que se siga
el método adecuado.
En la definición de bucles WHILE, las condiciones se pueden combinar también
con OR (“o”). Por ejemplo, en un juego de “tres en raya” podría haber un par
de líneas como las siguientes:

500 WHILE gana=0 OR moví mientos<9


510 PRINT"Cual es su movimiento";

donde la variable ‘gana’ se pone a 0 al principio del juego y a 1 cuando gana uno
de los dos jugadores. La estructura del bucle sería:
WHILE (mientras) ninguno de los dos haya ganado
OR (o)
haya huecos libres en el tablero,
seguir jugando
WEND
Esto representa que el juego continúa si se cumple cualquiera de las dos condiciones,
y que termina solamente en el caso de que no se cumpla ninguna de ellas.
También podemos utilizar OR en un bucle WHILE para limitar las respuestas in­
troducidas por el teclado a un margen de valores permisibles. En un ejemplo ante­
rior sólo vigilábamos que el número introducido fuera menor que 10. Ahora pode­
mos comprobar que está entre dos valores extremos:

10 MODE 1
20 INPUT."Escriba un numero del 1 al 10: ",nume
ro
30 WHILE numero<5 OR numero>10
40 PRINT "No es ese. "
50 INPUT "Escriba otro: ",numero
60 WEND
70 PRINT "El numero;"es correcto!"

La línea 30 inicia el bucle, cuya acción principal es pedir un número al usuario. El


bucle se repite siempre que se cumpla cualquiera de las dos condiciones. Hay mu­
chos juegos, semejantes al de “tres en raya”, “barcos”, etc. en los que es necesario
restringir los movimientos para que no se salgan del tablero. Como hemos visto,
el bucle WHILE puede servir para rechazar los movimientos incorrectos.
La comprobación de los datos de entrada (generalmente por el teclado) es lo que se
denomina validación de datos. Se trata de un mecanismo que debe estar presente en
casi todos los programas, tanto en los de juegos como en los educativos y comerciales.
86 Programación BASIC con Amstrad

Ejercicios

1. Escriba un programa que capte por el teclado una coordenada X y rechace los
valores que queden fuera de la pantalla. (Los valores permisibles irán, pues, del
0 al 639, ambos inclusive.)
2. Escriba un programa que escriba una tira de asteriscos en cualquier lugar de la
pantalla. Debe captar por teclado las coordenadas X e Y de texto del lugar don­
de debe empezar la escritura y la longitud de la tira; debe rechazar, lógicamente,
las coordenadas que sean inválidas y las longitudes que, de ser aceptadas, hicie­
ran que la tira no cupiese en el resto de la línea. (Serán necesarios tres bucles
WHILE, uno para cada dato.)
5

Acciones condicionadas

TOMA DE DECISIONES

En el capítulo anterior empezamos a desarrollar un sencillo programa que hacía pre­


guntas y comprobaba la validez de las respuestas; pero teníamos la limitación de que
no sabíamos cómo tomar decisiones en función de la evolución de los acontecimien­
tos. Por ejemplo, nos gustaría que el ordenador diera la respuesta correcta cuando
el usuario no es capaz de aceptarla. Para ello necesitamos saber cómo decirle al
ordenador:
1) Si la respuesta es incorrecta, da tú la correcta.
2) En cambio, si es correcta, formula la siguiente pregunta.
Podemos elegir entre dos cursos de acción si utilizamos la instrucción IF ... THEN
(si ... entonces ...):

10 MODE 1
20 INPUT"Cuantos aftas tienes";edad
30 IF edad>18 THEN F'RINT"Ya no eres un adolescen
te. "

Ejecute este programa varias veces introduciendo edades diferentes. Puede com­
probar que el mensaje de la línea 30 aparece solamente cuando la edad introducida
es mayor que 18. El ordenador examina la afirmación comprendida entre IF y
THEN; si su valor lógico resulta ser “verdadero”, ejecuta el resto de la línea. Si
su valor es “falso” (en este caso, si la edad es igual o menor que 18), ignora el resto
de la línea, esto es, no ejecuta las instrucciones que haya después de THEN, sino
que pasa a la siguiente línea del programa.
Podemos ampliar el programa incluyendo otras instrucciones IF ... THEN que
controlen la acción para otros márgenes de edad:

10 MODE 1
20 INPUT"Cuantos aflos tienes";edad
30 IF edad>18 THEN F'RINT"Ya no eres un adolescen
te."
40 IF edad< = 14 THEN F'RINT"Todavi a estas en E.G.B

87
88 Programación BASIC con Amstrad

50 IF edad>=65 THEN F'RINT"Me parece que ya estas


retí rado."
60 IF edad>100 THEN PRINT"Mas de cien! Felicidad
es! "

La línea 40 comprueba si la edad es igual o menor que 14; la línea 50, si es igual
o mayor que 65. Observe que si introducimos el número 67, se cumplen dos de las
condiciones, y por lo tanto obtenemos dos mensajes. Si introducimos 110 obtene­
mos tres mensajes.
Las instrucciones que pongamos detrás de THEN no tienen que ser necesariamen­
te PRINT, sino que pueden ser cualquier orden válida de BASIC. Por ejemplo, en
nuestro programa de preguntas sobre la tabla de multiplicar, podemos utilizar
IF ... THEN para llevar la cuenta del número de respuestas incorrectas:

10 MODE 1
20 fallos=0
30 FOR preguntas=l TO 10
40 numl=INT(RND*12+l)
50 num2=INT(RND*12+1)
60 PRINT "Cuanto es";numl;"por";num2;
70 INPUT respuesta
80 IF respuesta-i >numl*num2 THEN -f al 1 os=-f al 1 os+1
90 NEXT
100 PRINT
110 PRINT "Has ten i do" ; -f al 1 os; " f al 1 os "

La línea 80 comprueba si la respuesta es correcta. Si es incorrecta, suma 1 a la varia­


ble “fallos”.
El programa sería de mayor calidad si cada vez que el usuario da una respuesta
incorrecta, el ordenador pudiera decirle cuál es la correcta. Podríamos incluir otras
dos instrucciones IF . .. THEN:

80 IF respuesta<>numl*num2 THEN -F al 1 os=f al 1 os+1


85 IF respuestai>numl*num2 THEN PRINT "No, eso n
o es correcto."
86 IF respuestaC>numl*num2 THEN PRINT "La respue
sta es";numl*num2

Pero esto parece tedioso y reiterativo. Una vez comprobada la respuesta en la línea
80, ¿por qué tenemos que comprobarla de nuevo? En realidad, después de THEN
podemos poner varias instrucciones en la misma línea:

80 IF respuestas: >numl*num2 THEN -F al 1 os=-f al 1 os+1 s


PRINT "No, eso no es correcto.":PRINT "La res
puesta es";numl*num2
Acciones condicionadas 89

Si la respuesta es incorrecta, el ordenador ejecuta todas las instrucciones que siguen


al THEN de la línea 80. Las instrucciones tienen que estar separadas por signos de
punto y coma y deben estar todas en la misma línea.
Esta forma de agrupar instrucciones en una línea es válida en cualquier lugar del
programa, no sólo a la derecha de una sentencia IF ... THEN:

10 MUDE 1:fal 1os=0:FOR preguntas=l TO 10:numl=IN


T (RND*12+1) : num2=INT (RND*12+1) : F'RI NT "Cuanto e
s";numl;"por";num2;:INPUT respuesta
20 IF res'puesta<>numl*num2 THEN fal 1 os=fal 1 os+1:
PRINT"No, eso no es correcto.":PRINT "La resp
uesta es";numl*num2
30 NEXT:PRINT:PRINT"Has tenido";fal los;" fal los."

Ahora bien, el lector no debe pensar que esto es una panacea. En realidad, los pro­
gramas tan “compactos” son difíciles de leer y editar. A no ser que el programa
sea muy largo y ocupe gran cantidad de memoria, es preferible dejar las líneas más
bien cortas, con dos o tres instrucciones como máximo en cada una, salvo, natural­
mente, en el caso de las que contengan instrucciones IF ... THEN.
El programa anterior puede servir como base para todos los programas que fun­
cionen a base de preguntas y respuestas. Con ligeras modificaciones, se lo puede
adaptar para que haga preguntas sobre geografía, francés, etc. Veamos un ejemplo:

10 MUDE 1
20 fallos=0
30 FOR preguntas=l TO 12
40 READ mesadlas
50 PRINT "Cuantos di as tiene ";mes$;
60 INPUT respuesta
70 IF respuestaí>di as THEN fal 1os=fal 1os+1:PRINT
"No, eso no es correcto; ";mes$;" ti ene";di as
;"di as"
80 NEXT
90 PRINT
100 PRINT "Has ten i do";fal 1 os;"fal 1 os"
110 DATA enero, 31, -febrero, 28, marzo, 31, abri 1,30, m
ayo,31,jun i o,30
120 DATA julio,31,agosto,31,setiembre,30,octubre
,31,novi embre,30,diciembre, 31

Los datos para las preguntas y las respuestas son los nombres de los meses y los días
que tiene cada uno de ellos. En un programa más general, es posible que los datos
deban contener las preguntas completas; las líneas DATA serían entonces de la
forma:
90 Programación BASIC con Amstrad

200 DATA Cual es la. capital del Reino Unido,Lond


res
210 DATA Que rio pasa por Val 1adolid,el Duero

Ejercicios

1. Escriba un programa que acepte como entrada por el teclado la estatura y el peso
del usuario y haga unos comentarios en función de los valores introducidos.
2. Escriba un programa que lea una lista de nombres y puntuaciones y que escriba
los nombres poniendo ‘APROBADO’ al lado de los que tengan 45 o más puntos,
y ‘SUSPENSO’ al lado de los restantes. Utilice dos colores diferentes para estas
dos palabras.
3. Utilice la instrucción IF ... THEN para mejorar el programa que hace preguntas
sobre la tabla de multiplicar en el siguiente sentido: cuando se han formulado
10 preguntas, el ordenador debe emitir diferentes mensajes en función del núme­
ro de respuestas correctas. Utilice un número de PEN distinto para cada
mensaje.
4. Diseñe su propio programa basado en preguntas y respuestas. Incluya un conta­
dor de las respuestas correctas. Haga que al final del programa se escriba un
mensaje que dependa del número de respuestas correctas y convierta ese número
en un porcentaje sobre el total de preguntas.

IF ... THEN ... ELSE

En el programa de preguntas sobre la tabla de multiplicar podemos incluir una línea


que escriba el mensaje adecuado cada vez que el usuario dé una respuesta correcta:

10 MODE 1
20 fallos=0
30 FOR preguntas=l TD 10
40 numl=INT(RND*12+1)
50 num2=INT(RND*12+1)
60 FRINT "Cuánto es";numl;"por";num2¡
70 INF'UT respuesta
80 IF respuesta«: >numl*num2 THEN f al 1 os=f al 1 os+1 :
F'RINT"No, eso no es correcto. ": F'RINT"La respu
esta es";numl*num2
85 IF respuesta=numl*num2 THEN F'RINT"Correcto. M
uy bien!"
90 NEXT
100 FRINT
110 FRINT "Has tenido" ;-f al los; "Tal los. "
Acciones condicionadas 91

Nos encontramos aquí con una situación muy frecuente en informática: una res­
puesta sólo puede ser correcta o incorrecta, sin ambigüedad ni posibilidades inter­
medias. Al comprobar la validez de una respuesta, sólo hay dos resultados posibles,
y podemos utilizar una ampliación de la instrucción IF .. THEN para controlar los
dos cursos de acción correspondientes:

80 IF respuesta<>numl*num2 THEN fal 1os=fal 1 os+1:


F'RINT"No, eso no es correcto."iPRINT"La respu
esta es";numl*num2 ELSE F'RINT"Correato. Muy B
i en. "

La línea 80 viene a decir: “IF (si) la respuesta es incorrecta THEN (entonces) haz tal
cosa, ELSE (en caso contrario) haz tal otra”. Si la afirmación que se comprueba fuera
más compleja, los resultados posibles serían más de dos y entonces se podrían enla­
zar varias sentencias IF ... THEN ... ELSE para tomar las decisiones oportunas.
Veamos un ejemplo en el que se utiliza IF ... THEN ... ELSE para dibujar un
diagrama de barras de las temperaturas medias mensuales:

10 MODE 0
11 REM preparar ejes
20 ycero=100
30 MOVE 35,0
40 DRAW 35,399
50 MOVE 35,ycero
60 DRAW 600,ycero
61 REM dibujar diagrama de barras
70 FOR mes=l TO 12
80 READ temperatura
90 IF temperatura<0 THEN color=6 ELSE color=3
100 temperaturaescala=temperatura*12
110 MOVE mes*40,ycero
120 DRAW mes*40,ycero+temperaturaescala,col or
130 DRAW mes*40+35,ycero+temperaturaescala
140 DRAW mes*40+35,ycero
150 NEXT
160 DATA -5,-1,0,5,11,15,20,22,14,12,10,-3

En realidad, con la temperatura puede ocurrir una de estas tres cosas: o es mayor
que 0, o es igual a 0 o es menor que 0. Si no queremos incluir la temperatura 0 en
ninguno de los otros dos grupos, necesitamos otra línea:

95 IF temperatura=0 THEN color=12

El siguiente programa, basado en IF ... THEN ... ELSE, demuestra hasta qué
punto los ordenadores pueden parecer inteligentes cuando en realidad no están ha­
ciendo prácticamente nada:
92 Programación BASIC con Amstrad

10 MODE 1
20 INF'UT "Como te 11 amas" ; nombreí
30 F'RINT: F’RINT "Encantado de conocerte, nombre
$
40 F’RINT: F'RINT"Estoy pensando en un animal y qui
ero queintentes adivinar su nombre."
50 F'RINT: F'RINT"Puedes hacerme las preguntas que
quierasacerca del aspecto del animal, pero lu
ego solo tendrás una oportunidad para acertar
su nombre."
60 F'RINT: F'RINT"Cuando creas que lo sabes, respon
de S cuando te pregunte si quieres hacer tu
único intento."
70 F'RINT: F'RINT"Bueno, cual es tu primera pregunt
a?"
80 respuesta$="n"
90 preguntas=0
100 WHILE respuesta$O"S"
110 F'RINT
120 preguntas=preguntas+1
130 L.INE INF'UT"" , pregunta»
140 IF RND(1)>0.5 THEN F'RINT"SÍ " ELSE F'RINT"No"
150 F'RINT: INF'UT "Estas ya preparado intentarlo <
S/N)respuesta»
160 IF respuesta»«: >"S" THEN F'RINT: F'RINT"Cual es
tu siguiente pregunta?"
170 WEND
180 F'RINT: INF'UT"Cual crees que es el. animal ";ani
mal»
190 F'RINT
200 IF RND(1)>0.5 THEN F'RINT"Si ! ! ! Lo adivinaste
conpreguntas; "preguntas. " ELSE F'RINT"No,
lo siento, te has equivocado. Y has hecho";p
reguntas;"preguntas!"
Ejercicios

1. Modifique el programa que califica alumnos con ‘SUSPENSO’ y ‘APROBADO’


de forma que la selección se realice con IF ... THEN ... ELSE.
2. Escriba un programa que lea en líneas DATA una serie de nombres y edades y
dé una relación de los nombres en dos columnas: una para los que tienen derecho
a voto y otras para los que son demasiado jóvenes para votar.
3. Escriba un programa que permita introducir po el teclado datos sobre ingresos
y gastos, estos últimos en forma de números negativos. Disponga una ventana
de texto para escribir en ella una columna con los ingresos y otra con los gastos,
con los respectivos totales al final. Escriba los gastos en rojo y los ingresos en
otro color.
Acciones condicionadas 93

Entrada por el teclado: otro método

Cuando un programa ofrece al usuario múltiples opciones, a menudo es cómodo


utilizar una serie de sentencias IF ... THEN para controlarlas. El siguiente progra­
ma convierte la pantalla en un tablero de dibujo controlado por el teclado:

10 MODE 1
20 direccion$=""
30 coordx=320
40 coordy=200
50 WINDOW 1,40,24,25
60 WHILE di recci on« >"x "
70 INPUT "Due direccion ( i/d/a/bdireccion$
80 IF direccion$="b " THEN coordy=coordy-l
90 IF direccion$="a" THEN coordy=coordy+l
100 IF di recci on$=" i " THEN coordx=coordx-l
110 IF direccion$="d" THEN coordx=coordx+l
120 PLOT coordx,coordy,1
130 WEND

El programa se detiene introduciendo ‘x’.


Hay algunos detalles dignos de observación en este programa. En primer lugar,
puesto que las posibilidades de movimiento de la pluma son cuatro, no tenemos más
remedio que utilizar varias sentencias IF ... THEN. En segundo lugar, el progra­
ma no funciona con el teclado en situación de CAPS LOCK, ya que las sentencias
IF ... THEN, tal como las hemos puesto, sólo reconocen letras minúsculas. Final­
mente, la necesidad de pulsar <ENTER> después de cada letra es irritante. ¿No ha­
brá otra forma más cómoda de utilizar el teclado?
La hay. En lugar de INPUT utilizamos INKEY$:

10 MODE 1
20 direccion$=""
30 coordx=320
40 coordy=200
60 WHILE direccion$<>"x"
70 direccion$=INKEY$
80 IF direccion$="b" THEN coordy=coordy-l
90 IF direccion$="a" THEN coordy=coordy+1
100 IF direcciont>="i " THEN coordx=coordx-l
110 IF direccion$="d" THEN coordx=coordx+l
120 PLOT coordx,coordy,1
130 WEND

El programa funciona ahora de forma completamente distinta. INKEYS examina


continuamente la situación del teclado y reconoce el estado de las teclas sin necesi­
dad de pulsar < ENTER >. Para dibujar una recta hacia la izquierda basta con pulsar
94 Programación BASIC con Amstrad

la tecla ‘i’. Como la tecla es de repetición, al mantenerla pulsada, INKEY$ recoge


una sucesión de letras ‘i’. Estas letras se transfieren, una a una, a la variable
‘dirección!’, línea 70. Es esta variable la que es objeto de comprobación en las lí­
neas 80 a 110, en las que se decide en qué dirección se debe mover la pluma o si
se debe detener el programa.
INKEYS es la función que se debe utilizar siempre que la respuesta del usuario
a través del teclado pueda consistir en un solo carácter. Observe que INKEY$ no
espera hasta que se produzca una pulsación en el teclado, sino que está examinándo­
lo continuamente, aunque no haya ninguna tecla pulsada. Compruébelo con este
programa:

10 MODE 1
20 respuestat="n"
30 WHILE respuesta$<>"s"
40 PRINT "Estas ya listo para parar (s/n)?"
50 respuesta$=INKEY$
60 WEND

El ordenador escribe repetidamente el mensaje porque INKEYS explora el teclado,


no detecta respuesta y la línea 30 permite que el programa continúe. El bucle se re­
pite hasta que el usuario reacciona y pulsa la ‘s’.
INKEYS permite controlar el tiempo que tarda el usario en dar la respuesta. Con
ella podemos hacer intervenir el factor tiempo en los programas de juegos. Ésta es
la base del programa de familiarización con el teclado que viene en la cinta de de­
mostración del ordenador. Todaviía no sabemos cómo generar letras al azar, así
que el siguiente programa es una versión rudimentaria en el que sólo se ofrece al
usuario una letra, leída en una línea DATA:

10 MODE 1
15 PEN 1
20 PRINT "Voy a escribir una letra en la"
30 PRINT "pantalla y quiero que la encuentres lo
II
40 PRINT "mas deprisa posible en el teclado y qu
e"
50 PRINT "la pulses."
60 PEN 3
70 PRINT:PRINT"Seras cronometrado!"
80 PRINT:PRINT "Pulsa R cuando estes preparado"
90 respuesta$=INKEY$
100 WHILE respuesta$< >"R" AND respuesta$O"r"
110 respuesta$=INKEY$
120 WEND
130 arranque=TIME
140 READ letra*
150 PRINTsPRINT "La letra es ";
Acciones condicionadas 95
160 F'EN 2
170 F'RINT letra*
180 respuesta*=INKEY*
190 WHILE respuesta$=""
200 respuesta*=INKEY*
210 WEND
220 total=TIME-arrenque
230 F'RINT: F'RINT "Has tardado";total 7300;"segundo
s"
240 IF respuesta*=letra* THEN F'RINT"pero al meno
s acertaste" ELSE F'RINT"y ademas te equivoca
ste! "
250 DATA q

Las líneas 90 a 120 examinan continuamente el teclado hasta que el usuario pulsa
la tecla de la ‘R’. Observe que el bucle WHILE que se establece en la línea 100 se
repite mientras la respuesta no sea ni ‘R’ ni ‘r’. O sea, el bucle se interrumpe cuando
se pulsa la tecla de la ‘R’, tanto en mayúsculas como en minúsculas.
En la línea 130 empezamos a cronometrar. TIME es una función intrínseca del
BASIC del Amstrad que da, en unidades de 1/300 segundos, el tiempo transcurrido
desde que se encendió la máquina. Escriba

7TIME

y el ordenador le dirá cuánto tiempo lleva encendido. El ordenador actualiza el valor


de TIME continuamente, como puede comprobar volviendo a escribir 7TIME. Lo
que hacemos en la línea 130 es guardar en la variable ‘arranque’ el valor de TIME
en el instante en que se empieza a cronometrar.
Las líneas 180 a 210 realizan otro examen del teclado, pero esta vez no en busca
de una respuesta concreta, sino de la pulsación de cualquier tecla. En cuanto se pul­
sa una tecla, la prueba termina; la línea 220 calcula entonces la diferencia entre el
tiempo actual y el inicial. La línea 230 informa del tiempo transcurrido en
segundos.
Este programa introduce algunas ideas nuevas, a pesar de que está incompleto y
tendremos que ampliarlo más adelante. TIME es una función muy útil de la que
podremos servirnos siempre que necesitemos cronometrar algo.

Ejercicios

1. Vuelva al programa de preguntas aleatorias sobre la tabla de multiplicar e incor­


pore en él algún sistema de cronometrado. Haga que el programa escriba al final
de la prueba el tiempo total transcurrido junto con algún comentario sobre si el
usuario ha sido lento, normal o rápido.
2. Escriba un programa que escriba repetidamente el valor de TIME convertido a
minutos y segundos y que se detenga cuando el usuario pulse la tecla ‘P’.
96 Programación BASIC con Amstrad

3. Amplíe el programa de dibujo para que permita también dibujar rectas en diago­
nal con sólo pulsar una tecla. Incluya la posibilidad de dibujar con el color del
papel, lo que permitirá borrar líneas dibujadas antes y mover la pluma por la
pantalla sin dejar huella. (El problema que se encontrará es que, al elegir esta
opción, ya no se sabe en qué lugar de la pantalla está la pluma; tendrá que dibu­
jar dos puntos en cada posición: uno con el color del papel para borrar y otro
con un color visible para poder identificar la posición de la pluma.)

Condiciones compuestas en IF ... THEN

Las condiciones que se incluyen en las sentencias IF ... THEN pueden ser expresio­
nes complejas, construidas con las operaciones lógicas AND y OR. Nuestro progra­
ma de preguntas sobre la tabla de multiplicar podría contener líneas de este tipo:

100 IF tiempototal>1000000 AND respuestas<5 THEN


PRINT "Ademas de tonto eres lento!"
110 IF tiempototal<5000 AND respuestas<5 THEN F'R
INT "Mas te vale correr menos y acertar mas!"

En un programa que seleccione nuevos alumnos para una famosa universidad po­
dría haber una línea como esta:

200 IF ingresos>4000000 OR CI>130 THEN PRINT“Bie


nvenido a la Universidad!"

El siguiente programa mueve un punto por la pantalla y lo hace rebotar cuando cho­
ca con el borde:

10 MODE 0
20 -fin=0
30 coordx=300
40 coordy=100
50 cambio::=4
60 cambioy=8
70 WHILE fin<l
80 IF coordx+cambiox<0 OR coordx+cambiox>639 THE
N cambiox=-cambiox
90 IF coordy+cambioy<0 OR coordy+cambioy>399 THE
N cambioy=-cambioy
100 coordx=coordx+cambiox
110 coordy=coordy+cambioy
120 color=INT(RND*15+1)
130 PLOT coordx,coordy,col or
140 WEND
Acciones condicionadas 97

El punto parte de las coordenadas (300, 100), líneas 30 y 40. Las líneas 50 y 60 esta­
blecen la amplitud de los movimientos. El bucle WHILE es indefinido; para salir
de él hay que pulsar <ESC> dos veces. Las líneas 80 y 90 calculan el valor futuro
de las coordenadas gráficas; si alguna de ellas es exterior a la pantalla, las instruccio­
nes IF ... THEN invierten el sentido del movimiento en el eje correspondiente, con­
siguiéndose así el efecto de rebote. El movimiento se puede confinar a un área más
pequeña cambiando los valores 0, 399 y 639 que aparecen en las líneas 80 y 90.

Ejercicios

1. Modifique este último programa para que el punto cambie de color al rebotar.
2. Escriba un programa que lea en líneas DATA los nombres y número de senten­
cias condenatorias de una serie de delincuentes. Seleccione los que hayan sido
condenados 10 veces o más y escriba en la pantalla la lista de sus nombres, bajo
el encabezamiento de ‘REINCIDENTES PELIGROSOS’.
3. El departamento comercial de una empresa clasifica sus clientes como buenos pa­
gadores (1), normales (2) y morosos (3). Escriba un programa que lea una lista
de clientes y riesgo actual con ellos y que escriba toda la información disponible
sobre los que tengan calificación 3 o deban más de 100000 pesetas.
6

Cadenas literales

TODO MENOS NÚMEROS

En los capítulos anteriores hemos concertado nuestra atención en las variables nu­
méricas y en las instrucciones con las que podemos manejarlas. Las funciones que
se aplican a las variables literales son también muy potentes. Algunas de las opera­
ciones que realizábamos con variables numéricas son también válidas para las litera­
les, aunque con significado diferente:

10 MODE 1
20 INF'UT "Cual es tu nombre"; nombre!
30 INF'UT "Cual es tu apel 1 i do" ; apel 1 i do$
40 total$=nombre$+" "+apellido$
50 F'RINT "El nombre completo es: ";total$

Las cadenas literales se pueden unir (o concatenar) sin más que poner un signo ‘ + ’
entre ellas. También podemos comparar cadenas con los signos =, > y <, tal como
hacíamos con los números:

10 MODE 1
20 INF'UT "Escribe la primera palabra: ",primeraí
30 INF'UT "Escribe la segunda palabra: ",segunda$
40 IF primera$=segunda$ THEN F'RINT "Las dos pala
bras son identi cas.":END
50 IF priméra$<segunda$ THEN F'RINT primera!;" es
ta antes que ";segunda!;" en el diccionario."
ELSE F'RINT segunda!;" esta antes que ";prime
raí;" en el diccionari o."

En el caso de las cadenas, la igualdad es la identidad absoluta, carácter por carácter.


Por ejemplo, el ordenador considera que ‘Manzana’ es una cadena distinta de ‘man­
zana’. Los ordenadores tienen sus propias ideas acerca de la ordenación alfabética.
De hecho, para la máquina todas las letras mayúsculas van antes que las minúsculas
en el orden alfabético.
Como habrá observado al ejecutar el programa anterior, el ordenador interpreta
el signo "<’, aplicado a cadenas literales, con el significado de ‘anterior en orden

98
Cadenas literales 99

alfabético’. La línea 40 de este programa termina con una instrucción que aún no
conocíamos: END (fin). Su efecto es terminar el programa. El ordenador lo hace
sin que se lo pidamos explícitamente cuando se le acaban las líneas, pero en este caso
nos interesaba poner END en la línea 40 para impedir que la ejecución continuase
en la 50. Suprima el END y observe qué ocurre cuando ejecuta el programa e intro­
duce dos cadenas idénticas.
La capacidad de comparar cadenas es fundamental en los trabajos de ordenación.
Es muy frecuente tener que ordenar nombres, y la máquina puede realizar este tedio­
so trabajo para nosotros. Por ejemplo, podemos formar una base de datos con in­
formación sobre algún tema de nuestro interés; el ordenador puede examinarla rápi­
damente y extraer de ella la información que nos interese en cada momento. Así,
si en un programa tenemos grabada información sobre los nombres y fechas de naci­
miento de nuestros amigos, el ordenador puede averiguar con gran rapidez el cum­
pleaños de un amigo en cuanto le demos el nombre:

10 MODE 1
20 INPUT "Como se llama tu ami go";amigo$
30 WHILE nombre$<>"XXX" AND nombre$<>amigot
40 READ nombret,cumple$
50 IF nombre$=amigot THEN PRINT amigot;" cumple
afros el "jcumplet
60 WEND
70 IF nombre$="XXX" THEN PRINT "Lo siento. No co
nozco a tu amigo."
80 DATA JUANITA RODRIGUEZ,29 de octubre,LUIS GOM
EZ,16 de mayo,MARIANO PEREZ,3 de junio
90 DATA XXX,XXX

Por supuesto, cuando hay tan pocos datos, la velocidad a la que trabaja el ordena­
dor no representa gran ventaja. Veremos más adelante que los datos del programa
se pueden guardar fuera de él. Cuando hay miles de datos que examinar, la veloci­
dad del ordenador sí es de agradecer.
Un problema que usted puede haber descubierto en este programa tiene que ver
con algo que anunciábamos al principio del capítulo. El ordenador no reconoce el
nombre de nuestro amigo a menos que lo escribamos exactamente tal y como figura
en la lista de datos. En algunos ordenadores este problema sólo se resuelve median­
te una complicada manipulación de las cadenas introducidas. En el Amstrad todo
es más sencillo. Escriba

?upper$("Pedro")

(En inglés, upper case significa “mayúsculas”). UPPER$ convierte todas las letras
a mayúsculas. Si le decimos que lower case significa “minúsculas”, no le será difícil
averiguar para qué sirve la función LOWERS:

?lower$("Pedro")
100 Programación BASIC con Amstrad

Podemos mejorar nuestro programa añadiéndole la siguiente línea:

25 ami goS=UPF'ERS (amigoS)

Esta línea pide al ordenador que tome la cadena literal que hay almacenada en la
variable ‘amigoS’, la convierta en mayúsculas y luego la vuelva a guardar en la mis­
ma variable. Si ejecuta nuevamente el programa, verá que ahora puede escribir los
nombres en mayúsculas o en minúsculas. Para que este método funcione es necesa­
rio que haya una consistencia en la forma de poner los datos en las líneas DATA.
De poco sirve convertir la entrada con UPPERS o LOWERS si en los datos hay una
mezcla de mayúsculas y minúsculas.

Ejercicios

1. Escriba un programa que acepte como entrada su nombre, su apellido y su título


(Sr., Sra., Dr., etc.) y que combine las tres cadenas para escribir el nombre
completo.
2. Escriba un programa de léxico inglés-español que escriba la palabra inglesa equi­
valente a la que se introduce por el teclado.
3. Escriba un programa que acepte como entrada tres palabras y las escriba en or­
den alfabético. (No es tan fácil como usted cree).

Longitud de una cadena

En muchas ocasiones es necesario poder averiguar la longitud de una cadena. Por


ejemplo, si vamos a poner como cabecera de una columna una cadena captada por
el teclado, tenemos que estar seguros de que la cadena tecleada no es más larga que
la anchura de la columna. O bien, si debemos centrar una frase en la pantalla, nece­
sitamos saber cuál es su longitud para calcular en qué posición debemos empezar
a escribirla. La función que determina la longitud de las cadenas es LEN. Escriba

?1en("Juan")

El ordenador ha dado la respuesta correcta, 4. Como ya hemos anunciado, pode­


mos utilizar LEN para centrar frases:
10 MODE 1
20 INPUT "Como te 11 amas"; nombres
30 CLS
40 1ongitud=LEN(nombres)
50 posicionx=(40-1ongitud)/2
60 LOCATE 18,11
70 PEN 3
80 PRINT "hola"
Cadenas literales 101

90 LOCATE posicionx,13
100 F'EN 2
110 PRINT nombre*

La línea 40 resta la longitud de la cadena de la longitud de línea (que es 40 en modo


1) para determinar cuántos espacios van a quedar libres. Para que la frase quede
centrada, los espacios se deben repartir, la mitad a cada lado. Por eso, al dividir
por 2 el número de espacios, obtenemos la coordenada de texto X en la que debemos
empezar a escribir la cadena. En otros ordenadores habría que redondear este nú­
mero con INT, pero a la orden LOCATE de la línea 90 no parece importarle el que
uno de sus parámetros no sea entero.
Si observa con atención, verá que algunas cadenas no quedan perfectamente cen­
tradas. Esto se debe a que cuando la cadena es de longitud impar los espacios so­
brantes no se pueden repartir a partes iguales.
Veamos otro ejemplo de aplicación de LEN:

10 MODE. 1
20 INPUT "De que longitud quieres buscar palabra
s";1ongi tud
30 READ palabra*
40 «HILE palabra*<>"XXX"
50 IF LEN(pal abra*)=1ongitud THEN PRINT palabra*
60 READ palabra*
70 WEND
80 DATA una, característica,de,la,informática,se,
hizo, "patente,", y,todavía,sigue si endo, val i da
,hoy,"di a: "
90 DATA los,ordenadores,se,estaban,haciendo,cada
,vez,mas,"pequemos,", y,sobre,todo,mas,baratos
100 DATA XXX

La línea 90 de este programa puede parecerle extraña. La explicación es la siguien­


te: el ordenador interpreta la coma como separador de datos; la única forma de in­
cluir una coma en un dato es encerrar la cadena entre comillas. Por eso hemos teni­
do que poner entre comillas “patente,” y “pequeños.”.
El Amstrad puede repetir un carácter para formar una cadena de la longitud
especificada:

?=tring*(20,"A")

Si no fuera por esta función, para conseguir el mismo tendríamos que formar un
bucle que añadiese en cada pasada un carácter a la cadena.
10 MODE 1
20 INPUT "Base del rectángulo: ",base
30 INPUT "Altura: ", altura
102 Programación BASIC con Amstrad

40 CLS
50 LOCATE 1, 1
60 PRINT STRINGí(base,"*")
70 POR posiciony=l TO altura-2
80 PRINT ;SPC(base—2);"*"
90 NEXT
100 PRINT STRINGS(base,"*")

En la línea 70 hemos puesto ‘altura-2’ porque las dos cadenas de asteriscos escri­
tas en las líneas 60 y 100 también cuentan para la altura. Por razón análoga hemos
puesto ‘base-2’ en la línea 80.

Ejercicios

1. Modifique el programa que busca palabras de una longitud especificada en el si­


guiente sentido: el programa debe escribir el texto completo, llenando en lo posi­
ble las líneas de la pantalla, y distinguir las palabras seleccionadas escribiéndolas
en un color diferente del de las restantes.
2. Una función típica de los procesadores de texto es la búsqueda y sustitución de
palabras, mediante la cual el usuario hace que el ordenador busque en todo el
texto una palabra determinada y la cambie por otra. Diseñe un programa que
lea un texto en líneas DATA, busque una palabra para sustituirla por otra siem­
pre que aparezca y escriba el texto modificado en la pantalla.
3. Escriba un programa que acepte como entrada su nombre y luego lo escriba cen­
trado dentro de un rectángulo formado por asteriscos.

Eslabones sueltos

El programa que buscaba cadenas de una longitud determinada tenía un pequeño


defecto: consideraba que la cadena “dia:” tenía cuatro letras.
Podemos eliminar los signos de puntuación examinando el último carácter de la
cadena y suprimiéndolo si no es una letra. Para ello necesitaremos una de las fun­
ciones de manejo de cadenas que extraen subcadenas de una cadena dada. Veamos
un ejemplo:

?1 eft$("Hola, que tal",4)

(En inglés, left significa “izquierda”.) Esta orden extrae de la cadena de entrada los
cuatro primeros caracteres de la izquierda. Otro ejemplo sería

?1eft$("entrada/salida" , 7)

lo que nos da ‘entrada’. Sabiendo que right significa derecha, puede imaginar cuál
será el efecto de la función RIGHTS:
Cadenas literales 103

?ri ght$("Barato",4)

Efectivamente, extrae cuatro caracteres por la derecha. La tercera función de este


grupo es más versátil, pues puede sustituir a LEFT$ y RIGHT$ y además extraer
caracteres del interior de las cadenas:

?mid$("Instituto",6,2)

(Middle significa “medio”.) En este ejemplo, MID$ genera una subcadena extra­
yendo 2 caracteres a partir del sexto: ‘tu’. Si no se incluye el segundo número, los
caracteres que se extraen son todos los restantes, de modo que, por ejemplo,

?mi d$("Recompensar " , 6)

produce ‘pensar’.
Como era de esperar, estas funciones son aplicables también a variables literales.
Pero volvamos a nuestro problema original. Tenemos que suprimir el último carác­
ter de la cadena siempre que no sea una letra. Introduzcamos la siguiente modifica­
ción en el programa:

40 WHILE palabra$<>"XXX"
41 fi opalabra$=RIGHT$(palabra$,1)
42 longpalabra=LEN(palabra$)
43 IF finpalabra$="." OR finpalabra$=" ," OR finp
alabra$="i" THEN 1ongpalabra=longpalabra- 1
50 IF 1 ongpal abr a=l ongi tud THEN F'RINT palabrat
60 READ palabras
70 WEND
100 DATA XXX

La línea 41 toma el último carácter de la cadena. Si es un signo de puntuación, la


línea 43 decrementa el valor de la variable ‘longpalabra’.
MID$ puede ayudarnos a eliminar los espacios no deseados que pueda haber en
las cadenas introducidas por el teclado. Ya hemos visto en un programa anterior
que el ordenador distingue “Alvarez” de “ALVAREZ”, a pesar de que a los huma­
nos ambas palabras nos puedan parecer la misma. Este problema lo resolvíamos
aplicando UPPERS o LOWERS a la cadena de entrada. Pero a este respecto hay
otra fuente de conflictos: los espacios que el usuario puede teclear antes, después
y en medio de las cadenas. El ordenador ignora los espacios que se teclean antes
y después de las cadenas, pero no los interiores. Por consiguiente, distingue entre
‘E.Alvarez’, ‘E. Alvarez’ y ‘E. Alvarez’; sólo la primera de estas cadenas será re­
conocida al comparlas con lo almacenado en las líneas DATA. Como solución, se
puede adoptar la norma de guardar en las líneas de DATA las cadenas sin espacios
y luego suprimir sistemáticamente todos los espacios de las cadenas captadas por el
teclado.
104 Programación BASIC con Amstrad

Eso es lo que hace el siguiente programa. Usted puede mezclarlo con el programa
que pregunta el nombre del amigo y busca la fecha del cumpleaños. Para hacer más
patente la diferencia entre la cadena de entrada y la elaborada por el programa, las
líneas 120 y 170 escriben las dos cadenas flanqueadas por asteriscos:

10 MODE 1
20 INF’UT "Escriba una frase: ",frase$
30 longfrase=LEN(frase$)
40 nuevafrase$=""
50 FOR caracter=l TO longfrase
60 letra*=MID*(frase»,carácter,1)
70 IF letra*<>" " THEN nuevafrase$=nuevafrase$+l
etra»
80 NEXT
90 PRINT
100 PRINT "La -frase original era: "
110 PRINT
120 PRINT STRING*(10, "*") ;frase*;STRING*(10, "*")
130 PRINT
140 PRINT
150 PRINT "La frase nueva sin espacios es: "
160 PRINT
170 PRINT STRING*(10,"*");nuevafrase*;STRING*(10
, "*")

También podemos utilizar MID$ para poner en clave un mensaje captado por el
teclado:

10 MODE 1
20 INF'UT "Escribe el mensaje que quieras que pon
gaen clave: ",palabra*
30 elave*=palabra*
40 1ongitud=LEN(pal abra*)
50 FOR lio=l TO longitud
60 aleat=INT(RND*1ongitud+1)
70 der=longitud-aleat
80 elave*=LEFT*(el ave*,aleat-1)+RIGHT*(el ave*,de
r)+MID*(el ave*,aleat,1)
90 NEXT
100 PEN 1
110 PRINT:PRINT "El mensaje en clave es: ";
120 PEN 3
130 PRINT clave*
140 PRINT
150 REM vuelta a la pluma normal
160 PEN 1
Cadenas literales 105

El bucle de las líneas 60 a 110 revuelve las letras de la frase introducida. Podríamos
haber hecho que el bucle se repitiese, por ejemplo, 5 veces, pero entonces las frases
largas no quedarían suficientemente deformadas, así que hemos preferido que el lí­
mite superior del bucle fuera precisamente la longitud de la cadena de entrada. Lo
primero que hacemos es elegir en la línea 80 una posición de partida. Después, en
la línea 90, calculamos cuántas letras quedan a la derecha de esa posición. Final­
mente, en la línea 100 juntamos los dos trozos de la cadena, excluyendo la letra que
está en la posición seleccionada al azar, y ponemos esa letra al final.

Ejercicios

1. Escriba un programa que capte por el teclado una palabra y la escriba en la pan­
talla dedicando una línea a cada letra.
2. Modifique el programa del ejercicio anterior para que todas las letras se escriban
en la misma línea, pero con la letra ‘e’ en un color diferente.
3. Escriba un programa que acepte como entrada su nombre y apellidos y escriba
sus iniciales.
4. Escriba un programa que lea en líneas de DATA una serie de palabras y las repar­
ta en dos columnas: en una las que empiezan con mayúscula y en otra las que
empiezan con minúscula. (Recuerde que el ordenador considera que todas las
letras que empiezan con mayúscula son anteriores en el orden alfabético a las que
lo hacen con minúscula.)

La función INSTR

El BASIC del Amstrad dispone de una función que permite buscar rápidamente una
subcadena dentro de una cadena. Se trata de la función INSTR. Por ejemplo, si
escribimos

?instr("Rescate","es")

el ordenador examina la cadena ‘Rescate’ para averiguar si dentro de ella se encuen­


tra la cadena ‘es’. En caso afirmativo, INSTR da el número de la posición, dentro
de la cadena mayor, donde empieza la subcadena (en este caso, el número 2).
Escriba

?instr("Rescate","cate")

y obtendrá el número 4. ¿Pero, qué ocurre si la subcadena buscada no está en la


cadena en la que se busca? La función INSTR genera entonces el número 0:

?instr("Rescate","Salvamento" )

Nada impide buscar con INSTR en cadenas mucho más largas:


106 Programación BASIC con Amstrad

?instr("este es el testamento","te")

(El único límite es el impuesto por la máxima longitud de las cadenas que admite
el Amstrad: 255 caracteres.) En este último ejemplo, el ordenador ha respondido
con el número 1, que es la primera posición en que aparece ‘es’. Una vez detectada
la primera aparición de la subcadena, podemos seguir buscándola en el resto de la
cadena original. Para ello debemos especificar en qué posición debe comenzar la
búsqueda. En este caso, como sabemos que ‘es’ aparece por primera vez en la posi­
ción 1, debemos seguir buscando a partir del segundo carácter:

?instr(2,"este es el testamenta","es")

Otra vez encontramos ‘es’, ahora en la posición 6, luego podemos seguir buscando
a partir de la 7:

?instr (7,"este es el testamento","es")

El ordenador escribe el número 13, y nosotros reanudamos la búsqueda a partir de


la posición 14, y así hasta que INSTR dé el número 0. (¿Qué podemos hacer para
buscar solamente la palabra ‘es’, o sea, para que el ordenador no detecte estas dos
letras dentro de una palabra más larga, tal como ‘este’ o ‘testamento’?)
El siguiente programa utiliza INSTR para contar el número de letras ‘e’ que hay
en una palabra:

10 MODE 1
20 INPUT "Escriba una palabra: "..palabras
30 arranque=l
40 numerodees=0
50 continuar=l
60 WHILE continuar=l
70 posicion=INSTR(arranque,pal abraí, "e")
80 IF pasicion>0 THEN numerodees=numerodees+1: P
RINT"Hay una ’e’ en la posición posición:ar
ranque=posicion+l ELSE continuar=0
90 WEND
100 PRINT “En la palabra hay";numerodees;"letras
’e’ en total"

La línea 80 actualiza el valor de ‘arranque’ para que la siguiente búsqueda se realice


a partir de la posición siguiente a la actual. Cuando se acaban las letras ‘e’, la cláu­
sula ELSE hace ‘continuar’ igual a 0 y el bucle termina.
Un método análogo se puede utilizar en el juego Hangman:

10 MODE 1
11 REM escoger una palabra aleatoriamente
20 numerodepalabras=10
Cadenas literales 107

30 palabraelegida=INT(RND*numerodepalabras+1)
40 FOR palabras=l TO palabraelegida
50 READ palabra*
60 NEXT
61 REM preparar las variables
70 1ongitud=LEN(pal abra*)
80 resputesta$=STRING$ (1 ongi tud, ")
90 intentos=l
100 adiv$=“"
101 REM dar 10 oportunidades
110 WHILE intentosíll AND respuesta*<>palabra*
120 PEN 3
130 PRINT
140 F'RINT"l_a palabra es "¡respuesta*
150 PRINT
160 PEN 1
170 F'RINT"Este es el intento numero";intentos
180 PRINT
190 INPUT"Adi vi na una letra: ",letra*
191 REM comprobar si esa letra aparece en la pal
abra
200 arranque=l
210 continuar=l
220 WHILE continuará
230 posi ci on=INSTR(arranque,palabra*,letra*)
231 REM si la letra aparece, colocarla en la res
puesta en la posición correcta
240 IF posicion>0 THEN respuestaT=LEFTT(respuest
a$,posición-1)+letra$+MID$(respuesta*,posici
on + 1):arranque=posicion+1 ELSE continuar=0
241 REM continuar comprobando letras hasta que n
□ haya mas coincidencias
250 WEND
251 REM otro intento
260 intentos=intentos+l
270 WEND
280 PEN 2
290 PRINT
300 IF respuesta*=palabra* THEN PRINT"Lo consegu
iste!" ELSE PRINT"Era ";palabra$
310 PEN 1
320 END
330 DATA chacal,1 ince,antilope,elefante,tigre
340 DATA rinoceronte,i guana,avestruz,panda,bal 1e
na
108 Programación BASIC con Amstrad

Este programa contiene dos bucles WHILE, uno dentro del otro. En el capítulo si­
guiente estudiaremos más detenidamente esta cuestión de los “bucles anidados”.
Las palabras que vamos a utilizar en el juego están en las líneas de DATA, 330 y
340. Si quiere añadir otras palabras, ponga más sentencias DATA y modifique la
línea 20 para que el ordenador sepa cuántas palabras hay.
La primera parte del programa selecciona una palabra al azar, para lo cual lee
un número de palabras determinado aleatoriamente. Una vez elegida la palabra,
la línea 80 forma una cadena de la misma longitud y compuesta por guiones. El
bucle WHILE externo que empieza en la línea 110 da 10 oportunidades para adivi­
nar la palabra. El bucle interno, líneas 220 a 250, examina la palabra para determi­
nar en qué posición se encuentra la letra tecleada, si es que está en ella. Si la letra
está en la palabra, la línea 240 coloca la letra en la cadena ‘respuestaS’ en la posición
correcta. Es decir, cuando se acierta una letra, ésta sustituye un guión (o varios)
en ‘respuestaS’. El programa termina cuando las cadenas ‘palabraS’ y ‘respuestaS’
son idénticas o cuando se han consumido las 10 oportunidades.
Quizá le resulte difícil de seguir el programa. En cualquier caso, sirva como de­
mostración de que, con las instrucciones de BASIC que hemos introducido hasta
ahora, es posible escribir programas relativamente sofisticados. Esta versión de
Hangman funciona igual que la incluida en la cinta de demostración, aunque sin el
atractivo de los gráficos.

Ejercicios

1. El programa de Hangman tiene dos pequeños defectos. El primero es que permi­


te que el usuario teclee más de una letra en cada intento. El segundo es que no
avisa al jugador cuando teclea una letra que ya ha sido introducida antes. Corri­
ja usted estos dos defectos. (Sugerencia para el segundo: ¿se podría utilizar la
concatenación para mantener una lista de las letras introducidas?)

EL JUEGO DE CARACTERES DEL AMSTRAD

En un programa anterior vimos cómo podíamos eliminar de una cadena caracteres


que no fueran letras, tales como el punto, la coma y los dos puntos. El método no
tiene interés general, ya que, además de estos tres, hay muchos otros caracteres que
pueden estar al final de una cadena y no ser letras; por ejemplo, las comillas, el pun­
to y coma, los signos de admiración y de interrogación y el de cerrar paréntesis. Se­
ría muy pesado tener que comprobar todos estos caracteres uno a uno. ¿No habrá
una forma más fácil de averiguar inmediatamente si un carácter es una letra o no
lo es?
Pues sí, la hay. Todos los caracteres que se pueden generar mediante el teclado
tienen asociado un código numérico, denominado código ASCII. El margen de estos
códigos va del 0 a 255. Los 32 primeros, del 0 al 31, tienen para el ordenador signifi­
cados especiales, tales como “borrar la pantalla” o “hacer avanzar el cursor una
posición”. Los códigos del 32 al 255 representan caracteres visualizables en la pan­
Cadenas literales 109

talla. Una de las ventajas de este sistema de codificación reside en el hecho de que
las letras están agrupadas en dos series de códigos; por eso, observando su código,
es muy fácil determinar si un carácter es una letra. Por ejemplo, los códigos del
65 al 90 representan las letras mayúsculas:

10 MODE 1
20 FOR codigo=65 TO 90
30 PRINT CHR$(codigo);
40 NEXT

La línea 30 nos presenta una nueva función, CHR$, que convierte los códigos AS­
CII en caracteres. El código 65 representa la letra ‘A’, el 66 la ‘B’, etc. Los códigos
del 97 al 122 representan las letras minúsculas. Modifique la línea 20 para
comprobarlo.
Los restantes códigos representan los signos de puntuación, las cifras y muchos
otros caracteres que se utilizan principalmente en juegos. Modifique la línea 20 del
programa anterior para que el bucle se extienda del 32 al 255 y podrá ver la mayor
parte del juego de caracteres del Amstrad.
Una advertencia: los códigos inferiores al 32 representan para el ordenador diver­
sas órdenes (son códigos de control). Si los “imprimimos” por error, obtendremos
efectos inesperados. Pruebe el programa haciendo que el bucle vaya de 0 a 255. Pa­
ra volver a la normalidad, ejecute una orden de modo de pantalla, o bien reinicialice
la máquina con <CTRL> <SHIFT> <ESC>.
En realidad, los códigos del 0 al 31 también representan caracteres visibles, pero
para que puedan aparecer en la pantalla tienen que ir precedidos del código ASCII
número 1. El código 1 es un código de control cuya función es decirle a la máquina:
“visualiza en la pantalla el código que viene a continuación, aunque sea menor que
32, y déjate de tonterías”:

10 MODE 1
20 FOR codigo=0 TO 31
30 PRINT CHR$(1);CHR$(codigo);
40 NEXT

Caracteres Códigos ASCII

Códigos especiales 0-31


y de control
Espacio 32
0-9 48-57
A-Z 65-90
a-z 97-122

Figura 24. Algunos de los códigos ASCII más útiles.


110 Programación BASIC con Amstrad

Muchos de estos caracteres se pueden obtener pulsando <CTRL> en combinación


con las teclas de letras. Compruébelo recorriendo el alfabeto.
El juego de caracteres está descrito con detalle en el Manual del Usuario.
Otra ventaja de los códigos ASCII es la facilidad con la que se restringe la entrada
por el teclado a un margen predeterminado de caracteres. El siguiente programa
escribe las letras mayúsculas que el usuario introduzca e ignora todos los demás ca­
racteres. El programa consiste en un bucle infinito; para interrumpirlo hay que pul­
sar dos veces la tecla <ESC>:

10 MODE 1
20 continuar=l
30 WHILE continuar=l
40 codigo$=INKEV$
50 IF codigo$<>"" THEN codigo=ASC(codigo$)
60 IF codigo>64 AND codigo<91 THEN PRINT codigoi
?
70 WEND

En la línea 40 la función INKEY$ examina el teclado. Si detecta una pulsación,


guarda el carácter introducido en la variable *codigo$’. En la línea 50 encontramos
otra función de BASIC: ASC convierte un carácter en su correspondiente código
ASCII. Necesitamos la comprobación IF ... THEN porque, si no se ha pulsado
ninguna tecla, codigoS es la cadena vacía (ningún carácter), y el ordenador emite
un mensaje de error si le pedimos que halle el código ASCII de algo que no existe.
La línea 60 escribe codigoS si el código del carácter es mayor que 64 y menor que
91, o sea, si representa una letra mayúscula.
Podemos utilizar los códigos ASCII para escribir un sencillo programa codifica-
dor/decodificador:

10 PRINT
20 INPUT "Cual es el codigo";desplazamiento
30 PRINT
40 LINE INPUT "Cual es el mensaje? ",mensaje$
50 longitud=LEN(mensajeí)
60 mensajecodificado$=""
70 FOR cuenta=l TQ longitud
80 letra$=MID$(mensaje$,cuenta, 1)
90 1etraascii=ASC (1etra$)
100 letraeodifi cada$=CHR$(1etraasci i +desplazamie
nto)
110 mensaj ecodi fi cado$=mensajecodi f i cado$+letrac
odi-Ficada$
120 NEXT
130 PRINT
140 PRINT"E1 mensaje codificado es: "
150 PEN 3
Cadenas literales 111

160 PRINT
170 PRINT mensajecodificadol
180 PEN 1

Responda a la primera pregunta con un número igual o menor que 120. El ordena­
dor capta el mensaje en la línea 40. El bucle de las líneas 70 a 120 toma una a una
las letras del mensaje y suma a su código ASCII el valor de ‘desplazamiento’ para
obtener otro código ASCII. La línea 100 convierte este código en un carácter, y la
línea 110 coloca el carácter al final de la cadena ‘mensajecodificadoS ’.
Al principio del programa no hemos puesto la habitual instrucción de modo de
pantalla. De esta manera, al no borrarse la pantalla, usted puede decodificar un
mensaje sin tener que recordar la versión codificada. Copie el mensaje codificado
con la tecla <COPY> al responder a línea 40. Para decodificar correctamente un
mensaje, hay que utilizar el mismo valor de ‘desplazamiento’ con que fue codifica­
do, pero cambiado de signo. Por ejemplo, si codificó su mensaje con 23, decodifí-
quelo con -23.

Las funciones VAL y STR$

En ocasiones interesa tratar los números como si fuesen cadenas literales. Un caso
típico es el de las fechas. Sin embargo, en algún lugar del programa podremos nece­
sitar esos números en algún cálculo, y ya sabemos que el Amstrad se niega rotunda­
mente a realizar operaciones aritméticas con cadenas literales. Así pues, tenemos
que aprender a convertir números de su forma normal a forma literal, y viceversa.
La función VAL convierte una cadena en un número:

10 MODE 1
20 INPUT "Escriba lo que quiera, pero empezando
con un numero: ",caracter$
30 numero=VAL(carácter!)
40 F'RINT "El numero era"; numero

VAL empieza con examinar el primer carácter de la cadena. Si no es una cifra, ya


no comprueba más caracteres y genera el número 0. Esto es lo que ocurre si se escri­
be ‘Junio 6’ en respuesta a la línea 20 del programa anterior. No obstante, podría­
mos extraer el número ‘6’ con el siguiente programa:

10 MODE 1
20 INPUT "Introduzca una -fecha (por ejemplo, 6 d
e junio): ", fecha!
30 continuará
40 posicion=l
50 WHILE continuar3!
60 letra$-MID$(fecha!,posición, 1)
70 codiqo=ASC(1etra!)
112 Programación BASIC con Amstrad

80 IF codigo>47 AND codigo<58 THEN continuar=0 E


LSE posicion=posicion+1
90 WEND
100 numero*=MID$ (fecha*, posi c i on)
110 numero=VAL(numero*)
120 PEN 3
130 PRINT "El dia era el";numero

El programa examina una a una las letras de la cadena hasta que encuentra un códi­
go que representa una cifra (línea 80). La línea 100 extrae entonces la subcadena
en la que está el número; la línea 110 la convierte con VAL.
STR$ realiza la función inversa: convierte un número en su forma literal:

10 MODE 1
20 INPUT "Escriba la -fecha actual (en la forma
31/6/83): ",fecha$
21 REM convertir dia y mes a números
30 dia=VAL (-f echa*)
40 posicionmes=INSTR (-fecha*, "/")
50 mes$=MID$(fecha*,posicionmes+1)
60 mes=VAL(mes*)
70 posici onano=INSTR(posicionmes+1,fecha*,"/")
80 ano$=MID$ (-fecha*, posi c i onano+1)
81 REM averiguar el nombre del mes
90 FOR cuenta=l TO mes
100 READ nómbrenles*, numerodedi as
110 NEXT
111 REM averiguar la fecha de la semana siguient
e
120 dia=dia+7
121 REM si este numero es mayor que el numero de
dias del mes, pasar al mes siguiente
130 IF dia>numerodedias THEN dia=dia-numerodedi a
s:READ nombremes*,numerodedias
135 READ ind$:IF ind$="XXX" THEN ano$=MID$(STR$(
VAL(ano$)+l),2)
140 dentrodeunasemana*=STR*(dia)+" de "+nombreme
s$+" de 19"+ano$
150 PRINT
160 PRINT"Dentro de una semana la fecha sera: "
170 PEN 3
180 PRINT dentrodeunasemana*
190 PEN 1
200 DATA Enero,31,Febrero,28,Marzo,31,Abri 1,30,M
ayo,31,Juni o,30
,210 DATA Juli o,31,Agosto,31,Setiembre,30,Octubre
,31,Novi embre,30,Diciembre,31,Enero,31,XXX
Cadenas literales 113

Este programa toma la fecha actual y calcula la de una semana más tarde. Tanto
el día como el mes tienen que estar en forma numérica: el día, para poder hacer cál­
culos con él; el mes, para saber cuántos datos hay que leer en el bucle de las líneas
90 a 120. La línea 140 convierte la variable numérica ‘dia’ en variable literal.
Aunque en este momento no le parezca demasiado interesante esto de convertir
variables numéricas en variables literales, y viceversa, vale la pena que estudie la téc­
nica de extracción de valores numéricos contenidos en una cadena. La conversión
de números en cadenas literales para luego concatenar las cadenas es una forma sen­
cilla de agrupar datos interrelacionados sin tener que describirlos individualmente.
Los números originales se pueden recuperar fácilmente utilizando MID$ para ex­
traer la parte de la cadena que se desee.

Ejercicios

1. Escriba un programa que capte números por el teclado y rechace todo lo demás.
2. Un defecto del programa que calcula la fecha de dentro de una semana es que
no tiene en cuenta los años bisiestos. Los años son bisiestos si son divisibles por
4, con la excepción de los años en que cambia el siglo (1700, 1800, etc.), que sólo
son bisiestos si son divisibles por 400. Modifique el programa para que asigne
a febrero el número de días correcto.
3. Escriba un programa que calcule cuántos días laborables quedan desde hoy hasta
el día de Navidad.
4. Otro del mismo estilo. Escriba un programa que calcule cuántos días ha vivido
el usuario, después de preguntarle la fecha de nacimiento y la fecha actual.
7

Bucles y listas

BUCLES ANIDADOS

En un ejemplo del capítulo anterior utilizábamos dos bucles, un bucle dentro del
otro. Los bucles anidados son interesantes porque permiten simplificar los progra­
mas. Veamos un sencillo ejemplo que ilustra la naturaleza de los bucles anidados:

10 MODE 1
20 FOR buc 1 ee:; ter i or = 1 TO 3
30 FEN 3
40 PRINT "El bucle exterior es";buc1eexter i or
50 FOR bucleinterior=l TO 4
60 PEN 2
70 PRINT "El bucle interior es";buc1einteri or
80 NEXT
90 NEXT
100 PEN 1

La salida del programa es la que se muestra en la figura 25.

El bucl a ex tari or GS 1
El bucl e i nteri or es 1
El bucle interi or es n
El buc 1 e i nter i or- es "T
El bucl e interior es 4
El bucle ex ter i or es
El bucle i nter i or es 1
El bucle i nteri or es r»
El bucle i nter i or es T
El bucle i nter i or es /i
El bucle ex ter i or- es T
El bucle interi or­ es 1
El bucle interi or­ es n
El . bucle interi or es T
El bucle i nter i or es 4

Figura 25. Salida del programa de bucles anidados.

114
Bucles y listas 115

Cuando se ejecuta el programa, el ordenador abre el bucle exterior (línea 20) y


describe el valor de su variable de control, que inicialmente es 1 (línea 40). El bucle
interior comienza en la línea 50, antes de que el programa haya salido del exterior,
pues no ha llegado al correspondiente NEXT. La línea 70 escribe el valor de la va­
riable de control del bucle interior, que es 1 en la primera pasada.
En la línea 80 aparece la primera sentencia NEXT. Tal como está organizado el
lenguaje BASIC, este NEXT no corresponde al primer FOR, sino al segundo, o sea,
al bucle interior. Así pues, el ordenador continúa recorriendo el bucle interior hasta
que su variable de control alcanza el límite superior especificado en la línea 50.
Cuando completa el bucle interior, pasa a la siguiente instrucción, la de la línea 90,
que es otro NEXT. Esta sentencia NEXT tiene que corresponder al último FOR
que no haya sido todavía emparejado con un NEXT; en otras palabras, el NEXT
de la línea 90 señala el final del bucle abierto en la línea 20.
Al llegar por primera vez a la línea 90, el ordenador vuelve a la línea 20 para reali­
zar la segunda pasada por el bucle exterior, escribe el número 2 (línea 40) y entra
otra vez en el bucle interior, escribiendo por segunda vez los números 1, 2, 3 y 4.
Y así sucesivamente.
La razón por la que estos bucles se denominan “bucles anidados” se evidencia
en la figura 26.

Figura 26. Bucles anidados.

Pasemos a un ejemplo más práctico, extraordinariamente corto, que no obstante


escribe las tablas de multiplicar completas:
116 Programación BASIC con Amstrad

10 MODE 1
20 FOR tabla=l TO 10
30 PEN 3
40 PRINT "tabla de multiplicar del";tabla
50 PRINT
60 PEN 2
70 FOR numero=l TO 10
80 PRINT numero;"por";tabla;"es" ;numero*tabla
90 NEXT
100 PRINT
110 NEXT
120 PEN 1

Si no fuera por los bucles anidados, este programa habría sido mucho más largo,
pues habríamos necesitado 10 bucles independientes para conseguir el mismo efecto.
Las tablas pasan por la pantalla a velocidad excesiva; introduzca una línea con una
instrucción INPUT que pregunte al usuario si ha terminado de observar una tabla
y quiere ver la siguiente.
El siguiente programa dibuja una serie de rectángulos que llena la pantalla:

10 MODE 1
20 FOR coordenadax=0 TO 500 STEP 100
30 FOR coordenaday=0 TO 330 STEP 50
40 MOVE coordenada*,coordenaday
50 DRAW coordenadax+90,coordenaday+10
60 DRAW coordenadax+40,coordenaday+40
70 DRAW coordenada*,coordenaday
80 NEXT
90 NEXT

El valor del paso (STEP) y las coordenadas son arbitrarios. Experimente con otros
valores.
En el capítulo 3 desarrollamos un programa que dibuja una casa. Reduciendo
el tamaño de la casa y utilizando un bucle podemos dibujar una calle entera:

10 MODE 1
20 REM coordenadas de la -fachada
30 FOR casaízquierda=0 TO 500 STEP 100
40 casaabajo=200
50 casaderecha=casaizquierda+90
60 casaarriba=250
70 REM dibujar la fachada
80 MOVE casaizquierda,casaabajo
90 DRAW casaderecha,casaabajo
100 DRAW casaderecha,casaarriba
110 DRAW casaizquierda,casaarriba
Bucles y listas 117

120 DRAW casaizquierda,casaabajo


130 REM coordenadas del tejado
140 tejadoizquierda=casaizquierda+15
150 tejadoarriba=270
160 tej adoderecha=casaiz qui erda+75
170 REM dibujar el tejado
180 MOVE casaizquierda,casaarriba
190 DRAW tejadoizquierda,tejadoarriba
200 DRAW tejadaderecha,tejadoarriba
210 DRAW casaderecha,casaarriba
220 NEXT

Un programa del capítulo anterior codificaba los mensajes que le entregábamos.


Basándonos en esa idea hemos escrito un programa que propone una serie de 10
mensajes codificados y pide al usuario que los descifre lo más deprisa posible:

10 MODE 1
20 arranque=TIME
30 FOR clave=l TO 10
40 READ palabra*
50 elave$=palabra*
60 . 1ongitud=LEN(pal abra*)
70 FOR lio=l TO longitud
80 aleat=INT(RND*1ongitud+1 )
90 der=longitud-aleat
100 el ave*=LEFT*(el ave*,aleat-1)+RIGHT*(clave*,d
er)+MID*(el ave*,aleat,1)
110 NEXT
120 PEN 1
130 PRINT:PRINT "La clave es ";
140 PEN 3
150 PRINT clave*
160 PEN 2
170 PRINT:INPUT "Cual es la pal abra";adiv*
180 PRINT
190 IF adiv*=palabra* THEN PEN 3:PRINT"Bien !" EL
SE PEN 1: PRINT"Fal so, es "¡¡palabra*
200 NEXT
210 total =TIME--arranque
220 PRINT"Ha tardado";total/300;"segundos."
230 DATA 1 isto,enorme,canguro,medusa,mobi 1 iari o
240 DATA electricidad,ventana,poliestireno,embud
o,macarrones

De ios dos bucles de este programa, el exterior hace las preguntas y el interior revuel­
ve las letras para generar los mensajes codificados. Podemos cambiar el tipo de bu-
118 Programación BASIC con Amstrad

ele; el exterior lo haremos del tipo WHILE para facilitar el control del tiempo.
Añada las siguientes líneas:

11 limite=100
12 PRINT "Dispones de ";1 i mi te;"segundos para de
scifrar 10 claves."
13 segundos=0
14 correcto=l
15 cuentapalabras=0
31 cuentapalabras=cuentapalabras+1
190 IF ad iv$=palabra$ THEN correcto=correcto+1 :P
EN 3:PRINT"Bien !" ELSE PEN 1 :PRINT"Falso, es
"; palabraí
191 ti empoahora=TIME--arranque
192 segundos=tiempoahora/300
193 PRINT:PRINT"L1evas consumi dos";segundos; "seg
undos."
225 IF correcto>l THEN PRINT"Tienes"; correcto;"b
ien." ELSE PRINT"No acertaste ni una!"

También podemos hacer que los dos bucles anidados sean del tipo WHILE:

10-MODE 1
20 READ pregunta!,respuestacorrectal
30 WHILE preguntaíí>"XXX"
50 PEN 3
60 PRINT:PRINT pregunta!
70 PEN 2
80 respuesta!-'"
90 intentos=l
100 WHILE respuesta!Orespuestacorrecta! AND int
entos<4
110 LINE INPUT respuesta!
120 intentos=intentos+1
130 IF respuesta!<>respuestacorrecta! AND intent
os<4 THEN PRINT"No. Inténtalo otra vez."
140 WEND
150 IF respuestalOrespuestacorrecta! THEN PRINT
"La respuesta era: ";respuestacorrectaí
160 READ pregunta!,respuestacorrectaí
170 WEND
180 PEN 1
190 DATA Cuantos dias tiene mayo?,31
200 DATA Cual es la capital del Reino Unido?,Lon
dres
210 DATA Quien gano el ultimo premi o individual
Bucles y listas 119

masculino de Wimbledon?,John McEnroe


220 DATA Que país gano la ultima copa del mundo
de -f utbol ?, Ital i a
500 DATA XXX,YYY

En este caso, el primer bucle WHILE, que va de la línea 30 a la 170, formula pregun­
tas hasta que el dato leído es el terminador ‘XXX’. El bucle interno da tres oportu­
nidades para cada pregunta. La principal ventaja de utilizar un WHILE en lugar
de un FOR ... NEXT en el bucle externo es que de esta manera podemos aumentar
el número de preguntas sin más que modificar los datos y sin tener que cambiar nin­
guna otra línea del programa (y cuidando que los nuevos datos estén en líneas de
número inferior a 500). Si el bucle fuera del tipo FOR ... NEXT, tendríamos que
modificar el valor del estremo superior de la variable de control cada vez que añadié­
semos una nueva pregunta.

Ejercicios

1. Dibuje un rectángulo formado enteramente por asteriscos utilizando un par


de bucles anidados. (El mismo efecto se puede conseguir con STRINGS y un
bucle sencillo; pero practique con los bucles anidados.)
2. Escriba un asterisco en todas las posiciones de texto que tengan impar al me­
nos una de sus coordenadas: (1,1), (1,3), (1,5), ... , (3,1), (3,3), ....
3. Escriba un programa que lea los nombres de una serie de alumnos y sus no­
tas en doce exámenes y que escriba toda esta información en la pantalla, jun­
to con las notas medias. Utilice dos bucles anidados: el externo para reco­
rrer todos los alumnos, y el segundo para leer las doce notas de cada
alumno.
4. Amplié el programa que dibuja una fila de casas para que dibuje varias filas
de colores distintos. Ponga puertas y ventanas en las casas.
5. Escriba un programa que dibuje un edificio de 3 plantas, con 5 ventanas por
planta. Todas las ventanas deben ser del mismo tamaño.

LISTAS

Los dos últimos programas de la sección anterior tenían el mismo defecto: cada vez
que se ejecuta el programa éste formula las mismas preguntas. Si intentamos resol­
ver este problema leyendo cada vez un número aleatorio de preguntas, creamos otro
nuevo: cómo garantizar que no repetimos ninguna pregunta.
En uno de los ejercicios del final de la sección anterior le pedíamos que escribiese
un programa para leer los nombres y las notas de una serie de alumnos y escribirlos
en la pantalla. En programa más cercano a la realidad, esta información tendría
que ser utilizada más tarde para otros fines; por ejemplo, para elaborar una lista
de los nombres ordenada de mayor a menor nota en Matemáticas. También podría­
mos necesitar repetir esta operación para las 11 asignaturas restantes. Ahora bien,
120 Programación BASIC con Amstrad

para ordenar las notas, el programa necesita conocer todas la de una asignatura al
mismo tiempo.
Todo esto sugiere la necesidad de que el ordenador pueda manejar listas de datos,
de forma que pueda comparar unos con otros. Con nuestros conocimientos actua­
les, esta tarea es enormemente tediosa, cuando no imposible. Supongamos que te­
nemos quince alumnos y que tenemos que ordenarlos según sus notas de Matemáti­
cas. El ordenador necesita conocer simultáneamente las quince notas para poder
compararlas y ordenarlas. La primera parte del programa tendría que leer los nom­
bres y las notas:

10 MODE 1
20 READ nombrelt,notai
30 READ nombre2$, nota2
40 READ nombre3$,nota3
50 READ nombre4$,nota4
60 READ nombre5$, n'otaS
70 READ nombreót,notaó
80 READ nombre7$,nota7
90 READ nombreBt,notaS
100 READ nombre9$,nota9
110 READ nombre10$,nota10
120 READ nombrel1$,notai 1
130 READ nombre12$,nota12

y así sucesivamente, y ni siquiera hemos empezado a comparar notas. ¿Se imagina


qué habría que hacer si los alumnos fueran 100? Este método es impracticable.
En lugar de guardar cada dato en una variable, lo que necesitamos es una variable
de un tipo especial, una lista, que contenga todos los datos:

10 MODE 1
20 DIM nombret(15),nota(15)
30 FOR cuenta=l TO 15
40 READ nombret(cuenta),nota(cuenta)
50 NEXT
400 DATA Alvarez,4,0,Beni to,5.6,Cuesta,7.7,Diegu
ez,2,Martin,8/4
410 DATA Fernandez,4.5,Garcia,9,Hernandez,3,Medi
na,9.5,Nieto,9.5
420 DATA Ruiz,0,Sanchez,5.5,Tomas,6,Victor,4.5,Z
acarias,8

La línea 20 informa al ordenador de cuántos elementos va a haber en cada lista: 15.


La palabra clave de BASIC, DIM, dimensiona las listas. Observe que las listas pue­
den ser literales, nombre$( ), o numéricas, nota( ). El bucle de las líneas 30 a 50
lee los datos y los guarda en las dos listas. El número que figura entre paréntesis
en la línea 40 es lo que se denomina subíndice. El subíndice varía al mismo tiempo
Bucles y listas 121

Figura 27. Almacenamiento de datos en listas.


122 Programación BASIC con Amstrad

que la variable de control del bucle. El resultado final es que, cuando el bucle termi­
na, todos los datos han quedado guardados en las listas, según se muestra en la
figura 27.
Ahora podemos acceder a los diferentes elementos de la lista mencionándolos por
su subíndice. Después de ejecutar el programa, pruebe la siguiente orden en modo
directo:

nombre$(15)

El ordenador escribe ‘Zacarías’, que es el decimoquinto elemento de la lista


‘nombreS’. Escriba

nota(5)

El ordenador escribe ‘8.4’, que es la nota del alumno número 5. Una vez guardados
los datos en las listas, podemos hacer que el ordenador los manipule a nuestro anto­
jo sin tener que volver a leerlos en las líneas de DATA. Añada las siguientes líneas
al programa:

2 MODE 1
60 PRINT "Voy a escribir los nombres de los
alumnos que tienen nota inferior a la que u
sted indi que."
70 PRINT
80 INPUT "Cual es la nota tope";notatope
90 PEN 3'
100 PRINT:PRINT "Alumnos con nota menor que";not
atope
110 PRINTsPRINT "Nombre","nota"
120 PEN 2
130 FOR cuenta=l TO 15
140 IF nota(cuenta)(notatope THEN PRINT nombret(
cuenta),nota(cuenta)
150 NEXT
160 PEN 1

Al recorrer 15 veces el bucle de las líneas 130 a 150, el programa examina las notas
de todos los alumnos y excribe el nombre y la nota de aquéllos cuya nota no alcanza
el valor especificado. La línea 140 demuestra lo fácil que es conectar una lista con
otra. Por ejemplo, nombre$(14) es el nombre del 14 alumno; para averiguar su nota
no tenemos más que consultar nota(14). Los componentes individuales de la lista,
tales como nombre$(14) o nota(5), son sus elementos.
Aparte la necesidad de mencionar un subíndice, por todo lo demás el ordenador
trata los elementos de las listas como si fueran variables ordinarias (numéricas o lite­
rales, según el caso). Pruebe, por ejemplo, las siguentes órdenes directas:
Bucles y listas 123

7LEPT*(nombre*(11),2)
?notci (7) +nota (12)
?nombre*(1)+nombre*(6)

Los elementos de las listas no se distinguen de las variables ordinarias más que en
la inclusión del subíndice.
Hemos utilizado listas para guardar datos en ellas. Pero también nos pueden ser­
vir para almacenar resultados. En un programa anterior simulábamos el lanzamien­
to de dos dados generando números aleatorios. Ahora ya podemos almacenar el
resultado de cada lanzamiento en los elementos de una lista, para luego utilizarlos
según nos interese:

10 MODE 1
20 WINDOW 1,40,1,1
30 WINDOW #1,1,40,2,25
40 INPUT "Cuantas ti radas";tiradas
50 DIM resultado(12)
60 FOR totaldados=2 TO 12
70 LOCATE#!,1,totaldados*2
80 PRINT#!,totaldados
90 NEXT
100 POR cuenta=l TO tiradas
110 dadol=INT(RND*6+1)
120 dado2=INT(RND*6+1)
130 total=dadol+dado2
140 resultado(total)=resultado(total)+l
150 LOCATE#1,4,total*2
160 PRINT#!,resultado(total)
170 NEXT

Siempre que se dimensiona una lista, como en la línea 50 de este programa, los
elementos de la lista se igualan a cero (o a la cadena vacía si la lista es literal). Lo
que hemos hecho en esa línea es preparar 13 cajas vacías, en las que más tarde pon­
dremos los valores a medida que los vayamos generando. (Hay dos cajas que no
vamos a utilizar, resultado(0) y resultado(l), porque al lanzar dos dados el resultado
no puede ser menor que 2.)
Las líneas 60 a 90 escriben los números del 2 al 12, convenientemente espaciados
para facilitar la visualización de los resultados.
Cada vez que lanzamos los dados, las líneas 110 a 130 generan los resultados de
la tirada; la línea 140 actualiza el valor del elemento correspondiente de la lista ‘re-
sultado( )’. La línea 160 escribe el nuevo valor del elemento de la lista en la posi­
ción de la pantalla que le corresponde. Si esta forma de visualización le parece “so­
sa”, modifique la línea 160:

160 PRINTttl,STRING*(resultada(total ),"*")


124 Programación BASIC con Amstrad

Esta línea escribe una cadena de asteriscos cuya longitud es igual al número de veces
que ha aparecido el resultado. El programa es más atractivo si visualizamos la dis­
tribución de los resultados con barras rectangulares, para lo cual necesitamos ins­
trucciones de dibujo:

100 FOR cuenta=l TO tiradas


110 dadol=INT(RND*6+1 )
120 dado2=INT(RND*6+1)
130 total=dado1+dado2
140 resultado(total)=resultado(total)+1
141 graf y= (24-total *2) *16
142 grafx=50
143 MOVE grafx+resultado(total)*2,grafy
144 DRAW grafx+resultado(total)*2,grafy+16
170 NEXT

Cada vez que se genera un resultado, las líneas 143 y 144 dibujan una nueva barra.
Así, el diagrama va creciendo hacia la derecha a medida que avanza el programa.
Dado que la resolución gráfica en el eje vertical es independiente del modo de pan­
talla, podemos hacer el diagrama mucho más atractivo dibujando las barras en dis­
tintos colores. Cambie las siguientes líneas:

10 MODE 0
142 grafx=150
143 MOVE grafx+resultado(total)*2,grafy
144 DRAW grafx+resultado(total)*2,grafy+16,total

Cada barra tiene ahora su propio color. Hemos tenido que mover la coordenada
‘grafx’ hacia la derecha, porque en modo 0 los números que hemos escrito junto
al margen izquierdo son más anchos.
Vamos a visitar a nuestro viejo amigo, el propietario del restaurante, para ver có­
mo van sus intentos de informatizar el negocio. Gracias a las listas, ahora ya le es
más fácil calcular las facturas. Lo primero que debe hacer es formar listas con los
nombres de los artículos y los precios:

10 MODE 1
20 numerogeneros=12
30 DIM nombregeneroí(numerogeneros),precio(numer
□géneros)
40 FOR cuenta=l TO numerogeneros
50 READ nombregenerot(cuenta),precio(cuenta)
60 NEXT
400 DATA patatas p,50,patatas m,60,patatas g,70,
bacalao p,90,bacalao m,110,bacalao g,130
410 DATA salchicha,40,f1an,70,musí o pollo,140,ha
mburguesa,100,pastel,60,perrito cal,50
Bucles y listas 125

Observe que en la línea 30 hemos utilizado una variable para especificar el tamaño
de las listas. En BASIC, todos los números se pueden sustituir por variables, a ex­
cepción de los números de línea.
Una vez leídos los datos, el propietario del restaurante puede dejar el ordenador
funcionando en un bucle infinito. El programa es suficientemente complejo como
para que valga la pena planificarlo. Necesitamos 3 bucles del tipo WHILE
anidados:
WHILE (mientras) el restaurante esté abierto
preguntar el nombre del primer artículo de la factura
WHILE (mientras) el artículo sea distinto de ‘XXX’
buscar el precio del artículo
WHILE (mientras) queden elementos por examinar en la lista
continuar examinándola
If (si) se encuentra el artículo THEN (entonces) calcular el importe
WEND
IF (si) no se encuentra el artículo THEN (entonces) informar al cajero
preguntar el nombre del siguiente artículo
WEND
escribir el importe total de la factura
WEND
Este plan no es exactamente un programa, sino un ordinograma que conduce al si­
guiente programa:

10. MODE 1
20 numenogeneros=12
30 DIM nombregeneroí(numerogeneros)?precio(numen
ogeneros)
40 FOR cuenta=l TO numenogeneros
50 READ nombregeneroí(cuenta),precio(cuenta)
60 NEXT
61 REM preparar ventanas para entradas y factura
70 WINDDW 1,40,21,25
80 WINDOW #1,1,40,1,20
81 REM primer bucle - sin -fin
90 continuar=l
100 WHILE continuar=l
110 CLS
120 PEN 1
130 F'RINT "Para terminar la -factura introduzca X
XX como nombre del articulo."
140 F'RINT
160 INPUT "Introduzca el nombre del articulo y
luego el numero de raciones: ",genero$,ra
c i ones
170 CLS#1
180 PEN #1,3
126 Programación BASIC con Amstrad

190 PRINT #1,"Articulo","Raciones", “Precia"


200 PRINT #1
201 REM segundo bucle - para procesar cada artic
ul o
210 WHILE genero$<>"XXX"
220 cuenta=l
230 hallado=0
231 REM buscar precio del articulo mientras no 1
o hayamos encontrado y todavia queden articu
los en la lista
240 WHILE cuentaOnumerogeneros AND hallado=0
250 IF genero$=nombregenero$(cuenta) THEN precio
=raciones*precio(cuenta):PRINT #1,nombregene
roí(cuenta),raci ones,preci o:preci ototal=prec
iototal+precio:hallado=l
260 cuenta=cuenta+l
270 WEND
271 REM pedir nueva introducción del articulo si
no lo hemos encontrado
280 IF cuentaínumerogeneros AND hallado=0 THEN P
EN 2:PRINT"F'or -favor, escriba otra vez los d
atos.":PEN 1
290 INF'UT "Introduzca el nombre del articulo y
luego el numero de raciones: ",generoí,ra
clones •
300 WEND
301 REM calcular importe total con impuestos
310 PEN #1,2
320 PRINT #1,"Precio totalpreci ototal
330 PRINT #1,"Impuestos:",,0.12*preciototal
340 PRINT #1,"Precio con impuestos:",preciototal
*1. 12
341 REM empezar factura siguiente
350 WEND
400 DATA patatas p,50,patatas m,60,patatas g,70,
bacalao p,90,bacalao m,110,bacalao g,130
410 DATA salchicha, 40,-flan, 70, muslo pollo,140,ha
mburguesa,100,pastel,60,perrito cal,50

Este programa constituye un buen ejemplo de utilización de bucles anidados y listas.


Hay un detalle que dificulta su utilización y lo hace más complicado: el usuario debe
escribir el nombre de los artículos tal como éstos están en la lista de nombres, ya
que el ordenador compara el nombre introducido con los elementos de la lista para
localizar los artículos. El programa es mucho más sencillo si el cajero introduce el
número del artículo en lugar del nombre.
Por ejemplo, ‘patatas p’ sería el número 1, y así salchicha’ el número 7. Borre las
líneas 160 y 210-350 y sustitúyalas por las siguientes:
Bucles y listas 127

160 INF'UT "Introduzca el numero del articulo y


luego el numero de raciones: ",genero,rae
i ones
210 WHILE genero< >-99
220 IF genero<>-99 AND genero<=numerogeneros THE
N precio-raciones*precio(genero):PRINT #l,no
mbregenero$(genero),rae i ones,preci o:preci oto
tal=preci ototal+preci o
230 IF genero>numerogeneros THEN PEN 2:F'RINT"Dem
asiado grande para ser el numero de un a
rticulo.":PRINT"Escri bal o otra vez." :PEN 1
240 INF'UT "Introduzca el numero del articulo y
luego el numero de raciones: ",genero,rae
i ones
250 WEND
260 PEN #1,2
270 PRINT #1,"Precio totalpreciototal
2S0 PRINT #1,"Impuestos:", 0.12*preciototal
290 PRINT #1,"Precio con impuestos:",preci ototal
*1. 12
300 WEND

Ahora se utiliza el número del artículo para buscar directamente su nombre y su pre­
cio unitario, con lo que se evita el engorro de tener que recorrer la lista en busca
del nombre. Aun más sencillo sería prescindir de los nombres e ir directamente a
los precios, pero entonces la factura final no es tan clara para el cliente y es más
difícil detectar errores en ella.
Recomendamos al lector que estudie atentamente este programa, aunque no tenga
interés práctico para él. La técnica de búsqueda de un elemento en una lista es de
interés general, como tendremos ocasión de comprobar más adelante, en el capítulo
que trata de ficheros.

Ejercicios

1. Modifique el programa codificador de mensajes para que haga lo siguiente: debe


leer las palabras que van a ser codificadas y asignarlas a los elementos de una
lista; la palabra que va a ser propuesta al jugador debe ser elegida aleatoriamente
de entre los elementos de la lista. Si se siente capaz, trate de mejorar el programa
para que no repita ninguna pregunta.
2. Escriba un programa que empiece por leer los nombres y números de teléfono
de un grupo de amigos y los almacene en dos listas. El programa debe solicitar
por el teclado el nombre de un amigo, buscar el número de teléfono y escribirlo
en la pantalla, o bien emitir un mensaje adecuado si no encuentra el nombre en
la lista.
128 Programación BASIC con Amstrad

3. Escriba un programa que simule el lanzamiento de una moneda generando núme­


ros aleatorios (que sólo podrán tener dos valores; por ejemplo, 1 y 2). Si el núme­
ro es 1, considere que el resultado es “cara”; si es 2, “cruz”. Vi­
sualice los resultados en la pantalla escribiendo ‘C’ o ‘X’ para representar “ca­
ra” y “cruz”, o bien dibujando un diagrama de barras.
4. Forme dos listas, una con nombres y otra con verbos, y genere frases aleatorias
con la estructura “NOMBRE VERBO NOMBRE”; por ejemplo, “Los leones
comen cebras”. El programa se puede complicar considerablemente si se preten­
de manejar correctamente el género y número en los nombres y la persona en los
verbos.
5. Si es realmente ambicioso, trate de diseñar algún generador aleatorio de rimas.
8

Juegos y gráficos

CARACTERES A LA CARTA

En el capítulo 6 hablamos del juego de caracteres del Amstrad. Aunque son muchos
y están bien pensados, obviamente no pueden satisfacer todas las necesidades. Afortuna­
damente, el Basic del Amstrad ofrece una instrucción con la que se puede diseñar
caracteres nuevos; la palabra clave es SYMBOL.
Todos los caracteres están basados en una retícula de 8 x 8 puntos. Para diseñar
uno nuevo, lo primero que tenemos que hacer es sombrear en una hoja de papel cua­
driculado los cuadraditos necesarios para lograr el efecto deseado. En la figura 28
se muestra el diseño de un extraterrestre con tentáculos.

'/Z/7'

^/// 'Z/^
ZZ/
V/
77/

y/// Z/'
vv //Z/
Z// ^Z/y z//
//'/y
//
^// Z^Z/,
Z// ZZ/
ZZ/
¿z
Figura 28. Diseño de un carácter para juegos.

Cada fila del carácter se describe mediante un número. Es costumbre utilizar en


estos casos los números hexadecimales o los binarios; estos sistemas de numeración
están descritos en el apéndice II del Manual del Usuario. Por si el lector no estuvie­
ra familiarizado con ellos, vamos a arreglárnoslas con los conocidos números
decimales.
Los números que describen las filas del carácter se calculan de la siguiente forma:
el número es inicialmente cero; se recorren los puntos de la fila; por cada uno que

129
130 Programación BASIC con Amstrad

esté sombreado, se suma el número que está en la cabecera de la columna correspon­


diente; si un punto no está sombreado, no se suma nada. Por este método se han
calculado los números de la figura 29. Por ejemplo, en la primera fila, están som­
breados los puntos de las columnas “16” y “8”; por consiguiente, el número para
esta fila es 16+8=24. Y análogamente para las restantes filas.

Figura 29. El extraterrestre con tentáculos, codificado.

Una vez calculados los ocho números, podemos definir el carácter y utilizarlo en
los programas:

10 MODE 1
20 SYMBOL 240,24,60,126,219,255,255,165,165

La línea 20 realiza la definición del carácter. El primer número que se pone después
de la palabra clave SYMBOL es el código ASCII del carácter que vamos a definir;
en este caso, 240. Escriba:

?CHR$(240)

y compruebe que la definición sigue en vigor incluso después de terminar el progra­


ma. Según el apéndice III del Manual del Usuario, el carácter 240 es inicialmente
una flecha que apunta hacia arriba, pero nosotros lo hemos redefinido. El Amstrad
permite diseñar por este método, sin más preparativos, los caracteres del 240 al 255.
Si queremos definir otros caracteres de fuera de ese margen, necesitamos otra ins­
trucción. Por ejemplo,

SYMBOL AFTER 60
Juegos y gráficos 131

permite definir cualquier carácter cuyo código ASCII sea igual o mayor que 60.
(Symbol after significa “símbolo después de”; pero observe que no sólo podemos
definir los caracteres posteriores al 60, sino también el 60.) Después de ejecutar esta
orden SYMBOL AFTER, podemos rediseñar casi 200 caracteres a nuestro gusto.
SYMBOL AFTER anula las anteriores definiciones de caracteres. Escriba
?CHR$(240) y verá que el carácter 240 es otra vez la flecha original.
Con SYMBOL AFTER 32 podemos redefinir cualquier carácter (incluso el espa­
cio, que es el número 32). La siguiente instrucción cambia el diseño de la letra ‘A’
y le da la forma de nuestro extraterrestre:

SYMBOL 65,24,60,126,219,255,255,165,165

Si usted hace lo mismo con unas cuantas letras, pronto llegará a no entender lo que
escriba en la pantalla. Siempre puede volver a la situación normal ejecutando la or­
den SYMBOL AFTER 240.
En la práctica, los 16 caracteres del margen 240 a 255 son suficientes para la ma­
yor parte de las aplicaciones.
El siguiente programa demuestra con qué facilidad podemos controlar a través
del teclado los movimientos del extraterrestre:

10 MODE 1.
20 PRINT"E1 monstruo se puede guiar utilizando
las teclas ’a’ y ’z’ para moverlo arribay ab
ajo, y las teclas y para moverlo a
izquierda y derecha."
25 PRINT: F'RINT "Pul se ’-f ’ para parar."
30 INF'UT "Pulse ENTER para empezar. ",comienzo$
40 MODE 0
50 SYMBOL 240,24,60,126,219,255,255,165,165
51'REM posición inicial
60 coordx=10
70 coordy“12
80 nuevacoordx=10
90 nuevacoordy=12
100 PEN 6
110 PAPER 1
120 CLS
130 respuesta$=""
140 continuar-1
150 WHILE respuesta$O" f "
151 REM examinar el teclado
160 respuesta$=INKEY$
161 REM actualizar posición del -monstruo - compr
obar que no esta fuera de la pantalla
170 IF respuesta$="a" AND coordy>l THEN nuevacoo
rdy=coordy-l
132 Programación BASIC con Amstrad
180 IF respuesta$="z" AND coordy<25 THEN nuevaco
ordy=coordy+l
190 IF respuesta^-"," AND coordx>l THEN nuevacoo
rdx=coordx-1
200 IF respuesta$="." AND coordx<20 THEN nuevaco
ordx=coordx+l
201 REM si se ha pulsado una tecla de movimiento
, borrar la posición anti qua
210 IF respuesta$<>"" AND respuesta$<>"s" THEN L
□CATE coordx,coordy:PRINT" ":coordx=nuevacoo
rdx:coordy=nuevacoordy
211 REM dibujar monstruo
220 LOCATE coordx,coordy
230 PRINT CHR$(240);
240 WEND
250 PEN 1
260 PAPER 0

Esta rutina forma la base de muchos programas de juegos, como veremos más ade­
lante. Hay un par de detalles que vale la pena observar. Primero, que necesitamos
cerciorarnos, antes de cada movimiento, de que el extraterrestre no se va a salir de
la pantalla. En segundo lugar, tenemos que borrar el carácter de la posición actual
antes de escribirlo en la siguiente. El signo de punto y coma que hemos puesto des­
pués de PRINT CHR$(240) es imprescindible. Si lo omitiésemos, el contenido de
la pantalla se desplazaría hacia arriba cuando el extraterrestre llegase al estremo in­
ferior derecho.
Las teclas que hemos utilizado para controlar el movimiento son las tradicionales
en los juegos de ordenador. Si utilizásemos las teclas del cursor, tendríamos que
jugar con una sola mano. En cambio, de esta manera, podemos dedicar la mano
izquierda al control de los movimientos horizontales con las teclas ‘z’ y ‘x’, y la dere­
cha a los movimientos verticales, teclas y 7’. En cualquier caso, el programa
es muy fácil de modificar si se prefiere, otra combinación de teclas.
Como mencionábamos antes, el carácter 240 es normalmente un flecha que apun­
ta hacia arriba. De hecho, los caracteres 240 a 243 son flechas que apuntan en las
cuatro direcciones. Podríamos modificar el programa para crear cuatro caracteres
que mirasen en las cuatro direcciones, y escribir el apropiado en función de la direc­
ción del movimiento. Por no complicar las cosas, tomaremos los caracteres 240 a
243 y cambiaremos el programa para que elija el carácter adecuado a la dirección
del moviento. (Antes de modificar el programa, ejecute la orden SYMBOL AFTER
240 para anular la anterior definición de este carácter.)

10 MODE 1
50 flecha$=CHR$(240)
170 IF respuesta$="a" AND coordyM THEN nuevacoo
rdy=coordy-l:f1echa$=CHR$(240)
180 IF respuesta$=="z " AND coordy<25 THEN nuevaco
Juegos y gráficos 133

□rdy=coor dy+1 : f 1 echa$=CHR$ (241 )


190 IF respuesta$="," AND coordx>l THEN nuevacoo
rdx =coordx ■ 1 : -f 1 echa$=CHR$ (242)
200 IF respuesta$="." AND coordx<20 THEN nuevaco
ordx=coordx+l : -f 1 echa$=CHR$ (243)
230 PRINT flechas

Caracteres más grandes

Los caracteres aislados pueden resultar demasiado pequeños, pero es muy fácil com­
binarlos para formar otros mayores. Podemos hacer una versión ampliada del ex­
traterrestre de los tentáculos definiendo cuatro caracteres y uniéndolos, como se
muestra en la figura 30.

IBBBBB^'^.BBBI

BB^SíOi8SS^»^BB
BB^-O^!^SSí8?S8»BB
S^S^BBB^^BB^^
^^BB^^SSBB^^SS

WBBS^BBBB^BB^
BB^^BIIBW
^SSBB^SSBB-------------------
BB^^B BS^
WBBS^BB___________
^BB^SSBBBB^SSBB^SS

Figura 30. El extraterrestre, formado por cuatro caracteres.

Al manejar cuatro caracteres, en principio tendríamos que escribirlos en cuatro


posiciones distintas. Una simplificación puede ser combinar los dos caracteres de
la fila superior para formar una cadena literal, y hacer lo mismo con los dos de aba­
jo. De este modo sólo tenemos que ocuparnos de instrucciones LOCATE:

10 MODE 1
20 RRINT"E1 monstruo se puede guiar utilizando
las teclas ’a’ y ’ z ’ para moverlo arribay ab
ajo, y las teclas y para moverlo a
izquierda y derecha. "
25 F’RINT: PRINT"F'ul se ’-f ’ para parar."
30 INPUT "Pulse ENTER para empezarcomienzot
40 MODE 0
41 SYMBOL 240,3,3,15,15,63,63,243,243
42 SYMBOL 241,192,192,240,240,252,252,207,207
134 Programación BASIC con Amstrad

43 SYMBOL 242,255,255,255,255,204,204,204,204
44 SYMBOL 243,255,255,255,255,51,51,51,51
45 arriba$=CHR$(240)+CHR$(241)
46 abajo$=CHR$(242)+CHR$(243)
51 REM posición inicial
60 coordx=10
70 coordy=12
80 nuevdCüord:-:= 10
90 nuevacoordy=12
100 PEN 6
110 PAPER 1
120 CLS
130 respuesta$=""
140 continuará
150 WHILE respuestat í >"f "
151 REM examinar el teclado
160 respuesta$=INKEY$
161 REM actualizar posición del monstruo - compr
obar que no esta fuera de la pantalla
170 IF respuesta$="a" AND coordy>1 THEN nuevacoo
rdy=coordy-l
180 IF respuesta$="z" AND coordy<24 THEN nuevaco
or dy=.coor dy +1
190 IF respuesta$="," AND coordx >1 THEN nuevacoo
rdx=coordx-l
200 IF respuesta$=". " AND coordx<19 THEN nuevaco
□rdx=coord>: + l
201 REM si se ha pulsado una tecla de movimiento
, borrar la posición antigua
210 IF respuesta^ >"" AND respuesta$O"s" THEN L
OCATE coordx,coordy:PRINT" "¡LOCATE coordx ,
coordy+1:PRINT" ":coordx=nuevacoordx:coordy
=nuevacoordy
211 REM dibujar monstruo
220 LOCATE coordx,coordy
230 PRINT arribad;
231 LOCATE coordx,coordy+1
232 PRINT abajo$;
240 WEND
250 PEN 1
260 PAPER 0

En las líneas 180 y 200 hemos simplificado los valores máximos de las coordenadas
de texto. Esto se debe al tamaño del carácter.
Juegos y gráficos 135

Ejercicios

1. Diseñe un carácter y visualícelo en la pantalla con las 16 plumas disponibles en


modo 0.
2. Modifique el programa que mueve las flechas por la pantalla para que permita
el movimiento en diagonal. Defina otros cuatro caracteres y haga que el progra­
ma dibuje el adecuado a cada dirección de movimiento.
3. Diseñe un carácter a su gusto (por ejemplo, un perro o un robot) y escriba un
programa que permita controlar mediante el teclado sus movimientos por la
pantalla.

Rebotes y disparos

Ya disponemos de casi todos los elementos necesarios para programar un juego.


Sabemos cómo definir caracteres y cómo moverlos por la pantalla impidiendo que
se salgan de ella. Pero aún tenemos que aprender algo más. En todos los juegos
en los que hay movimientos por la pantalla, necesitamos poder detectar qué hay al
lado del objeto móvil. Por ejemplo, si vamos a disparar sobre un ejército invasor,
tendremos que saber si hay un enemigo en la trayectoria de nuestros proyectiles. Si
estamos tratando de salir de un laberinto, tenemos que saber detectar las vías libres,
pues el juego pierde todo su sentido si nos permite atravesar las paredes.
Con la función TEST(x,y) podemos detectar con qué pluma se ha dibujado una
posición gráfica de la pantalla. En el programa anterior trabajábamos con coorde­
nadas de texto, pero en el capítulo 3 hemos desarrollado la fórmula que relaciona
las coordenadas de texto con las coordenadas gráficas:
graficosx = (textox - 1) x 32 (ponga 16 para modo 1 y 8 para modo 2)
graficosy = (25 - textoy) X 16
Estas fórmulas dan las coordenadas gráficas del punto extremo inferior izquierdo
del carácter en función de las coordenadas de texto. Las coordenadas gráficas del
centro (aproximado) del carácter serían:
graficosx = 16 + (texto - 1) x 32 (8 y 16 en modo 1; 4 y 8 en modo 2)
graficosy = 8 + (25 - textoy) X 16
Ahora ya podemos averiguar el color que hay en la posición de texto que necesita­
mos comprobar. Veamos un ejemplo que está basado en el programa de movimien­
to de flechas:

10 MODE 1
20 PRINT "Debe llevar la -flecha aí rincón in-feri
orderecho con las teclas ’a’ ’ z ’ lo m
as deprisa posible."
30 PRINT:INPUT "Nivel de habilidad (1-10) (1 es
■fácil; 10 es di-f i ci 1 ) " ; habi 1 i dad
136 Programación BASIC con Amstrad

40 PRINT:INPUT "Pulse ENTER para empezar.",comie


nzo$
50 MODE 0
60 PAPER 1
70 CLS
80 flecha$=CHR$(240)
90 REM posición inicial
100 coordx=l
110 coordy=l
120 REM paredes rojas
130 PEN 3
140 FOR cuenta=l TD habilidad*12
150 aleatx=INT(RND*20+1)
160 aleaty-INT(RND*25+1)
170 LOCATE aleatx,aleaty
180 PRINT CHR$(233);
190 NEXT
200 REM objetivo en color parpadeante
210 PEN 15
220 LOCATE 20,25
221 PRINT "*";
230 PEN 6
240 respuesta$=""
250 REM bucle que continua hasta que se llega a
(20,25)
260 WHILE coordx<>20 OR coordy<>25
270 REM examinar el teclado
280 respuesta$=INKEY$
290 REM poner coordenadas en la posición actual
300 nuevacoordx=coordx
310 nuevacoordy=coordy
320 REM actualizar posición de la -flecha - cpmpr
obar que no esta -fuera de la pantalla
330 IF respuesta$="a" AND coordy>l THEN nuevacoo
rdy=coordy-l: f 1 echa$=CHR$ (240)
340 IF respuesta$="z" AND coordy<25 THEN nuevaco
ordy=coordy+l:f1echa$=CHR$(241)
350 IF respuesta$="," AND coordx>l THEN nuevacoo
rdx=coordx-l: f lecha$=CHR$ (242)
360 IF respuesta$="." AND coordx<20 THEN nuevaco
ordx=coordx + l: -f 1 echa$=CHR$ (243)
370 gra-f x = 16+ (nuevacoordx-1) *32
380 gra-f y=8+ (25-nuevacoordy) *16
390 color=TEST (gra-f x , gra-fy)
400 REM si es una pared, no mover la flecha
Juegos y gráficos 137

410 IF respuestaíí>"" AND color<>3 THEN LOCATE c


oordx,coordy:PRINT" ";:coordx=nuevacoordx:co
□rdy=nuevacoordy
420 REM dibujar flecha
430 LOCATE coordx,coordy
440 PRINT flecha»;
450 WEND
460 PEN 1
470 PAPER 0

El programa dibuja un laberinto que consiste en una serie de obstáculos rojos. El


jugador debe guiar la flecha por entre los obstáculos y llevarla lo más deprisa posible
al rincón inferior derecho de la pantalla. Usted puede variar la dificultad del juego;
el número de obstáculos (líneas 140 a 190) depende del nivel de habilidad (línea 30).
Los obstáculos se dibujan con la pluma número 3. La línea 410 examina el color
de la futura posición de la flecha; si ese color es distinto del de la pluma 3, escribe
la flecha en la nueva posición.
El juego no está todavía completo, pues puede ocurrir que los obstáculos blo­
queen todos los caminos. Esto tiene varias soluciones. Una es impedir que se pon­
gan obstáculos en las inmediaciones de los rincones superior izquierdo e inferior de­
recho, pues de esta forma se reduce la probabilidad de que haya bloqueo. Otra posi­
bilidad es dejar que el jugador pueda volar cierto número de obstáculos:

75 voladuras=0
410 IF respuestaíO"" AND (colorí >3 OR voladuras
<2) THEN LOCATE coordx,coordy:PRINT" ”;:coor
dx=nuevacoordx:coordy=nuevacoordy
415 IF respuesta»<>"" AND color=3 THEN voladuras
=voladuras+1

En esta versión el jugador puede destruir dos obstáculos atravesándolos con la fle­
cha. La condición de la línea 410 nos ha quedado relativamente complicada: si se
ha pulsado una tecla de movimiento y además, o bien la próxima posición está libre
o bien el jugador todavía tiene derecho a volar un obstáculo, entonces mover la
flecha.
Estos mismos principios se pueden aplicar en muchos otros juegos. El jugador
puede guiar un coche de carreras por una pista, evitando las manchas de aceite; o
bien guiar la oruga hacia las hojas verdes evitando las moras venenosas. En ambos
casos, el programa debe averiguar el color de la próxima posición de texto y decidir
qué hacer en función del color que haya detectado.
Veamos otro ejemplo de aplicación de TEST. Se trata de un juego para dos jugado­
res; cada jugador debe evitar chocar con las paredes y contra el otro jugador. Los
caracteres van dejando un rastro según se mueven, de modo que el juego se va ha­
ciendo progresivamente más difícil.
En un juego de este tipo lo más sencillo es dividir el programa en varias secciones.
Empezaremos por las instrucciones de juego:
138 Programación BASIC con Amstrad

10 MODE 1
20 PEN 1
30 PRINT"Intenten evitar chocar el uno con el
□tro y con las paredes."
40 INPUT"Como se llama el jugador de la izquierd
a";nombrejuglí
50 PRINT"Use las teclas z y x para ir a izquierd
ay derecha. "
60 PRINT"Use las teclas d y c para subir y bajar

70 PRINT"Su carácter es: ";:PEN 3:PRINT CHR$(143


)
80 PRINT:PEN 1
90 INFUT"Como se llama el jugador de la derecha"
;nombrejug2$
100 PRINT"Use las teclas , y . para ir a izquier
day derecha. "
110 PRINT"Use las teclas / y ; para subir y baja
r. "
120 PRINT"Su carácter es: ";:PEN 2:PRINT CHR$(14
3)
130 PRINT:PEN 1
140 INPUT"Pulsen 1 a tecla ENTER para empezar: ",
empez ar$

Ahora vamos a dibujar un campo de juego rectangular y establecer las posiciones


de partida:

150 PAPER 1
160 PEN 0
170 CLS
180 pared$=CHR$(233)
190 expl$=CHR$(238)
200 izquierda=l
210 -Fondo=20
220 derecha=40
230 arriba=l
240 POR cuenta=arriba TO -Fondo
250 LOCATE izquierda,cuenta
260 PRINT pared$;
270 LOCATE derecha,cuenta
280 PRINT paredí;
290 NEXT
300 LOCATE izquierda,arriba
310 PRINT STRINGS(derecha-izquierda,pared$)
320 LOCATE i z qui er da,-F ondo
Juegos y gráficos 139

330 PRINT STRING«(derecha-izquierda,pared«)


340 juglx=13
350 jug1y=7
360 juglxmov=l
370 juglymov=0
380 jug1«=CHR«(143)
390 juglchoque-0
400 J.ug2x=26
410 jug2y=14
420 jug2xmov=-l
430 jug2ymov=0
440 jug2«=CHR«(143)
450 jug2choque=0
460 PEN 3
470 LOCATE juglx,jugly
480 PRINT jugl«;
490 PEN 2
500 LOCATE jug2x,jug2y
510 PRINT jug2«;

Finalmente, programamos el juego en sí, que sólo se interrumpe cuando un jugador


choca con una pared o atraviesa el rastro del otro:

520 WHILE juglchoque=0 AND jug2choque=0


530 respuesta«=INKEY«
540 IF respuesta$="z" THEN juglxmov=-1:jug1ymov=
0
550 IF respuesta$="x" THEN juglxmov=l:juglymov=0
560 IF respuesta«="d" THEN juglx<nov=0: juglymov=—
1
570 IF respuesta$="c" THEN juglxmov=0:juglymov=1
580 juglx=juglx+juglxmov
590 jugly=jugly+juglymov
600 grafx=8+(juglx-1)*16
610 gra-f y=8+(25-jugly) *16
620 col or=TEST (gra-fx , graf y)
630 LOCATE juglx,jugly
640 IF color<>l THEN PEN 0:PRINT expl«:jugIchoqu
e=l ELSE PEN 3:PRINT jugl«;
650 IF respuesta«^"," THEN jug2xmov=-l:jug2ymov=
0
660 IF respuesta$=". " THEN jug2xmov=1:jug2ymov=0
670 IF respuesta$=";" THEN jug2xmov=0:jug2ymov=-
1
680 IF respuesta«3"/" THEN jug2xmov=0:jug2ymov=l
690 juq2x = j uq2x + i uq2xmov
140 Programación BASIC con Amstrad

700 jug2y=jug2y+jug2ymov
710 gra-f x=8+(jug2x-l) *16
720 grafy=8+(25-jug2y)*16
730 col or=TEST (gra-f x , gra-f y)
740 LOCATE Jug2x,jug2y
750 IF colorOl THEN FEN 0: PRINT expl$:jug2choqu
e=l ELSE PEN 2:PRINT jug2$;
760 WEND
770 LOCATE 1,24
780 IF juglchoque=l AND jug2choque=l THEN PRINT"
Fue un empate.":END
790 IF jug1choque=1 THEN PRINT "Gano "jnombrejug
2$ ELSE PRINT "Gano ";nombrejug1$
800 PEN 1
810 PAPER 0

Para hacer más rápido el programa, sólo vamos a permitir el giro hacia la izquierda
o la derecha, pues así sólo tenemos que comprobar dos letras por jugador, en lugar
de cuatro:

540 IF respuesta$="z" OR respuesta$="x" THEN IF


juglxmov<>0 THEN juglymov=-juglxmov:juglxmov
=0 ELSE juglxmov=juglymov:juglymov=0
550 IF respuesta$="x" THEN juglxmov=-jugIxmov:ju
g1ymov=-jug1ymov
650 IF respuesta^", " OR respuesta^". " THEN IF
jug2xmov<>0 THEN Jug2ymov=-jug2xmovsjug2xmov
=0 ELSE jug2xmov=jug2ymov:jug2ymov=0
660 IF respuesta$="." THEN jug2xmov=-jug2xmov:ju
g2ymov=-jug2ymov

Estas líneas resultan muy complicadas para un ahorro de tiempo tan insignificante,
pero usted debe tratar de entenderlas.
Otra forma de acelerar el programa sería no tener que convertir las coordenadas
de texto en coordenadas gráficas. La solución, en la siguiente sección.

Ejercicios

1. Modifique el programa del laberinto para medir el tiempo que tarda el jugador
en llegar al objetivo. Calcule un tanteo basado en el tiempo y en el nivel de
habilidad.
2. Introduzca otra modificación en el programa del laberinto: dibuje algunos obstá­
culos de otro color para luego reducir el tanteo cada vez que la flecha choque
con ellos.
3. Modifique el programa de los jugadores para que continúe hasta que uno de
Juegos y gráficos 141

de los jugadores haya ganado tres juegos. Escriba los nombres de los jugadores
y el tanteo del rectángulo de juego.
4. Dificulte el programa de los dos jugadores diseñando un terreno de juego no rec­
tangular. Diseñe dos caracteres nuevos para representar los dos jugadores.
5. Diseñe cuatro caracteres que representen un coche de carreras apuntando en cua­
tro direcciones. Escriba un programa que permita controlar por el teclado el mo­
vimiento del coche por una pista negra dibujada sobre fondo verde. Si el coche
se sale de la pista, se desintegra. El programa será más completo y manejable
si dedica una tecla a la opción “freno”. Controle el tiempo y haga que el juego
termine cuando el coche llegue a la línea de meta, la cual debe estar dibujada con
un color diferente.

TEXTO EN LA POSICIÓN DEL CURSOR GRÁFICO

Esto de convertir coordenadas de texto en coordenadas gráficas es muy instructivo,


pero en la práctica lo que demuestra es un defecto de enfoque en los programas ante­
riores. Disponemos de una resolución de 160 X 200 puntos, y sin embargo sólo es­
tamos aprovechado una resolución de 20 x 25, que es la que proporcionan las posi­
ciones de texto. Incluso la resolución de texto en modo 2, que es de 80 caracteres
por 25 líneas, es muy pobre comparada con la resolución de la pantalla gráfica. Lo
que necesitamos es ser capaces de escribir caracteres en cualquier posición gráfica.
De esa forma mejoraremos considerablemente la resolución y podremos olvidarnos
de la conversión de coordenadas.
La instrucción que nos va a ayudar ahora es TAG. Aparte de otras ventajas, esta
instrucción facilita el diseño de gráficas y diagramas, ya que nos permite escribir tex­
to exactamente en la posición deseada. Por ejemplo, el siguiente programa dibuja
un diagrama de barras de datos relativos a los doce meses del año y escribe la inicial
del mes debajo de cada barra:

10 MODE 1
20 anchobarra=50
30 anchomes=16
40 anchorestante=anchobarra-anchome5
50 posicionmes=anchorestante/2
60 cerox=20
70 xmax=639
80 ceroy=50
90 ymax=350
100 MOVE cerox,ymax
110 DRAW cerox,ceroy,1
120 DRAW xmax,ceroy
130 TAG
140 FOR mes=l TO 12
150 READ mes$,ventas
142 Programación BASIC con Amstrad

160 MOVE cerox+(mes-1)*anchobarra,ceroy


170 DRAW cerox+(mes-1 )*anchobarra,ceroy+ventas,3
180 DRAW cerox+mes*anchobarra,ceroy+ventas
190 DRAW cerox+mes*anchobarra,ceroy
200 MOVE cerox+(mes-1 )»anchobarra+posicionmes,ce
roy-16
210 PRINT LEFT$(mes$,1);
220 NEXT
230 DATA Enero,97,Febrero,130,Marzo,141,Abrí 1,15
5,Mayo,210,Junio,276
240 DATA Juli o,240,Agosto,223,Septiembre,112,Oct
ubre,99,Novi embre,84,Diciembre,76

Obsérvese que los caracteres se escriben de tal forma que el punto superior iz­
quierdo del carácter coincide con la posición del cursor gráfico. Hay que tener este
hecho en cuenta antes de decidir dónde se va a escribir cada carácter. Esto explica
los cálculos de las líneas 20 a 50, con los cuales se centra la letra bajo la barra corres­
pondiente. Modifique la variable ‘anchobarra’ en la línea 20; si pone un valor ma­
yor, observará que las iniciales siguen centradas, pero las barras son demasiado an­
chas y ya no caben todas en la pantalla.
La instrucción TAG se anula con TAGOFF. A partir del momento en que se eje­
cuta TAGOFF, la instrucción vuelve a enviar los textos a la posición en que se en­
contraba el cursor de texto antes de ejecutar TAG. El modo TAG se cancela auto­
máticamente cuando el programa termina o es interrumpido.
No por el hecho de escribir con TAG nos vemos libres de las limitaciones que im­
pone la resolución gráfica. Por ejemplo, el desplazamiento en vertical tiene que ser
de al menos dos puntos; si sólo nos movemos un punto, el ordenador vuelve a escri­
bir el carácter en la misma posición. El desplazamiento mínimo en horizontal de­
pende del modo de pantalla. En la figura 14 se muestra cuál es ese desplazamiento
mínimo para los tres modos. El siguiente programa ilustra lo que decíamos:

10 MODE 1
20 TA8
30 x=300
40 y=200
41 MOVE x,y:PRINT CHR$(249);
50 respuesta$=""
60 WHILE respuesta$<>"n"
70 respuesta$=INKEY$
80 IF respuesta$="z" THEN MOVE x,y:PRINT" ";:x=x
-Is MOVE x,y:PRINT CHR$(249);
90 IF respuesta$="x" THEN MOVE x,y:PRINT" ";:x=x
+1:MOVE x,y:PRINT CHR$(249);
100 WEND
Juegos y gráficos 143

Observe que hay que pulsar cada tecla al menos dos veces para que se produzca al­
gún movimiento. La situación es aun peor si se ejecuta el programa en modo 0, por­
que entonces hay que pulsar las teclas cuatro veces para conseguir un movimiento
horizontal.

ORIGIN y movimientos relativos

El programa que dibuja los diagramas de barras se puede simplificar aun más si se
dibuja cada barra después de modificar el origen de las coordenadas gráficas. He­
mos visto antes que podemos definir ventanas de texto, y que cada una de ellas tiene
su sistema de coordenadas propio, con el origen en el extremo superior izquierdo.
De manera análoga podemos desplazar el sistema de coordenadas gráficas eligiendo
qué punto queremos que tenga las coordenadas (0, 0):

10 MODE 1
20 anchobarra=50
30 anchomes=16
40 ancharestante=anchobarra-anchDme5
50 posi cionmes=anchorestante/2
60 cero:: =20
70 xmax=639
80 ceroy=50
90 ymax=350
100 MOVE cerox,ymax
110 DRAW cerox,ceroy,1
120 DRAW xmax,ceroy
121 ORIGIN cerox,ceroy
125 MOVE 0,0
130 TAG
140 FOR mes=l TO 12
150 READ mes$,ventas
170 DRAW 0,ventas,3
180 DRAW anchobarra,ventas
190 DRAW anchobarra,0
200 MOVE posicionmes,-16
210 PRINT LEFT$(mes$,1);
215 cerox=cero;:+anchobarra
216 ORIGIN cerox,ceroy
220 NEXT
230 DATA Enero, 97,Febrero,130,Marzo,141,Abri1,15
5,Mayo,210,Juni o,276
240 DATA dui io,240,Agosto,223,Septiembre,112,Oct
ubre,99,Novi embre.84.Di ci embre,76
144 Programación BASIC con Amstrad

Como se puede observar, los cálculos previos al dibujo de cada barra son ahora más
sencillos. El bucle de la línea 140 desplaza el origen de coordenadas hasta el sitio
donde se va a dibujar cada barra. Las órdenes DRAW son también más sencillas.
El interés principal de la orden ORIGIN está en que permite repetir una figura
determinada en diversos lugares de la pantalla.
A menudo se observa que un dibujo se simplifica cuando lo programamos en
coordenadas relativas en lugar de en coordenadas absolutas. Observe el siguiente
programa, que dibuja un rectángulo:

10 MODE 1
20 MOVE 0,0
30 DRAW 200,0
40 DRAW 200,100
50 DRAW 0,100
60 DRAW 0,0

En este programa las coordenadas son absolutas. Así, en la línea 30 las coordena­
das son las del punto (200, 0); por muchas veces que ejecutemos el programa, el di­
bujo siempre será el mismo. A pesar de lo sencilla que es esta figura, es un trabajo
tedioso tener que calcular las coordenadas de los vértices cada vez que queramos di­
bujarla en otra posición de la pantalla. Sería muy conveniente poder describir los
movimientos refiriéndolos a la posición actual del cursor gráfico. Los movimientos
relativos necesarios para dibujar el rectángulo serían los que se muestran en la
figura 31.

(100,0)

(200,0)

Figura 31. Desplazamientos necesarios para dibujar un


rectángulo, referido a la posición actual del cursor gráfico.

Como era de esperar, el BASIC del Amstrad dispone de las instrucciones que resuel­
ven este problema. Se trata de MOVER, DRAWR y PLOTR, con las que se reali­
zan movimientos relativos sin tener que cambiar el origen de coordenadas:
Juegos y gráficos 145

10 MODE 1
15 INPUT "Coordenadas del vértice inferior
izquierdo del rectangulo";x,y
20 MOVE x,y
30 DRAWR 200,0
40 DRAWR 0,100
50 DRAWR “200,0
60 DRAWR 0,-100

Las órdenes DRAWR de las líneas 30 a 60 especifican desplazamientos referidos a


la última posición visitada. La línea 30 dibuja una recta que va desde el último pun­
to visitado hasta un punto que se encuentra a 200 puntos a su derecha y en la misma
horizontal. La línea 60 dibuja una recta que va desde el último punto visitado hasta
un punto que está en la misma vertical y a 100 puntos por encima de él.
Incluyendo un factor de escala podemos dibujar una serie de rectángulos
semejantes:

10 MODE 1
15 INPUT "Coordenadas del vértice inferior
izquierdo del rectangulo";x,y
20 MOVE x,y
25 INPUT "Escala";escala
30 DRAWR 200*escala,0
40 DRAWR 0,100*escala
50 DRAWR -200*escala,0
60 DRAWR 0,-100*escala

Introduciendo un valor de ‘escala’ de 2, se dibuja un rectángulo de tamaño doble


que el programa anterior. Con un factor de escala de 0.1 el rectángulo se reduce
a la décima parte. Aunque en estos programas no hayamos tenido ocasión de hacer­
las intervenir, las instrucciones MOVER y PLOTR funcionan de forma similar.
Cuando hay que dibujar varias figuras iguales o compuestas por elementos que se
repiten, los programas se simplifican mucho si se utiliza ORIGIN y los desplaza­
mientos relativos.

Ejercicios

1. Vuelva a escribir el programa del laberinto haciendo que la flecha se mueva reco­
rriendo posiciones gráficas en lugar de posiciones de texto.
2. Modifique el programa del diagrama de barras para que escriba un título debajo
del diagrama. Rotule el eje para que se puede leer aproximadamente la longitud
de las barras.
3. Escriba un programa que simule 200 lanzamientos de dos dados y dibuje un dia­
grama de barras en el que se muestre la distribución de los resultados. Rotule
los ejes horizontal y vertical.
4. Escriba un programa que dibuje la siguiente figura con MOVER y DRAWR:
146 Programación BASIC con Amstrad

5. Amplié el programa del ejercicio anterior para que dibuje una “pirámide huma­
na”, cada “piso” con un color diferente.

Plumas y tinteros

Hasta ahora sólo hemos visto parte de los colores que el Amstrad puede generar.
Hay un máximo de 16 plumas (en modo 0), y sin embargo los colores que relacioná­
bamos en la figura 18 son 27. El Amstrad nos permite decidir en cuál de los 27 tinte­
ros queremos cargar cada una de las 16 plumas. De esta forma podemos seleccionar
una combinación de colores, cuya variedad dependerá del modo de pantalla.
El máximo número de colores que puede haber en la pantalla simultáneamente
sigue estando limitado. Por ejemplo, en modo 2, aunque decidamos escribir con
caracteres rojos sobre fondo blanco, éstos serán los dos únicos colores que podre­
mos tener en la pantalla en un momento dado. Los límites son, pues 2 colores en
modo 2, 4 en modo 1 y 16 en modo 0.
Cuando encendemos o reinicializamos la máquina, se pone automáticamente en
modo 1 y selecciona el papel número 0 (PAPER 0, que inicialmente es azul porque
está cargado con tinta número 1) y la pluma número 0 (PEN 1, inicialmente amari­
lla, tinta número 24). Reinicialice el ordenador y escriba:

INK 1,6

El texto que había en la pantalla ha cambiado instantáneamente de amarillo a rojo


intenso. La orden INK va seguida de dos números: el primero es el número del pa­
pel y de la pluma cuyo color se va a cambiar; el segundo es el número de la tinta
con que se va a cargar ese papel y esa pluma.
Así pues, la orden INK 1,6 ha hecho que el papel número 1 y la pluma número
1 se carguen con tinta de color 6, que es el rojo intenso. En el momento de ejecutar
la orden, cambia de color todo lo que antes se hubiera escrito con la pluma 1 o sobre
Juegos y gráficos 147

fondo de papel 1. Para volver de color azul intenso el texto que tiene en la pantalla,
escriba

INK 1,2

Todo lo que antes era rojo ahora es azul. ¿Cómo devolver el color normal al texto?
Quizá sepa usted la respuesta:

INK 1,24

Inicialmente, la pluma 1 está cargada con tinta (INK) 24 en todos los modos, como
puede comprobar consultando la figura 20.
El color del fondo se cambia con la misma facilidad. En este momento el ordena­
dor está utilizando el papel número 0. Como no se lo hemos cambiado, su color
sigue siendo azul. Para hacerlo blanco escriba

INK 0,26

El texto es difícil de leer. Pruebe con

INK 0,6

o con
INK 0,0

El papel 0 es inicialmente azul (tinta número 1) en todos los modos. Esta vez vamos
a dejar que devuelva usted todos los colores a la normalidad sin ayuda.
No es necesario haber utilizado previamente un papel o una pluma para cambiar­
les la tinta. Reinicialice el ordenador y escriba:

INK 3,0

No parece que haya ocurrido nada. Si ahora elegimos la pluma 3 en modo 1, com­
probaremos que está cargada con tinta negra (número 0), no con la tinta roja (núme­
ro 6) que podemos ver en la figura 20. Escriba

F'EN 3

y verá cómo todo el texto siguiente aparece en negro. Escriba

INK 3,6

Todo lo que antes era negro ahora se ha vuelto rojo (tinta número 6). La pluma
3, que es la que estamos utilizando en este momento, empieza a escribir con tinta
roja. Esta situación permanece así hasta que se cambie de modo de pantalla.
148 Programación BASIC con Amstrad

Compruébelo.
Se puede cargar un número de pluma o de papel con una mezcla de dos colores:

INK 1,3,26

El texto escrito con la pluma 1 alterna ahora entre los colores 3, rojo, y 26, blanco.
La ventaja obvia de INK es que nos permite seleccionar una combinación cual­
quiera de los 27 colores disponibles, aunque con la limitación del número total de
colores simultáneos, el cual depende del modo de pantalla. Incluso el modo 2, con
su modesta variedad, se puede animar eligiendo color blanco para el fondo y rojo
para el texto.
El siguiente programa genera las 749 combinaciones de color posibles en modo 2:

10 MODI7 2
20 FOR x=0 TO 27
30 CLS
40 INK 0,x
50 FOR y=0 TO 27
60 IF xOy THEN INK. 1,y: PRINT"ink ";y
70 respuestaí=""
80 WHILE respuesta$=""
90 respuesta$=INKEY$
100 WEND
110 NEXT
120 NEXT

Una ventaja no tan evidente de este sistema de selección de color es que se puede
elegir una pluma que esté cargada con tinta del mismo color que el fondo para escri­
bir mensajes o dibujar figuras y luego hacerlos aparecer instantáneamente con una
simple instrucción INK:

10 MODE 0
20 REM dibujar monigotes con plumas diferentes
.30 FOR x=l TO 17 STEP 4
40 FOR y=l TO 20 STEP 4
50 PEN 1
60 REM ponerlos del color del fondo
70 INK 1,1
80 LOCATE x,y
90 PRINT CHR$(248);
100 NEXT
110 NEXT
120 PEN 5
130 INK 5,24
140 LOCATE 1,22
150 PRINT "Pulse Cualquier tecla para ver lo
s monigotes";
Juegos y gráficos 149

160 REM esperar pulsación de tecla


170 respuesta$=""
180 WHILE respuesta$=""
190 respuesta$=INKEY$
200 WEND
210 INK 1,24
220 GOTO 220

También podemos cargar varias plumas con el color del fondo y luego cambiarles
la tinta selectivamente:

10 MODE 0
11 REM dibujar monigotes con diferentes colores
de pluma
20 FÓR x = l TO 17 STEF 4
30 FOR y=l TO 20 STEF 4
40 PEN 1
41 REM ponerlos del color del fondo
50 INK 1,1
60 LOCATE x,y
70 PRINT CHR$(248);
80 PEN 2
81 REM ponerlos del color del fondo
90 INK 2,1
100 PRINT CHR$(249);
110 PEN 3
111 REM ponerlos del color del fondo
120 INK 3,1
130 PRINT CHR$(250);
140 PEN 4
141 REM ponerlos del color del fondo
150 INK 4,1
160 PRINT CHR$(251);
170 NEXT
180 NEXT
190 PEN 5
200 INK 5,24
210 LOCATE 1,22
22.0 PRINT "Pulse cualquier tecla para mover
1osmoni gotes";
221 REM ciclo de colores
230 FOR color~0 TO 50
231 REM esperar pulsación de tecla
240 respuesta^""
250 WHILE respuesta$=""
260 respuesta$=INKEY$
150 Programación BASIC con Amstrad

270 WEND
271 REM calcular color para -fondo
280 nover=color MOD 4
290 IF nover=0 THEN nover=4
300 INK nover,1
301 REM calcular color para -figuras
310 ver=(color+l) MOD 4
320 IF ver=0 THEN ver=4
330 INK ver,24
340 NEXT
341 REM volver pen 1 a normal
350 PEN 1
360 INK 1,24

Con la línea 230 recorremos los colores de tinta del 0 al 50. Como sólo nos interesan
los colores del 1 al 4, con las líneas 280 a 310 obtenemos números de este margen.
La función MOD da el resto de la división; por ejemplo, 17 MOD 4 da 1, porque
1 es el resto que se obtiene al dividir 17 por 4. Nos queda un pequeño problema,
y es que los números producidos por MOD van del 0 al 3, no del 1 al 4. Por eso
hemos incluido las líneas 290 y 320, para convertir el 0 en 4. El efecto global es que,
en cada pasada por el bucle, cargamos una pluma con tinta del color del fondo (1)
y la siguiente con tinta del color del texto (24), dando así una ilusión de movimiento
de los monigotes, cuando en realidad lo que estamos haciendo es apagarlos y encen­
derlos como si fueran bombillas.

Ejercicios

1. Escriba un programa que cambie los colores de una tinta de modo que un mensa­
je aparezca, en modo 1, en caracteres morados, negros y verdes sobre fondo
blanco.
2. Añada unas líneas al programa del laberinto para que la pantalla se dibuje con
el color del fondo y luego aparezca súbitamente con una orden INK.
3. Dibuje una casa sobre un cielo azul, con hierba verde delante. Al tocar una te­
cla, los colores deben cambiar la escena para que parezca que es de noche y sale
luz por las ventanas.
4. Provoque un incendio en la casa dibujando algo a su alrededor en colores parpa­
deantes adecuados.
9

Planificación de un programa

EN QUE PUEDE AYUDARNOS EL AMSTRAD

En los últimos capítulos hemos avanzado mucho. Los programas han ido siendo
cada vez más largos y más complejos. A estas alturas el lector ya conocerá a fondo
los métodos de edición del Amstrad, pero hay muchas otras funciones del ordenador
que pueden ayudarle en la elaboración de programas. Una de las cosas que vamos
a estudiar en este capítulo es cómo utilizar funciones del ordenador para detectar
los errores que inevitablemente se deslizan al escribir los programas.
No obstante, el objetivo principal de este capítulo es dejar bien claro lo importan­
te que es la planificación en todo trabajo de programación. Le daremos unas suge­
rencias sobre cómo evitar los problemas que suelen dar los programas mal organiza­
dos. Como instrumento para exponer estas ideas, desarrollaremos un programa
de juego, desde su concepción hasta su versión final libre de errores.
Antes de nada, vamos a hacer unos preparativos para trabajar con mayor
comodidad.

Las teclas de función

El lector habrá observado que hay determinadas órdenes que se utilizan con extraor­
dinaria frecuencia; por ejemplo, LIST y RUN. A partir de ahora podrá listar y eje­
cutar los programas con sólo pulsar una tecla. (Cargue o escriba un pequeño pro­
grama para tener algo que listar y ejecutar.)
Vimos en el capítulo 6 que todo carácter tiene asociado un código ASCII. Los
códigos que van del 0 a 31 tienen significados especiales. Los del margen 32 a 127
representan las letras mayúsculas y minúsculas, las cifras, los signos de puntuación
y otros caracteres de uso corriente. Los del margen 128 a 159 representan diversos
caracteres gráficos, pero también se los puede asociar a cadenas literales, que enton­
ces pueden ser generadas al pulsar la tecla correspondiente; son los códigos
expansibles.
En el momento de inicializar o encender la máquina, los códigos expansibles del
128 al 140 son generados por el teclado numérico y tienen asignadas las cadenas de
expansión que se muestran en la figura 33. Los restantes códigos expansibles, del
141 al 159, no están asignados inicialmente a ninguna tecla.

151
152 Programación BASIC con Amstrad

Asignación inicial
Código
expansible
Tecla Cadena de expansión

128 0 “0”
129 1 “1”
130 2 “2”
131 3 “3”
132 4 “4”
133 5 “5”
134 6 “6”
135 7 “7”
136 8 “8”
137 9 “9”
138 C( ,,
139 <ENTER> CHR$(13)
140 < CTRL >< ENTER) “RUN” + CHR$(13)

Figura 33. Códigos expansibles: posiciones y valores implícitos.

Mediante la instrucción KEY (“tecla”) podemos modificar la cadena de expan­


sión asignada a los caracteres expansibles. Por ejemplo,

KEY 128,"Hola, amigo lector"

Esta orden hace que, en lo sucesivo, cada vez que pulsemos la tecla del ‘0’ en el tecla­
do numérico, obtengamos la frase ‘Hola, amigo lector’. Las teclas del teclado nu­
mérico se denominan teclas de función por la facilidad con que pueden ser progra­
madas. No obstante, todas las demás teclas son programadles, como veremos más
adelante.
Una aplicación más útil de KEY sería

KEY 128,"LIST"

Obsérvese que el número del código debe ir seguido de una coma y que la cadena
de expansión se debe especificar siguiendo las reglas de las cadenas literales. Si aho­
ra pulsa la tecla del ‘0’, el ordenador escribe la palabra LIST, pero el cursor se queda
a la derecha de ella, esperando que usted pulse <ENTER>. Esto está bien para algu­
nas funciones, pero en ocasiones preferimos que el propio ordenador “pulse”
<ENTER>.
Pues bien, la acción de pulsar <ENTER> se especifica mediante uno de los códigos
del 0 al 31; concretamente, con el 13. Escriba:
Planificación de un programa 153

y pulse la tecla del ‘0’.


No es mala idea incluir <ENTER> al principio de la cadena de expansión. De
lo contrario, si por ejemplo acabamos de escribir una línea del programa y todavía
no hemos pulsado <ENTER>, al pulsar la tecla del ‘0’ lo que hacemos es equivalente
a escribir LIST al final de la línea y luego pulsar <ENTER>. En cambio, si la defini­
ción es

KEY 128, CHRt ( 13 ) •» " LI2T " t CHR$ 113 )

al pulsar la tecla del ‘0’ el ordenador da por terminada la línea pendiente y luego
lista el programa.
En la cadena de expansión se puede incluir cualquier palabra clave de BASIC.
Por ejemplo, es conveniente volver al modo 1 antes de listar el programa:

KEY 128, CHR$ (13)+"MODE 1 :LI ST" +CHR$ (13)

Como los números siguen estando disponibles en la primera fila del teclado princi­
pal, nada impide que asignemos cadenas de expansión a todas las teclas del teclado
numérico. Quizá le interese grabar el siguiente conjunto de definiciones para utili­
zarlo sistemáticamente en el futuro:

10 KEY 128,CHR$(13)+ "mode 1: 1ist"+CHR$(13)


20 KEY 129,CHR$(13)+ "run"+CHR$(13)
30 KEY 130,CHR$(13)+ "save"
40 KEY 131,CHR$(13)+ "load"
50 KEY 138,CHR$(13)+ "auto"
60 KEY 139,CHR$(13)+ "cls"+CHR$(13)
70 KEY 132,"while"
80 KEY 133, "wen'd "
90 KEY 134, "-for"
100 KEY 135,"next"
110 KEY 136,"read"
120 KEY 137,"data"

o modifíquelo según su gusto personal o sus necesidades concretas.


La gran ventaja de que las teclas sean definibles por programa es que se puede
tener grabados varios programas, cada uno con un juego de definiciones distintas.
En cada sesión de trabajo se carga y ejecuta el programa deseado; cuando se borra
el programa, no se pierde la definición de las teclas. Por ejemplo, cuando se está
desarrollando programas gráficos, el siguiente conjunto de definiciones puede ser
útil:

10 KEY 128,CHR$(13)+"mode 1:1 i st"+CHR$(13)


20 KEY 129.CHR»(13)+"run"+CHR$(13)
30 KEY 130,CHR$(13)+"save"
40 KEY 131,CHR$(13)+"1oad"
154 Programación BASIC con Amstrad

50 KEY 138, CHR$(13)hi- " auto"


60 KEY 139, CHR*(13)hh "cls"+CHRt. (13)
70 KEY 132, "move"
80 KEY 133, "draw"
90 KEY 134, "plot"
100 KEY 135,"pen"
110 KEY 136,"window"
120 KEY 137,"data"

La única forma de saber qué cadena de expansión tiene asignada cada tecla en
un momento dado es pulsar las teclas. Este pequeño inconveniente no debe desani­
marle; si utiliza siempre el mismo juego de definiciones, puede pegar unas etiquetas
autoadhesivas en las teclas; si no, confíe en su memoria.
La definición de teclas no tiene más límite que el siguiente: el máximo número
de caracteres que pueden contener las cadenas de expansión es 120.
Estos 120 caracteres se pueden repartir como se desee entre todas las cadenas. No
es probable que esta limitación tenga ninguna importancia, a menos que su trabajo
se salga de lo normal.

Definición de otras teclas

Como hemos dicho, todas las teclas son definibles, aunque las del teclado principal
requieren una instrucción más. Ilustraremos el procedimiento con un ejemplo. Va­
mos a redefinir la tecla de la ‘A’ para que genere, en minúsculas, la ‘Z’ mayúscula:

KEY DEF 69,1,90

El primer parámetro de KEY DEF es el numero de tecla. En el apéndice III del Ma­
nual del Usuario se da un mapa con los números de todas las teclas. El segundo
parámetro puede ser 0 o 1; si es 1, la tecla será de repetición; si es 0, no lo será.
El tercer parámetro es el código ASCII que queremos que la tecla genere en minús­
culas; en este caso hemos puesto el 90, que representa la ‘Z’ mayúscula, pero tam­
bién podríamos haber puesto cualquier código expansible. Los parámetros cuarto
y quinto, omitidos en este caso, son los códigos ASCII que la tecla debe producir
en mayúsculas y combinadas con <CTRL>, respectivamente.
Para devolver la tecla a su situación normal escriba

KEY DEF 69,1,97

donde 97 es el código ASCII de la ‘a’ minúscula.


Este ejemplo no revela ninguna utilidad. Sin embargo, hay ciertas aplicaciones,
como en proceso de textos, en las que es conveniente poder redefinir teclas para
adaptar el teclado al idioma (acentos, tilde, etc.) Por otra parte, seguimos dispo­
niendo de los códigos expansibles, algunos de los cuales (del 141 al 159) no hemos
tenido ocasión de utilizar. Para servirnos de ellos necesitamos KEY DEF y KEY.
Vamos a tomar uno de ellos, el 141, y a asignarlo a la tecla de la libra esterlina, *£’:
Planificación de un programa 155

KEY DEF 24,0,141

A partir de este momento la tecla “£’ produce el código 141. Sin embargo, al pulsarla
no vemos que aparezca nada en la pantalla. Es natural, puesto que todavía no he­
mos asignado ninguna cadena de expansión al código 141. Escriba

KEY 141,"read"

y pulse la tecla de la *£’. Hemos estableceido así una conexión indirecta entre el te­
clado y los códigos expansibles.
El método para definir una tecla que no esté en el teclado numérico es el siguiente:
1) Elegir una tecla que no se utilice habitualmente; averiguar su número consultan­
do el apéndice III del Manual del Usuario.
2) Redefinir la tecla con KEY DEF para que genere uno de los caracteres expansi­
bles (de 120 al 159).
3) Asignar a ese carácter, con KEY, la cadena de expansión deseada.
También se puede, con KEY DEF, modificar una tecla del teclado numérico para
que produzca un código expansible distinto del inicialmente asignado o cualquier
otro código ASCII. Por ejemplo, KEY DEF 6,1,65,66,130 redefine la tecla
<ENTER> pequeña para que genere la letra ‘A’, la letra ‘B’ y el código expansible
130 en minúsculas, en mayúsculas y con <CTRL>, respectivamente.
El siguiente programa redefine cinco de las teclas que se utilizan con menor
frecuencia:

10 KEY 128, CHR$(13) + "mode 1: 1ist"+CHR$(13)


20 KEY 12?; CHR$(13)+ ”run"+CHR$(13)
30 KEY 130, CHR$(13)+ "save"
40 KEY 131, CHR$(13)+ "1oad"
50 KEY 138, CHR$(13)+ "auto"
60 KEY 139, CHR$(13)+ "cls"+CHR$(13)
70 KEY 132, "move"
80 KEY 133, "draw"
90 KEY 134, "plot"
100 KEY 135,"pen"
110 KEY 136,"window"
120 KEY 137,"data"
121 REM tecla de libra esterlina
130 KEY DEF 24,0,141
140 KEY 141,"read"
141 REM tecla de la ’arroba’
150 KEY DEF 26,0,142
160 KEY 142,"whi le"
161 REM tecla de abrir corchete
170 KEY DEF 17,0,143
180 KEY 143,"wend"
156 Programación BASIC con Amstrad

1S1 REM tecla de cerrar corchete


190 KEY DEF 19,0,144
200 KEY 144, "-for"
201 REM tecla de la barra inclinada hacia la izq
ui erda
210 KEY DEF 22,0,145
220 KEY 145,"next"

Otra t?cla que se podría redefinir es la <TAB>, pero con esto casi se agota el reperto­
rio. La forma de ampliar las posibilidades de redefinición de teclas es una que ya
hemos mencionado: dar definiciones distintas para minúsculas, mayúsculas y
<CTRL>. Por ejemplo,

KEY DEF 22,0,145,146,147


KEY 145,"if"
KEY 146,“then"
KEY 147,"else"

redefine la tecla ‘V para que produzca tres palabras diferentes en minúsculas, ma­
yúsculas y combinada con <CTRL>.

Ejercicios

1. Diseñe usted una redefinición de las teclas y grabe el programa para su utilización
posterior. Algunas funciones que se pueden incluir en las cadenas de expansión
son las siguientes: devolver los números de pluma y de papel, así como sus colo­
res, a la situación habitual; asignar ‘KEY’ y ‘KEY DEF’ a alguna tecla para faci­
litar las redefiniciones; asignar a diversas teclas los nombres de variables más fre­
cuentemente utilizados, tales como ‘continuar’, ‘cuenta’, ‘numeropluma’, etc.

ERRORES Y DEPURACIÓN

Al principio de este capítulo mencionábamos la cuestión de los errores en los progra­


mas. Contra lo que el profano puede creer, no hay ningún programa que funcione
bien a la primera, salvo los más triviales. Casi todos los programas son el resultado
de una fase de planificación seguida de otra fase en la que el programador se dedica
a resolver problemas que no había previsto antes. Si la planificación no ha sido cui­
dadosa, en ocasiones los cambios necesarios son tantos que equivalen a escribir el
programa de nuevo.
No le sorprendan ni desanimen los errores, en particular si es usted nuevo en la
afición a la informática. El ordenador dispone de recursos que ayudan a detectar
errores; utilizándolos le será mucho más fácil depurar los programas. Veamos un
pequeño programa que ilustra el funcionamiento de esos recursos:
Planificación de un programa 157

10 ON ERROR GOTO 100


20 pront"Hola"
30 END
100 FRINT"Hay un error en la linea";ERL
110 PRINT"E1 numero de error es";ERR
120 END

En la línea 20 hemos dejado deliberadamente un error, ‘pront’ en lugar de ‘print’.


La línea 10 significa: “cuando encuentres un error, salta a la línea 100”. Y, en efec­
to, cuando el programa llega a la línea 20, detecta un error y salta a la línea 100.
Ésta escribe el número de línea donde ha detectado el error; la línea 110 escribe el
número del error, en este caso el 2. En el apéndice VIII del Manual del Usuario se
da una lista de los números de los errores junto con su descripción. El error 2 es
un syntax error (error de sintaxis), lo que significa que hemos escrito algo sin ajus­
tarnos a las reglas “gramaticales” de BASIC.
Gracias a la línea 110, sabemos dónde ha ocurrido el error y así podemos editar
la línea que lo contiene. Curiosamente, conseguimos mayor información omitiendo
la línea 10 que con ella; si lo dejamos solo, el Amstrad describe el error en lugar
de limitarse a indicar el número. Los demás ordenadores no suelen ser tan explíci­
tos; en ellos ON ERROR es más importante. No obstante, en algunas situaciones,
ON ERROR puede ser interesante también en el Amstrad, como demuestra el si­
guiente programa:

10 ON ERROR GOTO 1000


20 PEN 0
30 papper 1
40 END
1000 MODE 1
1010 INK 1,24
1020 INK 0,1
1030 PEN 1
1040 PAPER 0
1050 PRINT"Hay un error en la linea";ERL
1060 PRINT"E1 numero de error es";ERR
1070 END

El ordenador detecta el error de la línea 30 después de seleccionar la pluma 0 en la


línea ; si no fuera por la línea 10, el Amstrad escribiría el mensaje de error con esa
pluma, que tienen el mismo color que el papel; es decir, el mensaje sería invisible.
Pero ON ERROR reconduce el programa a la línea 1000; en las líneas 1010 y si­
guientes restauramos los colores normales antes de escribir los mensajes en las líneas
1050 y 1060.
Todos los errores que hemos estudiado hasta ahora han sido errores de sintaxis,
pero hay muchos otros que pueden presentarse en los programas. Si escribimos
numero=“Hola”
158 Programación BASIC con Amstrad

provocamos un error de ‘Type mismatch’ (“incongruencia de tipos”); hemos trata­


do de asignar una cadena literal a una variable numérica. Estos errores, y muchos
otros, pueden ser detectados porque transgueden las reglas que están grabadas en
la ROM; y por ser detectables podemos corregirlos. Mucho más graves son los
errores lógicos cometidos por el programador en la concepción del programa.
Un error lógico es aquél que hace que el programa no funcione como se espera
de él. Por ejemplo, el siguiente:

10 MODE 1
20 numero!”5
30 numero2=7
40 PRINT numero! ; "mas" ¡¡ numero2; "es igual a"; nume
rol*numero2
50 END

El programa funciona a la perfección en el sentido de que no viola ninguna regla


de BASIC. Sin embargo, no da el resultado correcto porque el programador ha co­
metido un error lógico en la línea 40: ha multiplicado los números en lugar de su­
marlos. En este caso el error es obvio porque la operación es muy sencilla y el resul­
tado aparece inmediatamente en la pantalla. Pero si el resultado se utilizara para
realizar un cálculo posterior, y el de éste para otro, etc., el error ya no sería tan fácil
de detectar.
Un error lógico muy frecuente se produce cuando se abre un bucle infinito:

10 ON ERROR GOTO 1000


20 continuar=0
30 WHILE continuar=0
40 WEND
50 END ■
1000 MODE 1
1010 INK 1,24
1020 INK 0,1
1030 PEN 1
1040 PAPER 0
1050 PRINT"Hay un errar en la linea";ERL
1060 PRINT"E1 numero de error es";ERR
1070 END

Afortunadamente, este bucle se puede interrumpir pulsando dos veces <ESC>, ya


que esta interrupción es prioritaria con respecto a ON ERROR. Pero si hubiéramos
puesto las líneas

22 PEN 2
23 INK. 2, 1
Planificación de un programa 159

antes de entrar en el bucle, al pulsar <ESC> seguiríamos sin saber qué ocurre porque
los textos serían invisibles. Esto se remedia con la siguiente línea:

10 ON BREAK GOSUB 1000

(on break significa “en caso de interrupción”.) La línea 10 indica al ordenador qué
debe hacer si tratamos de interrumpir el programa pulsando la tecla <ESC>; en con­
creto, ir a la línea 1000 y ejecutar las instrucciones que allí encuentre. Ahora las
líneas 1050 y 1060 ya no sirven para nada; en cambio, las líneas 1000 a 1040 restau­
ran las condiciones normales de la pantalla, y esto es lo que necesitamos.
¿Por qué hemos puesto GOSUB en la línea 10 y no GOTO? Enseguida lo
explicaremos.
Otra instrucción aplicable a la detección de errores es STOP:

10 MODE 1
20 FOR :•: = ! TO 100
30 IF x MOD 5==:0 THEN STOP
40 NEXT

STOP nos permite detener momentáneamente el programa, examinar las variables


de interés y reanudar la ejecución. Si ejecutamos el programa anterior, éste se detie­
ne y emite el mensaje ‘Break in 30’ (“interrupción en 30”). Escriba *?x’ y el ordena­
dor le dirá cuál es el valor de la variable ‘x’ en este momento: 5. Si ahora escribe
CONT, el programa continúa, a partir de la situación en que se detuvo, hasta que
‘x’ valga 10, y así sucesivamente. En un programa más largo, cuando no se está
seguro de cómo evoluciona, se insertan instrucciones STOP en puntos estratégicos
para examinar el valor de las variables sospechosas. También se pueden definir
unas cuantas teclas de función para que escriban el valor de las variables de interes.

ORGANIZACIÓN DEL PROGRAMA

En la sección anterior vimos por primera vez una instrucción GOSUB, pero no la
utilizamos correctamente. Lo que hace GOSUB es decirle al ordenador que vaya
a la línea especificada y continúe a partir de ella hasta que encuentre una instrucción
RETURN:
10 MODE 1
20 GOSUB 100
30 PRINT"Fuera de la subrutina."
40 END
100 FOR cuenta=l TO 10
110 PRINT"Contador dentro de la subrutina:cuen
ta
120 NEXT
130 RETURN
160 Programación BASIC con Amstrad

La línea 20 reconduce el programa hacia la subrutina que empieza en la línea 100.


El ordenador obedece las instrucciones de las líneas 100 a 120; al llegar a la 130,
“retorna” a la línea siguiente a aquélla que invocó la subrutina, esto es, a la 30.
La línea 40 es muy importante, pues impide que el programa llegue a la subrutina
por la vía indebida.
GOSUB es la primera instrucción que hemos conocido que altera el orden normal
de ejecución de los programas, que es de menor a mayor número de línea.
En los últimos capítulos los programas se nos han ido complicando. En cuanto
un programa tiene más de unas 10 líneas, lo más conveniente es desarrollarlo por
secciones. Al disponer de las subrutinas, podemos dividir el programa en una serie
de subprogramas, cada uno de los cuales realice una tarea específica, sencilla, y por
consiguiente fácil de programar. Cada subrutina se prueba y depura hasta que fun­
cione correctamente; luego se reúnen todas las subrutinas para formar el programa
global.
Quizá no se entiendan bien estas ideas mientras no las ilustremos con un ejemplo,
así que vamos a escribir un programa de juego. Se trata de un juego muy popular,
del que hay versiones para todos los ordenadores.

Planificación de un programa

El juego consiste en que el jugador controla un avión que “vuela” de izquierda a


derecha por la pantalla. Cada vez que el avión llega al borde derecho, reaparece
por el izquierdo una línea más abajo. El avión está volando sobre una ciudad for­
mada por edificios de alturas diferentes. Cada vez que el jugador pulsa la tecla *b’,
el avión suelta una bomba; si cae sobre un edificio, lo destruye parcialmente por
arriba; si no, cae sobre la hierba, donde explosiona. Mientras una bomba está ca­
yendo no puede caer otra. El objetivo del juego es hacer aterrizar el avión, para
lo cual hay que destruir todos los edificios a tiempo. Si esto no se consigue, el avión
en algún momento se estrellará contra algún edificio, con lo que terminará el juego.
Desde el punto de vista del programador, podemos subdividir el problema en va­
rias secciones:
1) Instrucciones para el jugador, nivel de juego, etc.
2) Inicialización de las variables que se van a utilizar, dibujo de la pantalla con los
edificios y con el avión en la posición de partida.
3) Rutina de juego.
4) Comentarios sobre el resultado del juego, tanteo, restauración de los colores a
la situación normal, etc.
Esta subdivisión no es la única posible. Por ejemplo, la sección 2 se podría subdivi­
dir a su vez en dos partes. Pero en este momento no nos preocupan los detalles del
programa, sino su aspecto general.
Empecemos a escribir el esqueleto del programa:

5 ON ERROR GOTO 70
10 MODE 1
Planificación de un programa 161

11 REM instrucciones
20 GOSUB 1000
21 REM preparar posición de comienzo para el jue
go
30 GOSUB 2000
31 REM jugar
40 GOSUB 3000
41 REM comentarios y marcador
50 GOSUB 4000
60 END
70 INK 0,1
S0 INK 1,24
90 INK 2,20
100 INK 3,6
110'PEN 1
120 PAPER 0
130 PRINT"Error. en la linea";ERL
140 F'RINT"Numero de error :";ERR
150 END
1000 REM 1 o completaremos mas adel ante
1100 RETURN
2000 REM 1 o completaremos mas adel ante
2100 RETURN
3000 REM 1 o completaremos mas adel ante
3100 RETURN
4000 REM lo completaremos mas adelante
4100 RETURN

Esto ha sido fácil, ¿verdad? El programa todavía no hace nada práctico, pero
sólo es un esqueleto; ahora tendremos que ir colocando los músculos. Los números
de línea tan elevados que hemos reservado para las subrutinas nos dejarán espacio
amplio para cuando empecemos a programar. Conviene espaciar los subprogramas
de 1000 en 1000 para así recordar fácilmente qué líneas hay que listar cuando este­
mos trabajando con una subrutina concreta. Las subrutinas vacias nos permiten al
menos ejecutar el programa.
Observe que ya hemos escrito la rutina de gestión de errores, líneas 5 y 70-150,
en previsión de que se produzca algún error cuando la tinta de la pluma sea invisible.
No hemos escatimado líneas REM; cuando se está desarrollando un programa lar­
go, al cabo de unos días o semanas es fácil olvidar para qué sirven las diversas subru­
tinas; las líneas REM nos refrescan la memoria. Ahora bien cuando el programa
ya está completo y depurado, las líneas REM lo hacen más largo y más lento. Es
conveniente grabar dos versiones del programa, una con líneas REM y otras sin
ellas. Si en algún momento se decide introducir alguna modificación en el progra­
ma, se trabaja con la versión comentada. La versión más corta es la que se utiliza
habitualmente, porque es más rápida.
Bueno, vamos con la subrutina 1000. Se encargará de escribir en la pantalla las
162 Programación BASIC con Amstrad

instrucciones de juego y de preguntar al jugador en qué nivel de habilidad quiere


jugar. Hagamos la pantalla más atractiva escribiendo con caracteres rojos sobre
fondo blanco:

1000 PEN 3
1010 INK 0,26
1020 PRINT"En este juego debes intentar bombarde
ar "
1030 PRINT"todos los edificios para que tu avión

1040 PRINT"pueda aterrizar sin problemas. Pulsa


b para soltar una bomba."
1050 PRINT:PRINT"En cuanto has soltado una bomba
, no"
1060 PRINT"puedes tirar la siguiente mientras"
1070 PRINT"la primera no haya llegado al suelo."
1080 PRINT:PRINT"Cual es tu nivel de habilidad?"
1090 INPUT "(de l=facil a 10=di-ficil) ",habilida
d
1100 RETURN

Ejecute el programa y compruebe que todo marcha bien. Primero escribe las ins­
trucciones de juego, después capta el nivel de habilidad y termina.
Ahora ya podemos despreocuparnos de esta parte del programa, aunque cabe la
posibilidad de que hayamos cometido un error que no descubramos hasta más tarde.
Por ejemplo, si hubiéramos puesto ‘habillidad’ en lugar de ‘habilidad’, el error se
haría patente más tarde, cuando llegase el momento de utilizar esta variable. Es de­
cir, aunque una rutina esté probada, podremos encontrar otros errores cuando com­
binemos la rutina con otra.
En cuanto a la rutina 2000, hay que tomar muchas decisiones antes de que empie­
ce el juego. Tenemos que elegir el modo de pantalla; tenemos que decidir si este
juego es de los que requieren TAG o si, por el contrario, son preferibles las coorde­
nadas de texto. También hemos de diseñar los caracteres que represente el avión
y los edificios. Debemos elegir los colores y decidir qué zona de la pantalla vamos
a dedicar al cielo y a la hierba. Debemos buscar una forma sencilla de dibujar los
edificios y elegir un punto de partida para el avión.
La inicialización de variables consistirá en preparar una variable que indique en
cada momento si hay una bomba cayendo, para permitir o impedir el disparo de
la siguiente. Hará falta otra variable para indicar si el avión ha chocado con un edi­
ficio; en función de ella decidiremos cuándo debe terminar el juego.
Todo esto tiene que estar pensado y decidido antes de que nos pongamos a escribir
líneas. Las improvisaciones en el teclado sólo harán que tardemos bastante más en
terminar el programa. Hay muchas soluciones posibles para los problemas que he­
mos planteado; una de ellas es la siguiente:
Planificación de un programa 163

1999 REM preparar el ’cielo’


2000 WINDOW 1,40,1,20
2010 INK 0,2
2020 PAPER 0
2030 CLS
2031 REM preparar la ’hierba’
2040 WINDOW #1,1,40,21,25
2050 INK 2,19
2060 PAPER #1,2
2070 Clr.8 #1
2071 REM de-finir avión
2080 SYMBOL 240,0,0,192,192,255,0,0,0
2090 SYMBOL 241,0,128,192,224,254,224,192,128
2100 avi on$=CHR$(240)+CHR$(241)
2101 REM de-finir un bloque de edificios
2110 SYMBOL 242,221,221,255,221,221,221,255,221
2120 edi -f i ci o$=CHR$ (242)
2130 bomba$=CHR$(252)
2140 expl $--CHR$ (238)
2141 REM numero de edificios en función de la ha
bi1 i dad
2150 numerodeed.i f = INT (RND*hab i 1 i dad+5)
2151 REM dibujarlos
2160 POR numerc=l TO numerodeedif
2161 REM generar aleatoriamente una coordenada x
de texto
2170 x=INT(RND*20+10)
2171 REM altura en función de la habilidad
2180 a11 ur a-INT(RND*(h ab i 1 i d ad+3)+1)
2181 REM dibujar edificio por bloques
2190 POR cuenta=0 TO altura
2200 y=20--cuenta: PEN 3
2210 LOCATE x,y
2220 PRINT edificio^;
2230 NEXT
2240 NEXT
2241 REM colocar avión y dibujarlo
2250 avi onx = l
2260 avi ony=l
2270 INK 1,0
2280 PEN 1
2290 LOCATE avionx,aviony
2300 PRINT avionl;
2301 REM preparar variables para registrar caida
de bombas, choque, tanteo
2310 choque=0
2320 bomba=0
164 Programación BASIC con Amstrad

2330 tanteo=0
2340 RETURN

Ejecute otra vez el programa y compruebe que las dos primeras subrutinas funcio­
nan correctamente. Si los edificios quedaran “colgados” del cielo o la hierba fuera
roja, éste sería el momento de corregir tales errores lógicos hasta quedar plenamente
satisfechos con el funcionamiento de la subrutina.
La subrutina 3000 es la verdaderamente crucial. Es muy probable que el juego
sea suficientemente complicado como para que debamos subdividirlo en secciones
más sencillas. De momento, tratemos de identificar el aspecto más importante del
juego: cuándo debe terminar. Es evidente que el juego debe continuar mientras el
avión no haya aterrizado ni chocado con un edificio. Podemos elegir como final
de la pista de aterrizaje, por ejemplo, el borde derecho del suelo:

2999 REM el juego continua mientras el avión no


aterrize o se estrelle
3000 WHILE (avionx<>39 OR aviony<>20) AND choque
=0
3010 GOSUB 5000
3020 WEND
3021 REM mantener la pantalla -final durante 2 se
gundos
3030 tiempoinicial=TIME
3040 WHILE TIME<tiempoinicial+600
3050 WEND
3060 RETURN

La condición de la línea 3000 es algo complicada; sólo podremos comprobarla cuan­


do hayamos desarrollado la subrutina 5000. Aplacemos eso para más tarde y termi­
nemos la última de las subrutinas principales, la de la línea 4000:

4000 MODE 1
4010 INK 0,1
4020 INK 1,24
4030 INK 2,2
4040 INK 3,6
4050 IF choque=0 THEN tanteo=tanteo+habi1idad
4060 PRINT"Su tanteo para el nivel";habi1idad ;
4070 PRINT"ha sido";
4080 PEN 3
4090 PRINT tanteo*habi1idad
4100 PEN 1
4110 RETURN

Esta subrutina restaura los colores normales de pluma y papel y escribe el tanteo.
Tal como está el programa, no podemos probar esta subrutina porque la de la línea
Planificación de un programa 165

3000 no termina nunca. Podemos poner un parche en el programa para “falsificar”


el valor de las variables que intervienen en la línea 3000:

5000 choque=l
5100 RETURN

Ejecute ahora el programa. El avión no vuela mucho, pero podemos comprobar


que la subrutina 4000 funciona. Comprobemos también que el bucle de la 3000 ter­
mina cuando el avión está al final de la pista:

5000 avionx=39:aviony-20
5100 RETURN

El programa está casi completo, a falta de la subrutina 5000, que será la encargada
de controlar cada ciclo del juego. Si observamos la pantalla tal como está al princi­
pio del juego, vemos que lo primero que hay que hacer es borrar el avión de la posi­
ción inicial; después tenemos que:
1) Desplazar el avión y comprobar que su nueva posición no está ocupada por un
edificio.
2) Si lo está, visualizar una explosión y hacer choque igual a 1 para que el juego
termine.
3) Si hay una bomba cayendo, dibujarla a la altura correcta y visualizar su choque
con los edificios o contra el suelo cuando haga falta.
4) Si el jugador pulsa la tecla ‘b’ y no hay ninguna bomba cayendo, soltar una.
Para que el juego esté más correlacionado con el nivel de habilidad, podemos intro­
ducir la siguiente función:
5) Hacer una pausa entre cada dos movimientos cuya duración dependa del nivel
de habilidad.
Las acciones 1) y 5) se realizan en todos los casos, así que las programaremos en
la subrutina 5000. Las demás dependerán de las circunstancias; son suficientemente
complicadas como para que las releguemos a otras subrutinas. En los capítulo ante­
riores las sentencias IF ... THEN han llegado a ser muy complejas porque quería­
mos que las instrucciones que venían después de THEN cupiesen completas en una
línea. Si ponemos todas esas instrucciones en una subrutina, las líneas serán más
cortas y más fáciles de entender y depurar:

4999 REM rutina principal de juego - comienza po


r borrar el avión
5000 LOCATE avionx,aviony
5010 F'RINT"
5011 REM mover avión
5020 avionx=avionx+1
5021 REM bajar el avión una linea si ha alcanzad
o el borde derecho
166 Programación BASIC con Amstrad

5030 IF avionx>39 THEN avionx=l:aviony=aviony+l


5031 REM calcular coordenadas gráficas de la nue
va posición del morro del avión
5040 aviongx=8+avionx*16
5050 aviongy=8+(25-aviony)*16
5060 color=TEST(aviongx,aviongy)
5061 REM -fulminar el avión si se detecta un edi-f
icio
5070 IF color<>0 THEN GOSUB 6000:RETURN
5071 REM mover la bomba si esta cayendo
5080 IF bomba=l THEN GOSUB 7000
5081 REM examinar teclado
5090 respuesta$=INKEY$
5091 REM no dejar caer la bomba si hay otra caye
ndo
5100 IF respuesta$="b" AND bomba=0 THEN GOSUB 80
00
5101 REM dibujar avión en la nueva posición
5110 PEN 1
5120 LOCATE avionx,aviony
5130 PRINT avión*;
5131 REM hacer pausa de 0 a 3 centesimas de segu
ndo
5140 tiempoinicial=TIME
5150 WHILE TIME<tiempoinicial +10-habi1 i dad
5160 WEND
5170 RETURN
5999 REM volar avión
6000 REM lo completaremos mas adelante
6100 RETURN
7000 REM lo completaremos mas adelante
7100 RETURN
8000 REM lo completaremos mas adelante
8100 RETURN

Observe la línea 5070: ésta es la primera vez que ponemos más de un RETURN en
una subrutina. El significado de la línea 5070 es: “si el avión ha chocado, ir a la
subrutina 6000; al retornar, terminar también esta subrutina”. Después de todo,
si el avión ha chocado el juego tienen que terminar; no debemos perder el tiempo
realizando las acciones 3) a 5).
La fórmula de la línea 5040 no es la que antes utilizábamos para calcular la coor­
denada gráfica X. El avión está formado por dos caracteres; la coordenada avionx
es la coordenada de texto del carácter de la izquierda. Si en TEST ponemos las
coordenadas del centro de la siguiente posición de texto, lo que estamos comproban­
do es el color del morro del avión. La fórmula de la línea 5040 tiene esto en cuenta
y realiza el cálculo correcto.
Planificación de un programa 167

Ejecute el programa. Ahora podemos probar y depurar esta rutina de movimien­


to del avión. Este se desplaza de izquierda a derecha correctamente, pero cuando
choca con un avión, línea 5070, continúa como si tal cosa; esto se debe a que todavía
no hemos desarrollado la subrutina 6000, cuya misión sera hacer ‘choque’ igual a 1:

60(30 choque=l

Ejecute ahora el programa. Cuando el avión choca con un edificio, el juego termina
y el ordenador nos informa del bajo tanteo obtenido.
También debemos comprobar que el programa funciona bien cuando consegui­
mos aterrizar con el avión. La forma más sencilla de hacerlo es no dibujar ningún
edificio:

2143 BOTO 2250

Esta instrucción provoca el salto del programa a la línea especificada, impidiendo


así el dibujo de los edificios. Muchos programas utilizan indiscriminadamente la
instrucción GOTO (“ir a”), y esto los hace difíciles de seguir y depurar. GOTO
tiene sus aplicaciones, como en este caso, pero es una instrucción que se debe prodi­
gar lo menos posible. Nosotros preferimos utilizarla solamente como ayuda en la
depuración de programas; en este caso la borraremos en cuanto comprobemos el
funcionamiento de la subrutina 5000.
Hemos empezado a desarrollar la subrutina 6000, así que vamos a completarla:

5999 REM fulminar el avión


6000 LOCATE avionx,aviony
6010 PRINT expl$;
6011 REM destellos de colores
6020 INK 3,6,26
6021 REM indicador de si el avión ha chocado
6030 choque”1
6040 RETL'RN

Ejecute el programa para comprobar que esta sección funciona.


Vamos a ocuparnos de la subrutina 8000, que deja caer la bomba:

7999 REM dejar caer la bomba cuando se ha pulsad


o ’b’
8000 bomba;: =avionx
8001 REM la bomba debe estar una linea mas abajo
que el avión
8010 bombay=avi ony+■ 1
8011 REM no dejarla caer si el avión esta en la
h i erba
8020 IF bombay>20 THEN RET'JRN
8021 REM indicador de que la bomba esta cayendo
168 Programación BASIC con Amstrad

8030 bomba=l
8031 REM dibujar la bomba en su posición de part
i da
8040 LOCATE bombax,bombay
8050 PEN 1
8060 PRINT bombaí;
8070 RETURN

Ejecute el programa y compruebe que efectivamente se puede disparar la bomba.


Quedará suspendida en el aire y será imposible disparar otras porque la variable
‘bomba’ está a 1. Esto demuestra que las condiciones de la línea 5100 son las nece­
sarias para impedir el disparo de una bomba mientras hay otra cayendo y que la su­
brutina 8000 funciona correctamente.
La subrutina 7000 controla la caída de la bomba. Será similar a la 5000, que con­
trola el movimiento del avión:
1) Bajar la bomba y comprobar si en la nueva posición hay un edificio.
2) Si la bomba a alcanzado un edificio, visualizar una explosión, poner a 0 la varia­
ble ‘bomba’ y terminar la subrutina.
3) En caso contrario, dibujar la bomba en la nueva posición.
Análogamente a lo que ocurría en 5000, las acciones 1) y 3) serán las más frecuentes
y por eso las programaremos en esta subrutina. En cambio, 2) deberá ser relegada
a otra subrutina:

6999 REM rutina de caída de bomba - comenzar por


borrar la bomba
7000 LOCATE bombax,bombay
7010 PRINT"
7011 REM bajar la bomba una linea
7020 bombay=bombay+l
7021 REM calcular las coordenadas gráficas de la
nueva posición de la bomba
7030 bombagx=8+ (bombax-1) *16
7040 bombagy=8+(25-bombay)*16
7050 color=TEST(bombagx,bombagy)
7051 REM que estalle la bomba si se ha detectado
un edificio
7060 IF colorOO THEN GOSUB 9000: RETURN
7061 REM dibujar la bomba en la nueva posición
7070 PEN 1
7080 LOCATE bombax,bombay
7090 PRINT bombad;
7100 RETURN
9000 REM lo completaremos mas adelante
9100 RETURN
Planificación de un programa 169

Comparando esta subrutina con la 5000 se puede comprobar que son muy pareci­
das. Ejecute el programa. La bomba ya no se queda paralizada, sino que continúa
cayendo hasta que choca con un edificio o contra el suelo. No podemos disparar
más bombas porque no hemos escrito la subrutina 9000. Una de sus misiones será
poner a cero la variable ‘bomba’ para permitir el disparo de la siguiente:

9030 bomba--0

La subrutina 7000 parece funcionar bien, aunque la bomba se queda en la pantalla


porque borrarla es misión de la subrutina 9000. Otra cosa que tiene que hacer la
subrutina 9000 es visualizar una explosión en el punto de choque de la bomba. Si
el choque se ha producido contra un edificio, tenemos que actualizar el tanteo:

9000 REM escribiremos esta linea enseguida


9001 REM dibujamos la explosion y hacemos que de
stelle rápidamente
9010 LOCATE bombax,bombay
9020 INK 1,0,6
9030 PEN 1
9040 PRINT expl$;
9041 REM devolver pluma a lo normal
9050 INK 1,0
9051 REM la bomba ya no cae - poner a cero el in
di cador
9060 bomba==0
9061 REM incrementar tanteo si se la bomba ha al
cansado un edificio
9070 IF color=3 THEN tanteo=tanteo+1
9071 REM borrar la explosion
9080 LOCATE bombax,bombay
9090 PRINT"
9100 RETURN

Al ejecutar el programa descubrimos un error lógico: cada vez que la bomba llega
al suelo, la pantalla se desplaza hacia arriba. Esto ocurre porque dibujamos la ex­
plosión cuando ‘bombay’ es 21, y eso está fuera de la ventana. El problema se re­
suelve fácilmente de la siguiente forma:

8999 REM volver a meter la bomba en la ventana s


i se sale
9000 IF bombay>20 THEN bombay=20

Ejecutando el programa unas cuantas veces podríamos convencernos de que no


quedan errores importantes. Pero no seamos tan optimistas: todavía no hemos pro­
bado el programa en todas las condiciones posibles. De hecho, quedan errores.
Uno que el lector puede haber descubierto es el siguiente: cuando el avión está
170 Programación BASIC con Amstrad

inmediatamente por encima de un edificio en el momento de disparar la bomba, ésta


destruye varios bloques del edificio, no uno sólo. El problema está en la rutina
8000, en la que no hemos previsto esta posibilidad. Tenemos que comprobar el co­
lor de la nueva posición de la bomba en todos los casos, aun cuando acabemos de
dispararla. Para ello podríamos repetir las líneas 7030 a 7060 en la subrutina 8000,
pero hay otra forma mejor de hacerlo.
Una de las ventajas de las subrutinas es que nos permiten subdividir el programa
en trozos manejables. Otra ventaja muy importante es que una misma rutina puede
ser utilizada por diversas secciones del programa. En lugar de tener un grupo de
líneas repetido varias veces a lo largo del programa, podemos poner esas líneas en
una subrutina e invocar la subrutina cada vez que la necesitemos. Esto es justamen­
te lo que vamos a hacer ahora. En la figura 34 vemos que hay dos subrutinas con
necesidades comunes a ambas.

Figura 34. Subrutinas.

Vamos a quitar las líneas que calculan las coordenadas gráficas y a ponerlas en
una subrutina que empiece en la línea 10000. Esta subrutina tendrá que ser invoca­
da desde las subrutinas 7000 y 8000:

7020 bombay=bombay+1
7021 REN calcular coordenadas gráficas de la nue
va posición de la bomba
7030 GOSUB 10000
70S1 REM que estalle la bomba si se ha detectado
un edificio
7060 IF colorOB THEN GOSUB 9000:RETURN
8030 bomba=l
8031 REM dibujar la bomba en su posición de part
ida
3035 GOSUB 10000
8036 IF colorOB THEN GOSUB 9000:RETURN
8040 LOCATE bombax,bombay
9100 RETURN
10000 bombagx=8+-(bomba;:-1) *16
Planificación de un programa 171

10010 bombagy=8+(25-boínbay) *16


10020 color=TEST(bombagx,bombagy)
10030 RETURN

La forma más rápida de comprobar que esto a corregido el defecto es dibujar todos
los edificios con la altura máxima:

2182 altura=18

Ejecute el programa y dispare varias bombas. Sólo se destruye el bloque superior


del edificio, luego el problema está resuelto.
Ahora deberíamos comprobar todo el resto del programa, porque frecuentemente
al corregir un error se introducen otros nuevos.
Aunque la subrutina 10000 ha corregido el defecto, las subrutinas 7000 y 8000 tie­
nen más tareas comunes que el cálculo de las coordenadas gráficas. Intente poner
en la subrutina 10000 todas las líneas que son similares en las subrutinas 7000 y
8000.

Resumen

Lamentablemente, en un libro dedicado a describir y explicar las instrucciones de


BASIC no es posible dedicar al tema de la planificación de programas el espacio que
merece. La principal conclusión que debemos deducir de este ejemplo es que la pla­
nificación permite identificar y preparar las subrutinas en que se debe dividir el pro­
grama. Las subrutinas se escriben entonces una a una, lo que da la oportunidad
de probarlas y depurarlas antes de pasar a la siguiente. Los errores restantes serán
los que surjan al ensamblar unas subrutinas con otras y resultarán más fácil de
detectar.
Los diagramas también son de gran ayuda en la planificación de programas. Hay
métodos sistemáticos para la elaboración de diagramas; en general basta con escribir
la descripción de los diversos bloques de acciones en unos rectángulos e iñterconec-
tar los rectángulos con líneas que indiquen qué subrutinas llaman a qué otras. Es
conveniente analizar el plan del programa para determinar qué acciones se pueden
programar con una sucesión de líneas, cúales se deberán realizar con bucles y dónde
habrá que tomar decisiones; de este análisis se suele deducir qué funciones son sus­
ceptibles de ser encomendadas a subrutinas.
No se deje desanimar por los inevitables errores. En el programa que hemos desa­
rrollado no ha funcionado completo al primer intento, pero al dividirlo en subpro­
gramas nos nos ha sido difícil depurarlo.

Ejercicios

1. Modifique el programa anterior para que visualice y mantenga actualizado un


tanteador a lo largo del juego.
172 Programación BASIC con Amstrad

2. Limite el número de bombas disponibles, en función del nivel de habilidad. Man­


tenga informado al jugador del número de bombas restantes. (El número y altu­
ra de los edificios imponen un mínimo al número de bombas; con menos bombas
el avión no podrá llegar a aterrizar.)
3. Permita que el jugador pueda disparar una megabomba cuyo efecto sea destruir
completamente el edificio sobre el que caiga. (No olvide que tendrá que ajustar
el tanteo en función de la altura del edificio.)
4. Reescriba el programa de juego para dos jugadores del capítulo 8 de forma que
quede estructurado en subrutinas.
10

Música y sonidos

Un aspecto que hemos omitido completamente en nuestros programas anteriores es


el sonido. Las funciones de sonido del Amstrad son muy completas. Si le interesa
la generación de música con el ordenador, en los apéndices del Manual del Usuario
encontrará información muy completa sobre las instrucciones de sonido. Producir
notas aisladas de una frecuencia determinada es muy sencillo. El siguiente progra­
ma facilita la experimentación con la instrucción SOUND:

5 ON BREAK GOSUB 500


10 MODE 1
20 GOSUB 1000
30 GOSUB 2000
200 GDSUB 500
300 END
500 MODE 1
505 INK 1,24
510 PEN 1
520 PAPER 0
530 END
1000 PAPER 1
1010 CLS
1020 PEN 3
1030 PRINT"Este programa le da una oportunidad d
e"
1040 PRINT"experi mentar con la orden SOUND."
1050 PRINT
1060 PRINT"Pulse cualquiera de las teclas 1 a 7"
1070 PRINT"para poner a cero el canal."
1030 PRINT
1090 PRINT"Pulse ’s’ para subir el tono de la no
ta"
1100 PRINT"y ’1’ para bajarlo."
1110 PRINT
1120 PRINT"Pulse ’f’ para terminar."
1130 PRINT
1140 PRINT"La orden SOUND estara siempre en la"

173
174 Programación BASIC con Amstrad

1150 PRINT"pantal 1 a para que usted la observe al


II
1160 PRINT"mismo tiempo que la escucha."
1170 PRINT
1180 INPUT"Pulse ENTER cuando este preparado. ",e
nter
1190 RETURN
2000 PEN 1
2010 PAPER 0
2020 CLS
2030 CLS
2040 respuesta^“ "
2050 tono=478
2060 canal=1
2070 x=4
2080 canalx=10
2090 tonox=12
2100 y=12
2110 INK 1,0
2120 PEN 3
2130 LOCATE x,y
2140 PRINT"SOUND";
2150 WHILE respuestas >"-f "
2160 respuesta$=""
2170 WHILE respuesta$=""
2180 respuestas INKEY$
2190 WEND
2200 codi go=ASC(respuestas
2210 IF codigo>48 AÑD codigo<56 THEN canal=codig
o-48
2220 IF codigo=98 AND tono<4000 THEN tono=tono+l
2230 IF codigo=115 AND tono>100 THEN tono=tono-l
2240 PEN 1
2250 LOCATE canalx,y
2260 F'RINT canal;
2270 PEN 3
2280 LOCATE tonox,y
2290 PRINT tono;
2300 SOUND canal,tono
2310 WEND
2320 RETURN

El sonido es generado por la línea 2300. Los dos parámetros que siguen a la palabra
clave SOUND son obligatorios. El primero es el número de selección de canales.
El ordenador tiene tres canales de sonido: A, B y C. Cada combinación de canales
está representada por un número del margen 1-255. En la figura 35 se puede reco­
Música y sonidos 175

nocer la analogía entre estos números y los de la instrucción SYMBOL. Para selec­
cionar el canal A utilizaríamos el número 1; para el C, el 4. Pero para seleccionar
simultáneamente los canales A y C necesitamos la suma de 1 y 4, es decir, el 5. Para
seleccionar los tres, el número será 1+2+4, o sea, el 7.

2 3 3 £
c B A

Figura 35. Números de selección de canales.

A estos números se puede sumar otros mayores para controlar la sincronización


entre canales. El control completo de los canales no es difícil, pero queda fuera del
alcance de este libro. En cualquier caso, está bastante bien explicado en el Manual
del Usuario.
El segundo parámetro de SOUND establece el tono de la nota. El tono está
representado por un número del margen 0-4095. Cuanto menor es el número, más
aguda es la nota. En el apéndice VII del Manual del Usuario se da una lista comple­
ta de los números necesarios para generar las notas de varias octavas. Consulte esa
lista si pretende programar algo más que unas notas sueltas. En la línea 2050 del
programa se establece el número de tono en 478, que corresponde a la nota DO
media.
Usted puede variar la selección de los canales y el tono en el transcurso del progra­
ma. El número de tono se cambia de unidad en unidad en las líneas 2220 y 2230.
La amplitud de la variación se puede modificar fácilmente editando estas líneas.
Los números de tono están limitados al margen de 100 a 4000 para asegurar que no
se salen del margen permisible (0 a 4095), pero usted puede cambiar estos límites.
La duración de las notas es de aproximadamente 0.2 segundos.
El programa examina continuamente el teclado, línea 2200, y modifica la selec­
ción de canales o el tono si se pulsan las teclas adecuadas, líneas 2210 a 2230. Se
utilizan los códigos ASCII, pero también podríamos haber puesto la línea 2210 de
la siguiente forma:

2210 IF INSTR(respuesta»,"1234567")>0 THEN numer


□-■VAL (respuesta») : canal =numero

El programa muestra continuamente el número de selección de canales y el núme­


ro de tono para que el usuario pueda correlacionar fácilmente estos valores con los
efectos audibles.
176 Programación BASIC con Amstrad

Ejercicios

1. Escriba un programa que lea en las líneas DATA los datos necesarios pa­
ra interpretar una melodía sencilla utilizando repetidamente la instrucción
SOUND.
2. Incluya algunos sonidos en el juego para jugadores del capítulo 8. Haga so­
nar una nota por cada movimiento, con diferentes números de tono para cada
jugador. También utilizar un tono distinto para cada dirección de mo­
vimiento.
3. Modifique el programa del ejercicio anterior para que interprete una melodía
cuando un jugador choque con el otro o con una pared.

Parámetros opcionales

La instrucción SOUND puede llevar hasta 5 parámetros opcionales. Indican, res­


pectivamente, lo siguiente: la duración de la nota; el volumen; si el volumen de la
nota debe ser controlado por una envolvente de volumen; si el tono debe ser contro­
lado por una envolvente de tono; la cantidad de ruido que se debe mezclar con la
nota. Estudiaremos más adelante las envolventes de volumen y de tono. Por ahora
pondremos a cero estos parámetros para observar el efecto de los restantes. Añada
las siguientes líneas al programa anterior:

lili 'PRINT"Pulse ? £ ? para hacer la nota mas larg


a"
1112 PRINT"y ’d’ para hacerla mas corta."
1113 PRINT
1114 PRINT"Pul se ’ q’ para bajar el volumen"
1115 PRINT"y ’r’ para subí rio"
1116 PRINT
1117 PR INT"Pul se ’ n ’ para subir el nivel de ruid
o. "
1118 PRINT"y la barra espadadora para bajarlo."
1119 PRINT
2061 duraci on=20
2062 volumen=12
2063 rui do=0
2070 ,x=4
2030 canal :■: = 10
2090 tonox=12
2091 durad onx = 16
2092 volumenx=20
2093 rui dox =27
2141 LOCATE 23,y
2142 PRINT"0 0";
Música y sonidos 177

2360 LOCATE volumenx,y


2370 PRINT volumen;
2380 PEN 1
2390 LOCATE ruidox,y
2400 PRINT ruido;
2410 SOUND canal , tono, durac i on, vol umen, 0,0, rui do
2420 WEND
2430 RETURN
2231 IF codigo-105 THEN duracion=duracion+l
2232 IF codigo-100 THEN duracion=dLiracion-l
2233 IF codigo=113 AND volumen>0 THEN volumen=va
1umen-1
2234 IF codigo=114 AND volumen<15 THEN volumen-v
olumen+1
2235 IF codigo=110 AND ruido<31 THEN ruido=ruido
+1
2236 IF codigo=32 AND ruido>0 THEN ruido=ruido-1
2310 REM para borrar la antigua 2310
2320 PEN 1
2330 LOCATE duracionx,y
2340 PRINT duracion;
2350 PEN 3

Ahora el programa permite modifcar todos los parámetros y los exhibe en la


pantalla.
La duración de las notas se mide en centésimas de segundo; la línea 2061 establece
una duración de 0.2 segundos, que es la que el ordenador supondría si no incluyése­
mos este parámetro. El volumen puede variar entre 0 (silencio) y 15; en la línea 2062
establecemos el volumen estándar, 12. El ruido puede variar entre 0 y 31; el valor
por defecto es 0. Añadir ruido a una nota puede parecer contraproducente, pero
es la base de los efectos sonoros especiales.

Ejercicios

1. Introduzca en el programa del bombardero algunos efectos sonoros. Programe


una nota de duración adecuada, mezclada con ruido, para simular las explosio­
nes. Haga sonar una nota con cada movimiento del avión, pero de forma que
la duración esté en función del nivel de habilidad para que el programa no resulte
indebidamente lento. Aumente el tono de la nota cada vez que el avión baja una
línea.
178 Programación BASIC con Amstrad

La envolvente de volumen

La envolvente de volumen controla la forma en que el volumen varía durante el


tiempo que está sonando la nota. Se pueden definir hasta 15 envolventes distintas.
Una vez definida una envolvente, el ordenador almacena sus características hasta
que se lo desconecta. Para utilizar una envolvente, se cita su número como quinto
parámetro en la instrucción SOUND. Por ejemplo, SOUND 1,478,20,12 hace so­
nar la nota DO media por el canal A durante 0.2 segundos a volumen 12. Al incluir
como quinto parámetro el número 3, SOUND 1,478,20,12,3 hace sonar la misma
nota, pero ahora el 12 especifica sólo el volumen inicial; la evolución del volumen
con el tiempo es controlada por la envolvente de volumen número 3, que habrá sido
definida con anterioridad.
Añada al programa las siguientes líneas, con las que podrá definir envolventes de
volumen y observar sus efectos:
15 GOSUB 600
600 F'RINT"Esta subrutina le permite definir una"
610 F'RINT"envol vente de volumen antes de probar"
620 F'RINT"di f erentes notas con ella."
630 F'RINT
640 INF'UT" Numero de envolvente (1--15) " ; envol vent
e vol
650 INF’UT"Numero de escalones (0-27)numescvol
660 INF’UT" Al tura de escalón (--128 - +127)";altes
cvol
670 INF'UT"Ti empo de pausa (0-255)";pausavol
680 ENV envolventevol,numescvol,altescvol,pausav
ol
690 F'RINT
700 INF'UT "Pulse ENTER para continuar",enter
710 RETURN
2121 LOCATE x , y-2
2122 F'RINT"ENv" ; envo'l ventevol ; " , " ; numescvol ; " , " ;
altescvol;",";pausavol
2410 SOUND canal,tono,duracion,volumen,envolvent
evol,0,rui do

La forma de la envolvente de volumen es la siguiente:


ENV número de la envolvente,número de escalones,altura de cada escalón,
tiempo de pausa.
El número de envolvente es aquél por el cual se la invoca en la instrucción
SOUND.
El número de escalones especifica en cuántas etapas queremos que evolucione la
nota.
Música y sonidos 179

La altura de cada escalón especifica la variación del volumen con respecto al esca­
lón anterior.
El tiempo de pausa especifica la duración de cada escalón en unidades de centési­
mas de segundo.
Por ejemplo, ENV 1,100,-5,1 describe una envolvente compuesta por 100 etapas
de una centésima de segundo cada una, con un descenso de volumen de una a otra
de 5 unidades. A pesar de que el volumen de la nota está controlado por la envol­
vente, para apreciar la envolvente completa la duración especificada en SOUND tie­
ne que ser suficiente. Así, con SOUND 1,478,20,12,1 perderíamos parte del efecto
ENV 1,100, - 5,1 ya que la envolvente dura 1 segundo (100 centésimas) y en SOUND
hemos especificado una duración de sólo 0.2 segundos (20 centésimas).
La mejor forma de comprender los efectos de las envolventes de volumen es expe­
rimentar con el programa anterior. Defina una envolvente de volumen y ejecute
una orden SOUND adecuada; así podrá apreciar cómo afecta la envolvente a la nota
resultante. Vaya cambiando después los parámetros uno a uno, por ejemplo, el to­
no o el nivel de ruido, y observe los diferentes efectos. Cuando consiga algún efecto
interesante, tome nota de todos los parámetros de ENV y SOUND con los que lo
ha producido. En poco tiempo elaborará un amplio catálogo de efectos sonoros
que más tarde puede incorporar a otros programas. En el capítulo siguiente explica­
remos cómo se pueden grabar estos datos en cinta.

La envolvente de tono

La estructura es semejante a la de la envolvente de volumen:


ENT número de la envolvente,número de escalones,altura de cada escalón,
tiempo de pausa.
El número de envolvente puede variar también entre 1 y 15, pero ahora se pueden
poner números negativos para hacer que la envolvente se repita hasta el final de la
duración especificada en SOUND.
El número de escalones especifica en cuántas etapas queremos que evolucione la
nota.
La altura de cada escalón especifica la variación del tono con respecto al escalón
anterior.
El tiempo de pausa especifica la duración de cada escalón en unidades de centési­
mas de segundo.
Añada al programa las siguientes líneas, con las que podrá definir envolventes de
tono y observar sus efectos:

16 GDSUB 300
800 PRINVEsta subrutina le permite de-finir una"
310 PRINT"envolvente de tona."
320 PRINT
830 PRINT"Numero de envolvente (1..15, números ne
_. II

8-i5 INPUT " y at i vos para que sea de r epet i o i on) " ; e
nvolventetono
180 Programación BASIC con Amstrad

340 INPUT"Numero de escalones (0-239)numeseton


o
350 INPUT"Altura de escalón (-128 - +127)";altes
ctono
860 INPUT"Tiempo de pausa (0-255)pausatono
870 ENT envol vent:etor.o, numesctono, al tesetono,pau
satono
880 PRINT
890 INPUT "Pulse ENTER para continuar",enter
900 RETURN
2123 LOCATE x , y-4
2124 PRINT"ENT"; envolventatone;", " ;numesctono;",
" ; al tesatone;","; pausatone
2410 SOUND canal,tono, duraci on,volumen,envol vent
evol,ABS(envolventetono),ruido

Al experimentar con envolventes de tono conviene no utilizar las de volumen para


no confundir sus efectos.
11

Ficheros

En este capítulo vamos a explicar cómo se puede utilizar el ordenador para grabar
datos en un fichero y luego recuperarlos. Un fichero de ordenador es muy similar
al tradicional fichero de fichas de cartulina: consiste en una serie de fichas o regis­
tros que contienen información homogénea. Los registros se dividen en campos.
Por ejemplo, en un fichero de clientes un registro es el conjunto de datos relativos
a un cliente determinado; los campos de que consta el registro son; nombre, señas,
número de teléfono, saldo de su cuenta, etc.
Lo habitual es disponer de un programa que crea el fichero y lo graba en la cinta.
Otro programa puede encargarse de recuperar el fichero, ampliarlo o modificarlo
y luego volver a grabarlo. Las operaciones típicas que se realizan con los ficheros
son, pues, las siguientes:
1) Grabar un fichero en cinta.
2) Cargar un fichero en la memoria del ordenador leyéndolo de la cinta.
3) Añadir nuevos registros al fichero.
4) Borrar registros.
5) Modificar registros.
En un sistema de archivo en cinta, como es el del Amstrad, es teóricamente posi­
ble manejar los registros uno por uno, pero ello requiere tal manipulación de cintas,
que en la práctica el método es inviable.
Lo que vamos a hacer es grabar y leer ficheros completos, en vez de registros aisla­
dos. Una vez cargado un fichero en la memoria, podremos consultarlo, ampliarlo
o modificarlo, y luego lo volveremos a grabar completo en la cinta. Bastará con
dos cassettes como máximo: una para leer la versióri antigua del fichero; la otra para
recibir la versión actualizada.
Todas estas ideas quedarán más claras cuando las ilustremos con un ejemplo. Va­
mos a desarrollar un sistema de archivo de nombres y números de teléfono.

Creación del fichero

El fichero se puede crear con el siguiente programa:

10 MODE 1
20 GOSUB 1000
30 GOSUB 2000

181
182 Programación BASIC con Amstrad
60 END
1000 PRINT“Puede usar este programa para crear u
n"
1010 PRINT"fichero de nombres y números de tele-
II
1020 PRINT"fono. La técnica es de ínteres genera
1,"
1030 PRINT"por lo que usted puede adaptar el pro

1040 F'RINT"grama a cualquier tipo de datos."


1050 PRINT
1070 PEN 2
1080 PRINT"Dentro de un momento le pedire los no
m- "
1090 PRINT"bres y números de telefono de sus"
1100 PRINT"amigos. Escríbalos y, cuando quiera"
111.0 PRINT"acabar, introduzca xxx,xxx . "
1120 PRINT
1130 PRINT"Los datos serán grabados en cinta."
1140 PRINT"Ponga en el magneto-fono una cinta"
1150 PRINT"virgen. Yo le avisare cuando deba"
1160 PRINT"pulsar los botones de RECORD y PLAY."
1170 PRINT
1100 INF'UT"Pulse ENTER cuando este preparado. ",e
nter
1190 RETURN
t-j t o

000 CLS
010 INF’UT"C!ue nombre quiere dar a este fichero
";f i chero*
t-j w r-j

020 OPENOUT fichero*


030 PRINT"Escriba un nombre y un numero de "
040 F'RINT"telefono. "
050 PRINT
j t

060 PEN 3
j tj

070 INPUT"Nombre, numero de telefono:


r

",nombre*,telef ono*
080 WHILE nombre*<>"xxx "
j f j tj

090 WRITE #9,nombre*,telefano*


100 PRINT
t-j t

110 INPUT"Nambre, numero de telefono:


",nombre*,telefono*
M t-j M t j t-j

120 WEND
130 CLOSEOUT
140 PRINT
150 PEN 1
160 FRINT"Sus datos han sido grabados en cinta.
Ficheros 183

2170 PRINT"ñhora puede leer los datos del ficher


o"
2180 PRINT"con el siguiente programa. "
2190 RETURN

La subrutina de la línea 1000 explica al usuario el manejo del programa. La de la


línea 2000 crea el fichero y graba los datos en él. El procedimiento es muy sencillo.
En la línea 2010 se capta por el teclado el nombre del fichero. La línea 2020 lo abre
con OPENOUT (“abrir en dirección de salida”) y lo deja preparado para recibir
los datos.
Los datos son captados y enviados a la cinta por el bucle de las líneas 2080 a 2120.
La línea 2090 contiene la instrucción WRITE #9 (write significa “escribir”), con
la que se escriben los datos en la cinta. En realidad, el ordenador no graba los datos
en la cinta inmediatamente después de captarlos, sino que los guarda temporalmente
en una zona de la memoria reservada al efecto y denominada tampón. Cuando se
llena el tampón es cuando se realiza el proceso físico de la grabación en cinta.
La línea 2130 es muy importante. Informa al ordenador de que hemos terminado
de preparar datos y queremos que cierre el fichero. Como consecuencia de esta ins­
trucción, el ordenador vacía los datos que puediera haber en el tampón y los graba
en la cinta.
Una vez creado el fichero, podemos apagar el ordenador, sabiendo que aunque
se borre la RAM, los datos están a salvo en la cinta.

Lectura del fichero

Vamos a ampliar el programa anterior para que lea el fichero inmediatamente des­
pués de crearlo. No es esto lo que haríamos en la práctica, pero nos demostrará
que el fichero ha quedado grabado:

40 GOSUB 3000
50 SOS'JB 4000
3000 FEN 2
3010 PRINT
3020 PRINT"Este programa sirve para cargar en"
3030 PRINT"memori a un fichero grabado en cinta."
3040 PRINT
3050 PEN 2
3060 PRINT"Fonga en el magneto-fono la cinta en 1
a"
3070 PRINT"que este al fichero.".
3080 PRINT
3070 INPUT"Pulse ENTER cuando este preparado. ",e
nter
3100 RETURN
184 Programación BASIC con Amstrad

400(3 CLS
4010 INPUT'"Como se llama el fichero
";nombreficherot
4020 OPENIN nombref i cherot>
4030 PRINT"Esta es la lista de todos los nombres
y"
4040 PRINT"numeros de telefono:"
4050 WHILE NOT EOF
4060 INPUT #9,amigo$,telefono$
4070 PRINT
4080 PRINT amigoS,telefono^
4090 WEND
4100 CLOSEIN
4110 PRINT
4120 PRINT"Eso es todo!"

Para que el ordenador pueda leer el fichero, tiene que saber cómo se llama (línea
4010). Como vamos a leer del fichero, tendremos que abrirlo en dirección de entra­
da (OPENIN, línea 4020).
No es probable que recordemos cuántos datos hemos grabado en el fichero. Enton­
ces ¿cómo sabe el Amstrad cuántos datos tiene que leer?
Muy sencillo: le diremos que lea datos hasta que llegue al final del fichero. El
ordenador graba automáticamente al final de cada fichero una “señal de fin de fi-
chero”(EOF). No nos interesa demasiado cómo lo hace; nos basta con saber que
podemos aprovechar esa señal. Las líneas 4050 a 4090 equivalen a lo siguiente:
WHILE (mientras) no se haya alcanzado el final del fichero (EOF)
leer un registro
y escribirlo
WEND
INPUT #9 es la instrucción con la que se lee de la cinta.
Ya hemos leído el fichero, pero nos encontramos con que hemos perdido todos
los registros menos el último. Cada vez que la línea 4060 lee un registro , el ordena­
dor “olvida” los valores anteriores de amigo$ y telefonoS. ¿Cómo podemos leer
el fichero y almacenar al mismo tiempo los datos en la memoria para después exami­
narlos con tranquilidad?
Tenemos que asignar los datos a elementos de un par de listas según los vayamos
leyendo:

4000 CLS
4010 INPL!T"Como se llama el fichero
";nombref i cheroí
4015 DIM ami go$ (100) , tel ef oriol (100)
4016 cuenta=l
4020 OPENIN nombreficheroí
4030 PRINT"Esta es la lista de todos los nombres
y"
Ficheros 185
4043 PRINT"números de telefona:”
4050 WHILE NOT EOF
4060 INPUT #9, ami go$ (cuenta) , tel e-fonoS (cuenta)
4070 PRINT
4000 PRINT amigo$(cuenta),telefonoí(cuenta)
4005 cuenta-cuenta+1
4090 WEND
4100 CLOSEIN
4110 PRINT
4120 PRINT"Eso es todo!"

La línea 4015 dimensiona las listas para que puedan contener hasta 100 nombres y
números de teléfono. Podríamos haberlas hecho más grandes, pues el único límite
es el impuesto por la capacidad de memoria.
El programa utiliza un contador para llevar la cuenta del número de registros leídos
y al mismo tiempo para hacer de subíndice en amigo$() y telefono$(). Cuando ter­
mina la lectura del fichero, toda la información ha quedado almacenada en estas
dos listas.
Ya hemos visto en un capítulo anterior cómo se puede buscar un elemento en una
lista. En el programa del restaurante de comida rápida, el usuario escribía el nom­
bre del artículo y el programa lo buscaba en la lista. El precio se encontraba en el
elemento de igual subíndice de la lista de precios.
Podríamos utilizar la misma técnica para buscar el número de teléfono después
de captar por el teclado un nombre. Pero en vez de seguir ampliando el programa
vamos a reorganizarlo.

Programa controlado por menú

El siguiente programa utiliza el fichero de nombres y números de teléfono y demues­


tra cómo se puede manipular el fichero y volver a grabarlo después de modificado.
Este programa puede ser adaptado para que controle cualquier otro tipo de ficheros.
El programa tiene que pedir al usuario que elija una de las varias opciones que
puede ofrecerle; en casos como éste lo más conveniente es ofrecer las opciones en
forma de menú-.

10 MODE 1
20 GDSUB 1000
30 END
1000 respuestas-""
1010 cargafichero=0
1020 WHILE respuesta^ >"5"
1030 PEN 3
1040 PRINT
1050 PRINT"Elija 1 - 5:"
1060 PEN 1
186 Programación BASIC con Amstrad

1070 FRINT:FRINT"1. Cargar fichero"


1080 PRINT: F'RINT"2. Grabar f i chero"
1090 PRINT:FRINT"3. Buscar en el fichero"
1100 PRINT:PRINT"4. Corregi r fichero"
1 1 10 PRINT:PRINT"5. Fin"
1120 PRINT
1130 PEN 3
1140 PRINT"Cual?"
1150 WHILE respuesta*-"": re spuesta*=INKEV*:WEND
1160 IF respuesta!= "1" THEN GOSUB 2000
1170 IF respuesta*= "2" THEN GOSUB 3000
1180 IF respuesta*= "3" THEN GOSUB 4000
1190 IF respuesta*= "4" THEN GOSUB 5000
1200 IF respuesta*«: >"" THEN CLS
1210 IF respuesta*«: >"5" THEN respuesta*«=" "
1220 WEND
1230 RETURN

En un programa más complejo, el menú principal conduciría a una serie de sub­


menúes, en los cuales se ofrecerían al usuario nuevas opciones. Se suele procurar
que el usuario no tenga que escribir mucho para realizar la elección; lo idóneo es
que baste con que pulse una tecla. Las opciones suelen estar numeradas, como en
este caso.
La subrutina 2000 carga el fichero:

2000 CLS
201’0 INPUT"Cual es el nombre del fichero
"; f i chero*
2020 cuenta=l •
2030 IF cargafichero=l THEN ERASE nombre!,telefo
no*
2040 DIM nombre!(100),telefono!(100)
2050 OPENIN fichero*
2060 WHILE NOT EOF
2070 INF'UT #9, nombre! (cuenta) , tel ef ono* (cuenta)
20S0 cuenta=cuenta+l
2090 WEND
2100 CLOSEIN
2110 FRINT
2120 F'EN 2
2130 F'RINT"E1 fichero ha quedado cargado."
2140 INF'UT "Ful se ENTER para volver al menu.",ent
er
21.50 cargafichero=l
2160 RETURN
Ficheros 187

Estas instrucciones son similares a las correspondientes en el programa de la sección


anterior. Hemos incluido la línea 2030 por si queremos volver a utilizar la subrutina
para leer otro fichero. Cuando se ha ejecutado una vez la rutina, el ordenador ya
“conoce” las listas nombre$() y telefono$(), y entonces la línea 2040 provoca un
error. La línea 2150 pone a 1 la variable ‘cargafichero’ para que cuando se vuelva
a ejecutar la línea 2030 la orden ERASE borre las listas y la línea 2040 no dé
problemas.
La subrutina 3000 graba el fichero:

3000 CUS
3010 INPUT"Cual es el nuevo nombre del -fichero
" ,i icherot
3020 OPENOUT -fichero»
3030 contador“1
3040 WHILE contador<cuenta
3050 WRITE #9,nombre»(contador),telefono»(contad
or)
3060 contador=contador+l
3070 WEND
3080 CLOSEOUT
3090 PRINT
3100 PEN 3
3110 PRINT"E1 fichero ha quedado grabado."
3120 INPUT"Pulse ENTER para volver al menu.",ent
er
3130 RETURN

La subrutina 4000 busca en la lista el nombre captado por el teclado:

4000 CLS
4010 INPUT"De quien quiere el telefono
";ami go»
4020 contador=l
4030 encontrado=0
4040 WHILE contador(cuenta AND encontrado=0
4050 IF amigo»=nombre»(contador) THEN encontrado
=1:PRINT"E1 telefono de ";amigo»;" es ";tel
efono»(contador)
4060 contador“contador+1
4070 WEND
4080 IF encontrado-© THEN PRINT amigo»;" es dése
onocido para mi."
4090 PRINT
4100 INPUT"Pulse ENTER para volver al menu.",ent
er
4110 RETURN
188 Programación BASIC con Amstrad

El ordenador busca hasta que encuentra el nombre en la lista o hasta que la ha reco­
rrido entera sin éxito. La línea 4080 es útil porque informa al usuario de lo que ha
ocurrido; despúes de todo, no es tan difícil equivocarse al escribir un nombre.
La subrutina 5000 permite modificar números de teléfono; utiliza un método de
búsqueda similar al anterior:

5000 CLS
5010 INPUT"Nombre cuyo telefono quiere cambiar:
",ami
5020 contador=1
5050 encontrado--0
5040 WHILE contadorícuenta AND encontrado=0
5050 IF amigo$=nombre$(contador) THEN encontrado
=1:INPUT"Cual es el nuevo numero";telefono$
(contador)
5060 contador=contador+1
5070 WEND
5080 IF encontrado^ THEN PRINT amigo$;" es dése
onocido para mi."
5090 PRINT
5100 INPUT"Pülse ENTER para volver al menu.",ent
er
5110 RETURN

Con esto queda completo el esqueleto del programa; usted puede añadirle ahora los
refinamientos que guste.

Ejercicios

1. Este último programa sólo funciona con ficheros ya existentes. Añádale una su­
brutina para que pueda crear ficheros nuevos. Aplique UPPER$ o LOWERS
a las cadenas que grabe en el fichero para que luego no haya problemas a la hora
de buscar nombres en las listas.
2. Añada una rutina que permita al usuario repasar rápidamente el fichero; debe
aparecer en la pantalla un registro cada vez que se pulse una tecla.
3. Incluya una rutina que permita añadir nuevos registros o suprimir otros.
4. Reescriba el programa para adaptarlo a otro tipo de datos.

CONCLUSIÓN

Esperamos que este libro haya aclarado algunas de sus dudas sobre el ordenador
Amstrad. No es posible llegar a saberlo todo acerca de un ordenador, como de­
muestra la proliferación de revistas de informática que se observa en los quioscos.
Todos los meses alguien descubre una solución nueva para un antiguo problema,
o una capacidad insospechada en el ordenador.
Ficheros 189

En el limitado espacio de que disponíamos, hemos tratado de presentar y explicar


el mayor número posible de instrucciones del BASIC del Amstrad. Hay omisiones,
inevitablemente. En algunos casos podríamos habernos extendido mucho más; por
ejemplo, de las instrucciones gráficas sólo hemos explicado lo más elemental. Pero,
por otra parte, tampoco se puede hablar de todo en un libro de introducción como
es este.
Si usted quiere profundizar en el conocimiento de su ordenador, por ahora no hay
más información oficial que el Manual del Usuario (aparte del Manual del Firmwa­
re, que no habla de BASIC, sino del sistema operativo). Hay otros libros de nivel
más o menos equivalente al de éste y muy pronto se publicará una revista dedicada
exclusivamente a este ordenador.
Para terminar, recuerde que todos los autores de libros y artículos de revistas han
sido alguna vez principiantes como usted. Lo que ahora le parece tan complicado
muy pronto le resultará increiblemente fácil. ¡Disfrute practicando!
Indice

Acciones condicionadas 87-97 copiado de líneas 21-23


Aritmética 35-37 COPY, tecla 6, 22, 111
ASCII, códigos 108-111, 130-131, CTRL, tecla 5-7, 55, 109
151-155 cursor 3-4, 21-23
tecla de repetición 154 de copia 22
gráfico 43, 141-143
Base de datos 99 de texto 3, 22
BASIC 3
Borde de pantalla 52-54 DATA 74-77, 82, 108
Bucles 68-86, 114-128 decisiones 87-90
anidados 108, 114-119 definiciones 153-156
control de 71-74 DEL, tecla 4, 6, 21
FOR ... NEXT 73, 80-81 depuración de programas 156-159
WHILE ... WEND 80-86, 97, 108 desplazamiento de la pantalla 11
Búsqueda y sustitución 102 diagramas 141
Dibujos 42-67
Cadenas literales 98-113 DIM 125
comparación 98 disparos 131, 145
concatenación 98 DRAW 43-44, 57, 64, 144, 145
longitud 100
Canales 174-175
CAPS LOCK, tecla 4, 5, 93 edición 21-22
Caracteres grandes 133, 134 elementos de listas 122
Caracteres no alfabéticos 108 END 99
Carga de programas 41 ENTER, tecla 4-15, 93
Cassette 1 ENV 179
Centrado de textos 101 envolvente de tono 179-180
CINT 77 envolvente de volumen 178-180
CLR, tecla 6, 21 errores 4-6, 20-21, 151, 156-159
codificación 110-111 corrección de 4-6
colores 44, 51-67, 146-150 lógicos 158-159, 169
coma 32, 101 ESC, tecla 6, 19, 55, 109
comillas 9, 101 espacios 7, 103
coordenadas 42
gráficas 42, 64, 140-143, 171 ficheros 181-189
de texto 64 FOR ... NEXT, bucle 73, 80-81, 119

191
192 Índice

GOSUB 159, 160 modo directo 17, 20, 28


GOTO 167 modo de programa 17, 20
grabación de programas 41 monitor 1
gráficas 141 MOVE 43, 64, 145
grupos de instrucciones 68 Movimientos relativos 143-145
música 173-180
IF ... THEN 87-93, 96, 97, 110, 165
IF ... THEN ... ELSE 91, 92 NEXT 115
incongruencia de tipos 158 número de línea 18-19
INK, número 51, 146-150 número de escalones 178
INKEY$ 93-94, 110 números aleatorios 77-80
INPUT 30-32, 72-73, 116 números decimales 129
en gráficos 49-51
INSTR 105-108 ON ERROR 157
instrucciones 68 OPENOUT 183
INT 77-78 Orden alfabético 98
Órdenes 6-8
juego de caracteres 108-111, 129 ORIGIN 143-145
no alfabéticos 108
juegos 129-150 Pantalla
borde 52
KEY 152-154 organización en modo 1 13-14
KEY DEF 154, 155 visualización en la 7-9, 11
PAPER 53-56
LEFTS 103 Papel 53-56
LEN 100-101 parámetros 174-177
LINE INPUT 32 obligatorios 174
líneas multi-instrucción 88, 89 opcionales 176
listas 119-124, 126-127, 183, 186 pausa 179-180
elementos 123-124, 126 PEN 53-56
LOCATE 24, 64, 69, 101, 133 pixel 46
PLOT 46, 145
matrices 119-128 Pluma 53-56
mayúsculas 99, 105, 110 polígonos 73
memoria 1-3, 26, 181 PRINT 6-11, 22
mensajes de error 20, 28 programación 17-41, 151-172
menú 185 organización 159-172
MID$ 103-104, 113 planificación 151-172
minúsculas 8, 28, 99, 105 punto y coma 132
MOD 150
Modo 0 8, 44, 53, 65 RAM (random access memory) 1-3,
Modo 1 8, 15, 44, 53 7, 44, 53, 183
organización de la pantalla READ 74-75
en 13-14 rebote, efecto de 97
zonas de escritura 14 rebotes 131, 145
Modo 2 8, 44, 53 Redondeo 77
Índice 193

registros 181, 184-185 TAG 141, 142, 162


REM 47, 161 tampón 182
RENUM 20 teclado 1, 3, 5
repetición de instrucciones 68 teclas
resolución 44, 141 del cursor 5
RESTORE 76 de función 151-156
RIGHTS 102-103 numéricas 152
RND 77-78 terminador de datos 82, 119
ROM (read-only memory) 1-2, 6, 158 TEST 135, 137
ruido 176-177 TIME 95
Tinta 51, 146-150
SHIFT, tecla 5, 7, 22, 55 tono 175
Sistema binario 129
sistema hexadecimal 129 VAL 111-112
SOUND 173-180
validación de datos 85
Sonidos 173-180
variables 25-29
SPC 14-16
literales 33, 98, 111
STEP 72-73
numéricas 33, 98-113
STOP 159 y programas gráficos 47
STRS 111-113 variables de control 68, 71
subcadenas 102-103, 105-106
ventanas
subíndices 122
de colores 60-62
submenúes 186 definición de 71
subprogramas 160 de texto 60-66
subrutinas 160-169, 183, 187-188
SYMBOL 129, 130, 175
SYMBOL AFTER 131, 132 WHILE ... WEND, bucle 80-86, 97,
Syntax error 5, 157 108, 119
WINDOW 50, 60-64
TAB 14-16
TAB, tecla 6 zonas de escritura 14
PROGRAMACION
BASIC
CON AMSTRAD
El ordenador AMSTRAD es una máquina muy potente, con
funciones gráficas y sonoras muy avanzadas. El manual del
usuario no puede dar más que un repaso superficial a las
características del ordenador; en cambio, en este libro nos
tomamos las cosas con más calma, para yudar tanto a los
principiantes como a los usuarios más expertos.
Los dos primeros capítulos van destinados al principiante
absoluto. El resto del libro presenta la mayor parte de las
instrucciones de BASIC disponibles en el AMSTRAD. En los
últimos capítulos se abordan temas más especializados,
tales como la utilización del sonido y manejo de fichero de
datos. En todos los capítulos se incluyen abundantes ejem­
plos y ejercicios.

El autor
Wynford James se dedica en la actualidad para escribir
material educativo (incluidos programas) para una impor­
tante empresa de microordenadores. Antes ha trabajado
como autor técnico para ICL. También ha sido profesor de
matemáticas y ha participado en el desarrollo de estudios
informáticos.

AMSTRAD
CPC
https://acpc.me/
[FRA] Ce document a été préservé numériquement à des fins éducatives et d'études, et non commerciales.
[ENG] This document has been digitally preserved for educational and study purposes, not for commercial purposes.
[ESP] Este documento se ha conservado digitalmente con fines educativos y de estudio, no con fines comerciales.

También podría gustarte