Hetedhét
Sinclair ZX Spectrum

Tartalom

Bevezetés

Első hét
1. nap - Valahogy el kell kezdeni
2. nap - Első programunk
3. nap - Újabb és újabb négyzetek
4. nap - Már írni is tudunk a képernyőre
5. nap - Feltételes módban
6. nap - Most a gép kérdez
7. nap - Pihenés, de nem a gépnek

Második hét
1. nap - A szubrutin, avagy az alvállalkozó
2. nap - A kocka el van vetve
3. nap - Billentyűfigyelés
4. nap - Fiókba tett dobozok (avagy tömbösített változók)
5. nap - Ciklus a ciklusban
6. nap - Kör, egyenes, körív
7. nap - Egy-két apró trükk

 

Harmadik hét
1. nap - Rajzoljunk grafikont
2. nap - Nagyon nagy és nagyon kicsi számok
3. nap - Lottózás a számítógép segítségével
4. nap - Több ember, több szelvénnyel, több hétig
5. nap - Adatok elraktározása
6. nap - Még mindig a könyvtár
7. nap - Néhány adósságunk törlesztése

Függelék
Hibakeresés
Hibakódok és értelmezésük
BASIC kulcsszavak
A karakterkészlet


Bevezetés

A Hetedhét sorozat jelen kötete némileg más, mint elődei, ugyanis a ZX SPECTRUM már elég régóta ismert és kedvelt személyi számítógép. A különbség részben a nagyobb terjedelemben és az eddigitől valamelyest eltérő feldolgozási módban jelentkezik. Mindkettőre magyarázatul szolgálhat, hogy bár jelen esetben is az alapokról indulunk, de igyekszünk olyan ismereteket illetve munkamódszereket nyújtani, amelyek a BASIC programozásban már bizonyos jártassággal rendelkezők számára is újdonságul szolgálhatnak.
Tapasztalataink szerint a kezdők, de még a középhaladók esetében is célravezető az a módszer, hogy egy egyszerű kis programot hosszú időn keresztül bővítgetve jutunk el egy tekintélyes méretű és tudású végeredményhez. Ennek okát abban látjuk, hogy ezen a szinten még nagy problémát jelent egy bonyolultabb program teljes előzetes megtervezése. A "kis téglákból" építkezés folyamatos sikerélményt nyújt, s megkönnyíti a hibák megtalálását.
A fentebb említett munkamódszer lényeges eleme, hogy egy-egy felmerülő problémát megkíséreltünk részletesen elemezni, ezeket a részeket (egy könyökölő sárkányfigurával megjelöltük őket) át lehet ugrani, vagy elegendő az ott található sorokat beírni. De a dolgok mélyére ásók számára remélhetőleg megtérül a befektetett energia.
A könyv mellé egy kazetta is megvásárolható, amely egy teljesen BASIC-ben írt, kilistázható játékprogramot (a már-már klasszikusnak mondható, 15-ös nevű tologatás játék) és jónéhány kisebb nagyobb hibás programot tartalmaz. A hibakeresést külön fejezetben mutatjuk be, mert úgy gondoljuk sokak számára a hibák behatárolása rengeteg nehézséget okoz.


Első hét

1. nap - Valahogy el kell kezdeni

Kezdetben a számítógép bután és esetenként makacsul, ellenszegülve fog viselkedni. Bután, mert képtelen megérten, hogy mit szeretnénk vele csináltatni; és makacsul, mert ha akár egyetlen pici vesszőt nem talál a helyén, nem hajlandó elfogadni a beírt sort, és ezt egy szemtelenül villogó kérdőjellel hozza tudomásunkra. Megfelelő bánásmóddal persze munkára fogható, és - mint az majd remélhetőleg kiderül - egészen érdekes dolgokat tud művelni: de ne feledjük: ha egy módja van rá, mindig másként értelmezi a dolgokat, mint ahogyan azt gyanútlanul elvárnánk. Ez ellen semmilyen erőszakos eszközzel (rázás, földhözvágás stb.) nem érdemes fellépni, viszont célra vezet, ha BASIC nyelven szólunk hozzá.
A BASIC nem olyan, mint a beszélt nyelvek. Egy verset vagy regényt le lehet fordítani angolról franciára, vagy akár kínairól japánra, de BASIC-re nem. Ez a nyelv ugyanis csak néhány (egyébként angol vagy angol eredetű) szót használ - szerencsénkre -, ellentétben a beszélt nyelvek több százezres szókészletével.
A ZX Spectrum által ismert szavak a billentyűzeten olvashatók. Aki arra gondol, hogy gyorsan kikeresi a szavakat egy angol-magyar szótárból, bebiflázza őket, és már tud is BASIC-ül, téved. Egyrészt azért, mert a megtalált szavak szó szerinti fordításából nem tudhatjuk meg, hogy mit jelentenek a BASIC-ben. Másrészt pedig azért, mert hiába is adnánk meg az egyes szavak értelmezésének szakszerű meghatározását, úgy járnánk, mint az a lelkes turista, aki külföldi útja előtt megtanul 100-200 szót, és csodálkozik, ha nem tudja megértetni magát. Meg kell ismernünk a BASIC szavainak - azaz utasításainak - összefűzési módszerét, ami már majdnem maga a programozás.

Némi hazafiúi büszkeséggel mondhatjuk, hogy a BASIC nyelv megalkotja egy John Kemeny nevű magyar származású amerikai tudós. A mikroszámítógépek valamennyien ismerik ezt az egyszerű, könnyen megtanulható nyelvet, azaz annak valamelyik "nyelvjárását", ugyanis az egyes gépeken futó BASIC-ek némileg eltérnek egymástól. Aki megtanulja a Spectrum utasításait, az kis fáradsággal más gépekkel is szót ért. Léteznek más számítógépnyelvek is, mint például a PASCAL, FORTRAN, FORTH, C, ASSEMBLY, LOGO stb.
Kimondott szavainkat a gép sajnos nem érti (bár a tudósok már dolgoznak az emberi beszédet megértő számítógépen). Így kénytelenek leszünk a billentyűzetet használni, ami csak ránézésre bonyolult, ne ijedjünk meg. Igaz, hogy a legtöbb gombnak 4-5 funkciója is van, de éppen ezért lehet velük viszonylag könnyen BASIC utasításokat írni.
Még nem késő! Aki akarja, most dobja a sutba a könyvet, mert később - remélhetőleg - már nehéz lesz. Ha egyszer a számítógép engedelmeskedni kezd, könnyen rabjává teszi az embert.
Kezdjük a munkát (vagy a szórakozást? ki-ki tekintse annak, amelyiket jobban szereti)!

Természetesen nem árt, ha üzembe helyezzük a gépet, azaz

Ekkor a képernyő alján az

1982 Sinclair Research Ltd.

felirat olvasható, de az is előfordulhat, hogy az egész kép fekete. Ilyenkor húzzuk ki a tápegység csatlakozóját a gépből, és 1-2 másodperc elteltével dugjuk vissza. Ha néhány kísérlet után sem jön elő a felirat, akkor kezdhetünk hozzászokni a gondolathoz, hogy elromlott a gép. De ne fessük az ördögöt a falra, a tapasztalatok szerint a Spectrum hosszú időn keresztül megbízhatóan működik. Persze nem célszerű kalapáccsal verni a billentyűket, és szabadesési kísérletek elvégzésére is inkább más tárgyakat használjunk. Ügyeljünk arra, hogy működés közben a gép hátulján található csatlakozósorhoz fémtárgy ne érjen hozzá, s a későbbiekben bármilyen egyéb eszközt csak kikapcsolt állapotban csatlakoztassunk. A billentyűket nyugodtan nyomogathatjuk bármilyen sorrendben, ezzel a gépben nem tudunk semmiféle kárt tenni. Nem véletlenül használtuk a "nyomogatjuk" kifejezést, nem kell nagy erővel ráütni, elég finoman lenyomni a billentyűket, a hatás ugyanaz.
Keressük meg mindenekelőtt az ENTER gombot (jobb oldalon alulról a második). Ezen nem látunk különböző betűket, szavakat, jeleket, tehát ennek a billentyűnek csupán egy feladata van: ennek a lenyomása után kezd foglalkozni a gép azzal, hogy vajon mit is óhajtunk közölni vele. (A szó magyarul belépést, bejegyzést jelent.) Más gépeken ezt a feladatot egy RETURN vagy NEW LINE feliratú billentyű látja el, és nem véletlen, hogy éppen jobb oldalt található, ugyanis ezen a tájon van az elektromos írógépek soremelő billentyűje is.
Nyomjuk meg az ENTER-t. A felirat eltűnik, és a sor elején egy négyzet villog, s benne egy 'k' betű látható. Ennek (mármint a négyzetnek) neve CURSOR, magyarul talán mutatónak fordíthatnánk. Kiejtése angolosan kb. "körször", latinosan kurzor. A cursor két dolgot jelent számunkra:

  1. hova kerül a következő betű vagy szó., amit beírunk,
  2. egy adott nyomógomb lenyomásakor annak melyik feliratát - funkcióját fogadja el a gép.

Így azt hihetnénk, hogy a különböző funkciókhoz más és más cursorbetű tartozik. Ez nagyjából így is van, de csak ötféle villogó betűvel találkozhatunk:

Próbáljuk a képernyőre varázsolni a különböző feliratokat! Kezdjük a számokkal!
Írjuk be az idei év számát! Az 1-es lenyomása után villogó K egy hellyel odább kerül, s az eredeti helyén megjelenik a kívánt szám.
Ha már beírni tudunk, jó lenne tudni letörölni is, elvégre előfordulhat, hogy véletlenül más billentyűt nyomtunk meg, mint amit szeretnénk. Mi sem egyszerűbb ennél: egyszerre kell lenyomnunk a CAPS SHIFT (a bal alsó sarokban található) és az 1-es gombot. Az "egyszerre" szó nem azt jelenti, hogy háromig számolunk, s hirtelen rácsapunk a két említett nyomógombra. Helyesebb, ha bal kezünk hüvelykujját finoman a CAPS SHIFT-en tartjuk, és ezután a bal mutatóval lenyomjuk az 1-est.
Ha sikeresen végrehajtottuk ezt a bonyolult műveletet, akkor újra ott látjuk a villogó K-t a sor elején.

Egyezzünk meg valamiben!
A Spectrum majd mindegyik billentyűje telis-tele van írva mindenféle betűkkel, szavakkal, jelekkel. Most, amíg még aránylag az elején vagyunk, beszéljük meg, hogy a billentyűkre nem a rájuk írt kulcsszavak vagy grafikus jelek alapján hivatkozunk, hanem kizárólag a betűk szerint!

Jöjjenek most a betűs billentyűkre fehérrel írott szavak!
Ha lenyomjuk a Q betűt, akkor a PLOT szó jelenik meg, mögötte a cursor viszont átváltozik L-re. Nincs semmi baj , csupán a gép ily módon figyelmeztet rá, hogy a BASIC szavak mellé - egy-két kivételtől eltekintve - még számokat, betűket, jeleket kell írni ahhoz, hogy ez valóban értelmes utasítás legyen. A PLOT utasítással egy pontot rajzolhatunk a. képernyőre; nyílván meg kell adnunk a pont helyét is. Ennek módjáról majd később, most inkább töröljük le a PLOT-ot, és írjuk ki a többi szót is. A T betű lenyomásakor a RANDOMIZE szó jelenik meg. Ez nem hiba, a kilencbetűs szó nem fért rá a billentyűre, ezért ott rövidítve olvasható.

Ha mindegyiket kiírtuk, jöhetnek a billentyű feletti zöld, illetve alattuk a piros szavak. Ehhez először a K helyére E-t kell varázsolnunk. No természetesen nem az E billentyűvel, hiszen akkor a REM kerül a képernyőre. Nyomjuk le egyszerre a CAPS SHIFT-et (körülbelül nagybetű-váltónak fordíthatnánk) és az alsó sorban jobbról a második, SYMBOL SHIFT (mondjuk: jelváltó) feliratú billentyűt, s máris megjelent a villogó E, azaz átléptünk az E üzemmódba: írhatjuk a zöld szavakat, sőt, ha a SYMBOL SHIFT-et nyomva tartjuk, az alattuk lévő pirosakat is.
Az alsó három sornál minden rendben: a cursor a szó kiírása után ismét L-re változik; a legfelsőnél azonban egy-két érdekes dolog történik. Az E-ből újra K lesz, és az alapszín is megváltozik, olyan színűre, amilyennel a szavakat a billentyű fölé írták (1-7). A 7-es esetében nem látunk ugyan változást, de ez nem véletlen, hiszen az a lapszín eddig is fehér volt. A 8-asnál tényleg semmi nem történik, a 9-es az eddigi piszkosfehér hátteret fényesre festi. (A Spectrum-on minden színnek van egy normál és egy fényes változata.) A 0-nál pedig látszólag minden eltűnik, holott csak feketére változott a háttér, a K cursor most is ott van, csak éppen fekete alapon fekete, s így nem látható. De semmi vész, mert a CAPS SHIFT és az 1 megnyomásával most is visszatérhetünk az alapállapothoz.
Kapcsoljunk át E üzemmódba, és most a SYMBOL SHIFT-tel együtt nyomjunk le egy gombot. Megjelenik a billentyű alatti szó, vagy az Y, U, P, A, S, D, F, G billentyű esetében egy-egy jel. A cursor pedig minden esetben most is L-re vált.

Ha már idáig eljutottunk, ideje megtudni: Mi van a billentyűkön?
Ehhez térjünk át L üzemmódba. Ezt úgy érhetjük el, ha lenyomjuk bármelyik betűs billentyűt.
L módban csak kisbetűket tudunk írni. Ígértük, hogy fogunk még az elektromos írógépre hivatkozni nos, most is ezt tesszük. Az írógépen az úgynevezett betűváltó és az adott billentyű együttes leütése nagybetű írását eredményezi. A betűváltót rögzíteni is lehet, így folyamatosan írhatók a nagybetűk. Itt a CAPS SHIFT a betűváltó, a rögzítést a CAPS SHIFT és a 2-es számjegy (ezen CAPS LOCK felirat áll; a "lock" zárat, lakatot jelent angolul) együttes lenyomásával végezhetjük el. A nagybetűs üzemmódban az L helyét C cursor veszi át. Ha vissza akarunk térni a kisbetűkhöz, akkor újra együtt kell lenyomnunk a CAPS SHIFT-et a 2-essel, ilyenkor a cursor természetesen újra L lesz.
A számok persze mindkét üzemmódban azonos formájúak, csakúgy, mint a billentyűn látható piros jelek, szavak. Ezek előcsalogatásához a SYMBOL SHIFT-tel együtt kell lenyomnunk a kérdéses gombot, akár L, akár C, akár K módban vagyunk.
Most már csak az 1-8 billentyűkön látható grafikai jelek vannak hátra. Ehhez át kell lépnünk a G üzemmódba (CAPS SHIFT + 9). Próbáljuk végig a billentyűket! A visszatérés nem automatikus, ehhez ismét meg kell nyomnunk a CAPS SHIFT-et és a 9-est. Láthatjuk, hogy néhány esetben a nagybetű helyett (V, W, X, Y, Z) szavak láthatók (RND, INKEY$, PI, FN, POINT. Ne törődjünk vele, nem romlott el semmi ezekről a szavakról is megtudunk majd mindent a maga idejében. Már most eláruljuk, hogy lehetőségünk van 21 db saját magunk által rajzolt betű használatára is, ezek éppen a grafikus üzemmódban hívhatók elő. Így ékezetes magyar, görög vagy akár cirill betűket is a képernyőre varázsolhatunk. (A varázslás módjáról később.) Aki észrevette, hogy a lehetséges 26 betűből éppen 21 íródott ki helyesen grafikus módban, az most veregesse meg jobb kézzel a bal vállát!

Nem tagadjuk, a sok üzemmód meg funkció egy kicsit bonyolultnak tűnik, de higgyük el, nemsokára csukott szemmel is megtaláljuk a megfelelő billentyűt. Ezután bátran megpróbálhatjuk a

PLOT 128,88

sor beírását. A Q billentyűvel hívhatjuk elő a PLOT szót, a vesszőt pedig a SYMBOL SHIFT és az N együttes lenyomásával írhatjuk ki. Ugye egyszerű?
Ezzel lényegében parancsot adtunk a gép számára, hogy a képernyő egy bizonyos pontját fesse feketére. Ám a végrehajtás csak akkor történik meg, ha az ENTER gombot lenyomtuk. Ezzel jelezzük ugyanis, hogy befejeztük a beírást. Ekkor az alsó sorban a gép jelzi számunkra, hogy már is végrehajtotta a parancsot.

0 OK, 0:1

A számokról majd később szólunk, az OK annyit jelent, hogy minden rendben, ha tetszik: minden oké. A végeredmény, egy pici pontocska pedig ott látható a képernyő közepe táján. Nem túl nagy, de sok kicsi sokra megy. Ezt akár szó szerint is vehetjük, azaz sok ilyen pici pontocskából - idegen szóval: pixelből - áll össze minden kép, jel, betű a képernyőn.
256x176 ilyen képpont éli rendelkezésünkre, hogy gazdálkodjunk vele. Ez nem a teljes képernyő területe: a maradék 256x16 pontocskából álló rész a képernyő alján az úgynevezett üzenetmező, itt olvashatjuk a gép üzeneteit, illetve ide kerülnek az általunk beírt szavak, betűk, jelek, számok.

A PLOT szó után álló két szám alapján keresi meg a gép azt a helyet, ahová a pontot kell kirajzolnia. A kiindulási hely mindig a képernyő bal alsó sarka, ez a 0,0 pont. Az első szám azt adja meg, hogy hány lépést kell lépni a kezdeti helytől jobbra, a második pedig a lépések számát felfelé.
Mivel vízszintesen 256 pontból áll a kép, ezért az első szám 0 és 255 közötti értékű lehet. Ez éppen 256 db különböző számot jelent, hiszen 0 az első, az 1 a második, és így tovább. Ha ez az érték 0, akkor nem kell jobbra menni, tehát a képernyő bal szélső oszlopában lesz valahol a pont; ha 255, akkor a jobb szélsőben.
Függőleges irányban 176 pont alkotja a képet, így a második helyre kerülő szám - az előzőekből sejthetően - 0 és 175 közötti értékű lehet. 0 esetében az alsó sorban, 175-nél pedig a legfelső sorban van valahol a kirajzolt pont.

Az ábrán bejelöltük a képernyő 4 sarkának azonosító számpárjait. E számpár első tagja az úgynevezett x, a második az y koordináta. Aki nem találkozott eddig a koordináta szóval, ne rettenjen meg, a gép úgysem tudja, hogy mit gondolunk a PLOT után írt két számról.

Próbáljunk ki két változatot annak figyelembevételével, hogy az x 0 és 255, az y pedig 0 és 175 közötti értéket vehet fel. Ha negatív számot írunk, a gép nem veszi figyelembe az előjelet. (A mínusz jel előhívása: SYMBOL SHIFT + J.) így például a

PLOT -4,-52

utasítás pontosan ugyanazt eredményezi, mint az, hogy

PLOT 4,52

Ha valamit elrontanánk, a gép - legalábbis az esetek jelentős részében - figyelmeztet a tévedésünkre. Ha a PLOT-ban a vessző (,) helyére pont (.) kerül, ilyesformán:

PLOT 4.52

akkor az ENTER lenyomása után nem jelenik meg a kívánt pixel a képernyőn. A parancs ott marad az alsó sorban, és a pont után egy villogó kérdőjel jelzi, hol hibáztunk. Ki kell törölnünk a pontot, és a helyére írnunk egy vesszőt.
Vigyük a cursort a pont mögé (egy soron belül úgy mozgathatjuk, hogy lenyomjuk a CAPS SHIFT-et, a 8-as vagy az 5-ös számjegy billentyűjét: a cursor mozgásának irányát a billentyűkön nyilak mutatják. Ezután a DELETE parancsra - ezt a szót dilítnek ejtik - (CAPS SHIFT + 0) a pont eltűnik. (A DELETE szó magyar jelentése: "törölj!") Ezután beírhatjuk a vesszőt, s mint aki jól végezte dolgát, nyomjuk le az ENTER-t. A gép így már nem tiltakozik.
Akadnak olyan hibák is, ahol a gép elfogadja ugyan a beírt sort, de az ott lévő értékeket nem találván jónak (és ebben, ezt jól jegyezzük meg, kivétel nélkül mindig igaza van), egy úgynevezett hibaüzenettel közli velünk nemtetszését. Például:

PLOT 341,52

A gép válasza:

B Integer out of range, 0:1

Ilyenkor nincs lehetőség javítgatásra; újra be kell írni az egész sort.
Sajnos még fogunk ilyen és hasonló jelenségekkel találkozni. Nincs az a programozó, aki ne követne el hibákat - minél többet dolgozik, annál több erre az esély. (Minél ügyesebb valaki, annál nagyobb hibák telnek ki tőle - tartja a programozói közmondás...) Ennélfogva külön rovatban kigyűjtöttük a hibaüzeneteket; ezek a könyv végén megtalálhatók. Vegyük most sorra, milyen lehetőségek állnak rendelkezésünkre, hagy az alsó sorban javítsunk valamit:

1. A cursor mozgatása:

balra: CAPS SHIFT + 5
jobbra: CAPS SHIFT + 8
fel: CAPS SHIFT + 7
le: CAPS SHIFT + 6

Az utóbbi kettőt akkor használjuk majd, ha már több programsorunk van egymás alatt a képernyőn - ez a következő fejezetben kerül sorra.

2. Az egész sor törlése:

EDIT Paranccsal (CAPS SHIFT + 1) Ennek egyébként még egyéb hatásai is vannak.

3. Egy szó, betű, szám, jel törlése

DELETE paranccsal (CAPS SHIFT + 0) A cursortól balra lévő szó, betű stb. törlődik.

4. Beszúrás

A már meglévő szövegbe bárhová beleírhatunk, ha előtte a cursort a megfelelő helyre visszük. A beszúrt betű, szám, jel mindig a cursor helyére kerül.

Ha egymás után több számot, betűt akarunk kitörölni vagy a cursorral átugrani, akkor folyamatosan nyomhatjuk a megfelelő két gombot, nem kell elengednünk és újra lenyomnunk őket.
Figyeljük meg, ha visszajutott a cursor a sor elejére, akkor automatikusan K-ra változik, hiszen ide mindenképpen egy BASIC-szónak, vagy egy sorszámnak kell kerülnie, de erről majd később.

Amint láttuk, a parancsot a gép az ENTER lenyomására azonnal végrehajtja, de sajnos rögtön el is felejti: ha még egyszer ugyanazt akarjuk kérni tőle, gépelhetjük az egészet elölről. Ez elkerülhető, ha a sor legelejére egy számot írunk. Írjuk is be mindjárt a következő sort:

20 PLOT 128,76

Láthatjuk, hogy az ENTER lenyomására a gép a parancsot nem hajtja végre, viszont a beírt sor a képernyő felső részébe kerül.

20>PLOT 128,76

Ráadásul egy > jel is befurakodott a sorszám és az első betű közé. Most ügyet se vessünk rá, később még örülni is fogunk neki.
Az ilyen, sorszámmal ellátott parancs már nem parancs, hanem utasítás. Mostantól így is fogjuk nevezni.
Írjuk be ezt az utasítást:

30 PLOT 138,76

Most a 30-as után látjuk a > jelet, viszont az, első sorból eltűnt. Máris fogalmazhatjuk a zseniális következtetést: a > jelzi, melyik sort írtuk be utoljára. Következzék a

10 PLOT 118,76

sor. Ez is felkerül a képernyő felső részére, mégpedig az előzőleg beírt két sor fölé. Ez nem véletlen, mivel a gép ilyen sorrendben hajtja végre az utasítások sorozatát, azaz magát a programot, ha kiadjuk a

RUN

(E szónak körülbelül 'ran' a helyes kiejtése, és annyit jelent: fuss.)
Adjuk is ki, ha már szóba hoztuk. Nyomjuk meg az R billentyűt, majd az ENTER-t!
A képernyőn megjelenik a három pont, az alsó sorban olvasható üzenetből megtudhatjuk, hogy a 30-as sorban a program futása befejeződött:

0 OK, 30:1

Ezzel elkészítettük első BASIC programunkat! Elbizakodottságra persze egyelőre semmi okunk, az út nagy része még előttünk van.
Ha újra akarjuk látni a beírt utasításokat, nyomjuk le az ENTER-t, és előttünk áll első programunk:

10 PLOT 118,76
20 PLOT 128,76
30 PLOT 138,76

Esetenként szükségünk lehet a képernyő letörlésére. Ezt a CLS paranccsal tehetjük meg. Ha azt akarjuk, hogy a program futása közben törlődjék le a képernyő, a CLS is beépíthető a programba, ha sorszámot írunk elé. (Jól van már, mi is tudjuk, hogy nem magyaráztuk még el, mi az a CLS. De lássuk be: nem fér be minden egy bekezdésbe. Tehát: a CLS a CLEAR SCREEN rövidítése, ami annyit tesz: tiszta képernyő.)
Apropó sorszámok! Ezek csak pozitív egész számok lehetnek, ezért célszerű tízesével számozni a sorokat, mert így utólag még 9 új sort be tudunk írni a meglevők közé. Erre azért is érdemes gondolnunk, mert sajnos a Spectrum BASIC-je nem ismeri az újrasorszámozásra vonatkozó parancsot.
Biztosan sokaknak szöget ütött a fejébe: ha a gép mindig a sorszámok sorrendjében hajtja végre az utasításokat, akkor mindig ugyanaz történik. Megnyugtatásul: előbb-utóbb megismerkedünk azokkal az utasításokkal, amelyek megváltoztatják a végrehajtás sorrendjét.

FELADATOK:

  1. PLOT utasítások sorozatával rajzoljunk a képernyőre egy 4x4 pixelből álló négyzetet. A négyzet bal felső sarka a 100,120-as pontban legyen.

  2. PLOT utasítások sorozatával rajzoljunk a képernyőre egy 6x4 egységnyi oldalhosszúságú téglalapot!

(Ez csak az első nap volt; biztos, hogy a feladatokban sokan hibát ejtenek. A javítás legegyszerűbb módját épp ezért már most kénytelenek vagyunk elárulni: ha egy sort elrontunk, ugyanazzal a sorszámmal újra írhatjuk: ilyenkor a régi sor eltűnik, és az új veszi át a helyét. Az utolsó parancs érvényes, akár a katonaságnál...)

2. nap - Első programunk

Nézzük az előző nap 1. feladatát!

10 PLOT 100,120
20 PLOT 101,120
30 PLOT 102,120
40 PLOT 103,120
50 PLOT 103,119
60 PLOT 103,118
70 PLOT 103,117
80 PLOT 102,117
90 PLOT 101,117
100 PLOT 100,117
110 PLOT 100,118
120 PLOT 100,119

Láthatjuk, hogy a négyzet minden pontjának kirajzolása külön utasítást igényel.
Változtassuk meg a programot úgy, hogy a négyzet bal felső sarka a 40,30 pontban legyen! Szent ég, ez azt jelenti, hogy ki kell cserélnünk mind a tizenkét számpárt! Ügye kezd gyanússá válni a dolog? Egy ilyen kis változtatás ennyi átírást igényelne? Nagyon csalódnánk a számítógépben. Meg lehet olyan ügyesen is írni ezt a programot, hogy csak két számot, mondjuk a négyzet bal felső sarkának a helyét kelljen átírnunk. Ehhez egy kicsit másként kell fogalmaznunk a gép számára a teendőket.
Figyeljük meg a 10-es és 20-as sort! Mindkettőben azonos az y koordináta (emlékszünk még? Így neveztük a pontnak a képernyő aljától mért távolságát). Az x koordináta (a képernyő bal szélétől való távolság) a 20-as sorban eggyel nagyobb, így ez a sor az előző sor által rajzolt pont mellé tesz egyet. Hétköznapi nyelven így mondanánk:

10 Rajzolj egy pontot a 100,120 helyre!
20 Rajzolj egy pontot az előző mellé, jobbra!

Sajnos a BASIC nyelv az ilyen szószátyár kéréseket nem érti, így kénytelenek leszünk számára érthetőbben fogalmazni. Írjuk be a következő sorokat ! (Ne zavarjon minket, hogy esetleg még ott van az előző program is!)

3 LET x=100
4 LET y=120
10 PLOT x,y
20 PLOT x+1,y
30 STOP

Mint látjuk, a régi 10-es, 20-as és 30-as sorok eltűntek, és az újak léptek a helyükbe. Nem kellett előbb kitörölnünk és utána újra beírnunk őket. Bár azt is könnyen megtehettük volna, hiszen egy sor törléséhez elég beírni a számat, és lenyomni az ENTER-t. Így egyszerre mindig csak egy sort törölhetünk. (Ha az egész addig beírt programtól meg akarunk szabadulni, arra is van mód: a NEW (ejtsd: nyú, jelentése: új) Parancs minden BASIC programsort kitöröl a gép emlékezetéből. No meg persze akkor is törlődik az egész program, ha kihúzzuk a tápegység dugóját...) Ez a kis kényelem néha kellemetlenséget okozhat. Ha egy hosszabb program beírásakor eltévesztünk egy sorszámot, például 200 helyett 20-at írunk be, akkor az eredeti 20-as sorunk törlődik a gépből, s persze a 200-as hiányozni fog. No de hol vagyunk mi még a hosszabb programoktól?...
Futtassuk le a programot (RUN)!

A képernyőn ott van a két kis pont egymás mellett. Próbáljuk. meg értelmezni, mit is csináltunk!
A 3-as és 4-es sorban egy új utasítást találunk. A LET körülbelüli értelme a BASIC nyelvben: LEGYEN. Ezek szerint a 3-as sor azt jelenti: legyen x egyenlő 100-zal. Vagyis: az x nevű dobozba kerüljön be a 100. Mit jelent ez valójában?
A programban rendszerint nemcsak egy, hanem sok dolog adatait használjuk. Ezeket a számítógép csak úgy tudja kívánságra elővenni és felhasználni, ha pontosan megmondjuk neki, hogy melyiket kérjük. Ezért a dobozainkban tárolandó értéken kívül (ez a mi példánkban 100) valamilyen nevet (jelen esetben x) is adnunk kell a doboznak. (A telefonkönyv is értelmetlen adathalmaz lenne, ha a számok mellett nem állnának ott a nevek is...)
Törődjünk bele, hogy most egy szakkifejezést tanultunk meg: A dobozokat változónak nevezzük. Egyszerűen azért, mert a tartalmát változtatni tudjuk.
A 3-as sor szakszerűbb értelmezése: legyen az x nevű változó értéke 100. A 4-es sor végrehajtásakor is hasonló értékadás történik: az y-nak 120 lesz az értéke, mindaddig, amíg másként nem rendelkezünk.
A név nemcsak egy betű lehet, hanem betűk és számok sorozata; csupán arra kell figyelnünk, hogy a név betűvel kezdődjék.
Játsszunk egy kicsit!

3 LET cica=100
4 LET kutya=120
10 PLOT cica,kutya
20 PLOT cica+1,kutya
30 STOP

A leghosszabb változónév 255 betűből, számból állhat, de írásjel nem lehet közöttük. (Tudomásunk szerint még senki nem találkozott olyan programozóval, aki ezt a lehetőséget teljesen kihasználta volna...) A gép nem tesz különbséget a kis- és nagybetűk között, tehát azonosnak veszi az amerikai fehér szövőlepke és az AMERIAK FEHÉR SZÖVŐLEPKE neveket, s mindig az utoljára beírtakat tekinti érvényesnek. Ezt persze csak viccnek szántuk, hiszen kinek lenne türelme ilyen hosszú változóneveket bepötyögni? Igyekezzünk mindig olyan nevet adni, amely emlékeztet a doboz (vagy ahogy tanultuk: változó) tartalmára. Éppen ezért tegyük vissza az x-et és az y-t , mert ahogy korábban említettük, a PLOT utasításban szereplő két szám nem más, mint a pont helyének x és y koordinátája.
A 10-es sor végrehajtásakor a gép megkeresi az x és y nevű dobozokat (változókat), és a bennük talált értékeknek megfelelő helyre rajzolja ki a pontot. A 20-as sor esetében az x érték előhívása után ahhoz még 1 hozzáadódik, és az így kapott érték adja a pont távolságát a kép bal széléről. Az y marad ugyanannyi, mint a 10-es sorban.
A 30-as sor - mint ahogyan a benne álló utasítás sejteti - leállítja a program futását.
Alakítsuk át a négyzetet kirajzoló program PLOT utasításait úgy, hogy a koordinátákat mindig a négyzet bal felső sarkához képest adjuk meg.

3 LET x=100
4 LET y=120
10 PLOT x,y
20 PLOT x+1,y
30 PLOT x+2,y
40 PLOT x+3,y
50 PLOT x+3,y-1
60 PLOT x+3,y-2
70 PLOT x+3,y-3
80 PLOT x+2,y-3
90 PLOT x+1,y-3
100 PLOT x,y-3
110 PLOT x,y-2
120 PLOT x,y-1
130 STOP

Változtassuk meg a 3-as sorban levő 100-at 40-re, a 4-esben a 120-at 30-ra, s lám újra futtatva a programot a négyzet máshová kerül. Eddig csak úgy tudtunk egy már meglevő sort kijavítani, hogy ugyanolyan sorszámmal egy újat írtunk, s a régi ezzel automatikusan törlődött. De van erre kényelmesebb mód is.
Az utolsónak bevitt sorban (130) - mint ezt már megfigyeltük - a sorszám után egy > jelet látunk. Ezt is nevezhetnénk cursornak, de hogy megkülönböztessük a villogó K, L, C, G, E betűktől, inkább hívjuk sormutatónak.
Ha most kiadjuk az

EDIT

(magyarul szerkesztés) parancsot (CAPS SHIFT + 1), akkor a képernyő alján megjelenik a 130-as sor. Itt megcsinálhatjuk a szükséges törléseket, beszúrásokat. Ha lenyomjuk az ENTER-t, az így átjavított sor kerül a régi helyére.
Nekünk most a 3-as és 4-es sorokat kellene átírnunk, ehhez előbb vigyük fel a sormutatót (>) a kívánt helyre. kétségkívül sokan kitalálták: a CAPS SHIFT és a 7-es billentyű lenyomásával tudjuk felfelé mozgatni a > jelet (lefelé a CAPS SHIFT + 6 viszi). Ha esetleg nincs kedvünk kivárni amíg felmászik a >, tegyük a következőket: töröljük le a képernyőt (CLS), majd adjuk ki a

LIST 4

parancsot. A gép kilistázza a programot a 4-os sortól kezdődően, s a > jel is a 4. sorba kerül. (A LIST egyébként nem véletlenül hasonlít a mi 'lista' szavunkra: mindkettő ugyanabból a latin szóból származik. A BASIC-szót amúgy 'liszt'-nek szokás ejteni.)
Ha a LIST után nem írunk semmilyen sorszámot, akkor a gép az elejétől írja ki a képernyőre a programsorokat. Ilyenkor eltűnik a >, de úgy tekinthetjük, mintha a legfelső sorban lenne, erről egy EDIT parancs kiadásával meg is győződhetünk. (Aki nem tudná, hogyan adjuk ki az EDIT parancsot, az nézzen utána az előző fejezetben: mi most sietünk tovább. A következő bekezdésben találkozunk, oké?)

Így már könnyedén átírhatjuk a 3-as és 4-es sorokat. A módosított programot lefuttatva a négyzet a kívánt helyre kerül.
Csináljunk még néhány átírást, de vigyázzunk, nehogy kilógjon a négyzet a képről, mert akkor - mint tudjuk - a program futása a hibás értéknél leáll, s egy hibaüzenet olvasható a képernyő alján. Gondoljuk meg, melyek lehetnek a jó értékek. Szánjunk rá néhány percet, hiszen később, amikor komolyabb programokat készítünk, úgyis így teszünk majd.

 

 

Ezek az üres sorok a gondolkodási időt jelképezték. Lássuk, mire jutottunk!
A lehetséges kezdeti értékek:

x: 0 ... 252
y: 3 ... 175

Akinek nem egyezik a véleménye, az olvassa tovább a következő szöveget,a többiek ugorják át ezt a bekezdést!

A legnagyobb x koordináta érték, melyet a PLOT utasításban megadhatunk: a 255. Ez persze nem azt jelenti, hogy a

3 LET x=255

megfelelne. Hiszen már a 20-as sorban baj történne, ugyanis itt az x-hez 1 adódik hozzá, és az így kapott 256 már túl nagy a PLOT számára.. Ebből következően a legnagyobb x érték, amit megadhatunk a 3-as sorban, a 252 lehet, mert így még akkor sem lépjük túl a megengedett felső határt, ha 3-at adunk hozzá (40, 80, 110, 120).
A legkisebb x érték a 0 lehet, mert az x-ből nem vonunk ki egyik utasításban sem. Más a helyzet az y-nal. Ahogy emlékszünk, a PLOT utasításban a második helyen álló szám (az y koordináta) értéke 0 és 175 között lehet. Így kezdőértéknek a 6-os sorban nem adhatunk 0-át, mert az 50-es sorban leállna a program, hiszen itt az y-ból kivonunk 3-at. Az ezzel kapott -3 pedig kívül esik a megengedett értékeken.
Most már nem nagy kunszt kitalálni: a 6-os sorban az y-nak adható legnagyobb érték 175 lehet.

Legyünk telhetetlenek!
Próbáljunk több négyzetet a képernyőre varázsolni! A 130-as sorban a STOP helyére írjuk be a

130 GOTO 10

sort. A GOTO szó szerinti jelentése "Menj ...-hoz"; így a 130-as sorban nem állítjuk meg a program futását, hanem visszaküldjük a 10-es sorhoz. A GOTO egyike azoknak az utasításoknak, melyek megváltoztatják a végrehajtás sorrendjét. A siker még várat magára, mert továbbra is csak egy négyzet látható, viszont nincs üzenet az alsó sorban. No ez nem meglepő, mindig ugyanarra a helyre kerül az újabb négyzet, mivel az x és y értékét nem változtattuk meg.
Igen ám, de a program most ámokfutó módjára rohan körbe-körbe, és rajzolja az újabb és újabb négyzeteket ugyanarra a helyre.
Pánikra semmi ok, nem kell kikapcsolnunk a gépet, azaz kihúznunk a tápegység dugóját, mert ezzel az egész programot törölnénk. Elég, ha kiadjuk a BREAK (ejtsd: brék: ezt a valaha divatos tánc révén sokan tudjuk; magyarul megszakítást jelent) parancsot (CAPS SHIFT és a SPACE együttes lenyomása).
Ilyenkor az üzenő sorban

L BREAK into program, 000:1

jelenik meg. A ... helyén annak a sornak a száma áll, amelyben levő utasítást éppen végrehajtotta a program, amikor megszakítottuk a futását.
Nyilvánvaló, hogy mielőtt újra kezdődne a kirajzolás, az x és y közül legalább az egyiknek az értékét módosítanunk kell, különben ott vagyunk, ahol a part szakad. Szúrjuk be a

125 LET x=45

utasítást, s próbáljuk ki. Valamit javult a helyzet, már két négyzetünk van. Most viszont a 45,30 kezdőpontú négyzetet rajzolgatja ki újra és újra a program. Ezért úgy kellene módosítanunk a 125-ös sort, hogy minden alkalommal más és más x értékkel induljon az újabb
rajzolás. Próbáljuk ki a

125 LET x =x+5

utasítást. Ez első pillantásra furcsának tűnhet, különösen azok számára, akik jártasak az egyenletek megoldásában. Ha egy számhoz hozzáadunk 5-öt, hogyan lehet egyenlő az eredeti számmal? Bizony semmiképpen nem lehet egyenlő, de itt másról van szó. Egyszerű szavakkal azt mondhatnánk: vedd elő az x nevű dobozban levő számot, adj hozzá 5-öt, és tedd vissza az x nevű dobozba! Szakszerűbben: az x változó régi értékéhez adjunk hozzá 5-öt, és mostantól ez legyen az x új értéke! A számítógép lelkes felfedezője számára most persze nem az a legfontosabb, hogy a lehető legszabatosabb kifejezést használja, hanem az, hogy teljesen világos legyen, mit is csinálnak az egyes utasítások.
Így a 125-ös sor mindig 5-tel növeli az x értékét. Az első rajzolásnál az x=40, a másodiknál 45, a harmadiknál 50, és így tovább. Még az x=255 esetében is elindul a rajzolás, de a 20-as sorban, ahol az x-hez 1 adódik hozzá, már túlléptük a határt, erre a

B integer out of range, 20:1

hibaüzenet figyelmeztet.
Ha az y értékét is átírjuk az újrakezdés előtt, akkor a négyzetek nem kerülnek vízszintesen egymás mellé. Szúrjuk be a

127 LET y=y+1

sort, amely mindig eggyel följebb emeli a következő négyzetet.
Eljött az ideje, hogy művünket megörökítsük az utókor számára. Márványba vésésről még nincs szó, megelégszünk egy magnófelvétellel is.

3 LET x=100
4 LET y=120
10 PLOT x,y
20 PLOT x+1,y
30 PLOT x+2,y
40 PLOT x+3,y
50 PLOT x+3,y-1
60 PLOT x+3,y-2
70 PLOT x+3,y-3
80 PLOT x+2,y-3
90 PLOT x+1,y-3
100 PLOT x,y-3
110 PLOT x,y-2
120 PLOT x,y-1
125 LET x=x+5
127 LET y=y+1
130 GO TO 10

Bár a Rekordok könyvébe biztosan nem kerülünk bele fantasztikus programunkkal, holnap mindenképpen hasznát vehetjük a felvételnek, ugyanis megússzuk a program újbóli bepötyögését. A világ legcsodálatosabb számítógépe sem érne többet egy zsebszámológépnél, ha nem lehetne hozzákapcsolni egy tárolóeszközt, amelynek segítségével a munka végén eltehetjük a programunkat. (Ezt bizonyos gépeken egybe is építették a számítógéppel.)
Jelen esetben mi a legegyszerűbb tárolóeszközt, a kazettás magnót használjuk. Ez lehet egy közönséges, olcsó monó készülék is, ahol a felvétel jelszintje automatikus. Kazettaként nyugodtan használhatjuk az 5, 10 és 15 perces computerkazettákat; nem kell minden áron a legjobb minőségű HiFi szalagokat beszereznünk. Gépünk hátoldalán két csatlakozó aljzat (egyszerűbben: lyuk) van a magnó számára. Felvételkor a MIC feliratút kell összekapcsolni a magnó mikrofonbemenetével, lejátszáskor viszont az EAR nevűt a fülhallgató-kimenettel.

FONTOS!!
Bár a géphez egy dupla zsinórt mellékeltek, felvételkor a fejhallgató-csatlakozó ne legyen bedugva, mert ez hibás felvételt eredményezhet.

Ha a gép és a magnó összekapcsolása sikerült, már egyszerű dolgunk van. Írjuk be

SAVE "elso"

sort. Az idézőjelek közé került szó lesz a program neve. Ez legföljebb 10 betűből (illetve számból, írásjelből) állhat.
Az ENTER lenyomása után megjelenik a

Start the tape and press any key

szöveg. Ekkor nyomjuk le a magnó PLAY és RECORD gombjait, majd bármelyik billentyűt a gépen (az angol szöveg ugyanis pontosan erre szólít fel). Kellemetlen, sípoló hang kíséretében először széles piros és kék, majd keskenyebb kék és sárga csíkok másznak-futnak fölfelé a képernyő szélén. A folyamat végét a

0 OK, 0:1

üzenet jelzi.
Érdemes ellenőrizni, hogy mi került a szalagra.


A VERIFY szó (úgy ejtendő, hogy verifáj. Csúnya, csúnya, de mit csináljunk...?) ellenőrzést, igazolást jelent. Most az történik, hogy a gép összehasonlítja a szalagon talált programot a memóriájában levővel. (A memóriáról egyelőre elég annyit tudnunk, hogy ez a gépnek az a része, ahol mindaddig képes tárolni a beírt sorokat, amíg ezek törlésére parancsot nem adunk, illetve ki nem húzzuk a tápegység dugóját.)
A folyamat kísérőjelenségei olyanok, mint kimentéskor. Ha a gép megtalálta a programot, akkor a képernyőn a

Program: elso

Felirat látható. Ez jelenti azt, hogy sikerült azonosítani a szalagon talált programot. Ezután a keskenyebb kék és sárga csíkok jelennek meg, s egy sistergésszerű hangot hallunk. A sikeres ellenőrzés végét a

0 OK, 0:1

üzenet jelzi.
Ha az ellenőrzés eltérést derített ki a szalagon illetve a gépben lévő program között, akkor az

R Tape loading error, 0:1

üzenetet olvashatjuk.
A hibának többféle oka lehet, úgymint:

A fentiekből következően:

Amennyiben az ellenőrzés sikerrel járt, nyugodtan kikapcsolhatjuk a gépet, és kipróbálhatjuk a program betöltését. Ez pontosan úgy történik, mint az ellenőrzés, csupán annyi az eltérés, hogy a VERIFY "elso" helyett a

LOAD "elso"

parancsot kell kiadnunk. A parancs annyit jelent, hogy 'tölts', és "lódnak" ejtik.

FELADATOK:

  1. A fenti program 3-as, 4-es, 125-ös, 127-es sorainak módosításával rajzoljunk négyzeteket a képernyőre!

  2. Változtassuk meg a 10-120 sorokat, hogy a 4x4-es négyzet helyett más ábra szülessen!

3. nap - Újabb és újabb négyzetek

Ugye mindenkinek sikerült megbirkóznia a tegnapi feladatokkal? Ha valamilyen csoda folytan mégsem, akkor íme, itt van:

3 LET x=100
4 LET y=120
10 PLOT x,y
20 PLOT x+1,y
30 PLOT x+2,y
40 PLOT x+3,y
45 PLOT x+4,y
50 PLOT x+4,y-1
60 PLOT x+4,y-2
70 PLOT x+4,y-3
75 PLOT x+4,y-4
80 PLOT x+3,y-4
90 PLOT x+2,y-4
95 PLOT x+1,y-4
98 PLOT x,y-4
100 PLOT x,y-3
110 PLOT x,y-2
120 PLOT x,y-1
125 LET x=x+5
127 LET y=y+1
130 GO TO 10

Mint láttuk, egészen kicsi módosítás is a program jelentős részének átírását igényelte. Például egy 5x5-ös négyzet esetében - mivel minden ponthoz tartozik egy PLOT - négy újabb utasításra volt szükség, s a meglevő sorok közül négyet módosítani kellett. Hát ez így bizony nagyon strapás. Nem is érne sokat az egész számítástechnika, ha nem volna erre is valami fejlettebb módszer.
Töltsük he az "elso" nevű programunkat! Emlékszünk még?

LOAD "elso"

vagy

LOAD ""

Ha valami gond lenne, lapozzunk vissza a tegnapi fejezethez!
Ha jobban megnézzük az egymást követő PLOT-okat, valamii rendszert fedezhetünk fel. Osszuk fel a 12 Pontrajzoló utasítást 4 csoportra! (Miért éppen 4-re? Nemsokára kiderül.) Legyen az első csoport a 10-es, a 20-as és a 30-as sor; a második a 40-es, az 50-es és a 60-as - és így tovább. Figyeljük meg a 10-es, 20-as és 30-as sort! Itt az y koordináta mindegyiknél azonos, az x pedig egyesével növekszik. Egy korszakalkotó ötlet: a

LET x=x+1

sor elvégezhetné ezt a növelést, csak arról kellene gondoskodnunk, hogy éppen háromszor történjék meg ez a hozzáadás. írjuk be a

10 FOR i=1 TO 3 STEP 1
20 PLOT x,y
30 LET x=x+1
35 NEXT i
37 STOP

sorokat! A figyelmes szemlélő most már könnyen megtalálhatja a megfelelő utasítások kulcsszavait a billentyűzeten: a kevésbé figyelmesek számára azért még is ide ideírjuk

FOR: k módban F
TO: SYMBOL SHIFT + F
STEP : SYMBOL SHIFT + D
NEXT: k módban N

Két új utasítást láthatunk: a FOR-t és a NEXT-et. A szavak jelentését elmesélni túlságosan bonyolult volna; a használatban sokkal világosabb lesz, mint ha magyarázattal szaporítanánk a szót. A FOR és a NEXT a BASIC nyelvben mindig együtt fordul elő, ha a programban néha távol kerülnek is egymástól. Figyeljük meg: mindig ugyanannyi FOR van a BASIC programokban, mint amennyi NEXT. Segítségükkel egy vagy több utasítás elvégzését annyiszor ismételjük meg, ahányszor akarjuk.
Az ismétlendő utasítások a FOR és a NEXT közé kerülnek (jelen esetben a 20-as és a 30-as sor utasításai). Az ismétlési számot a FOR-ban adjuk meg, a következő módon:

FOR i=1
TO 3
STEP 1
(kezdete)
(befejezése)
(lépésköz)

(A STEP jelentését ebből könnyű kikövetkeztetni: lépést jelent angolul - és BASIC-ül is.) Most 1-től 3-ig számolunk egyesével, így a 20 és 30-as sorok háromszor kerülnek sorra. Először, amikor az i=1, másodszor, amikor i=2, és utoljára, azaz harmadszor i=3 esetén. Az i nevű változóban (dobozban) tartja nyilván a program, hogy hol is tart a számlálásban. Az i-t ezért néha számlálónak is emlegetjük majd a későbbiekben. Próbáljuk ki az új programrészt! Látni fogjuk, hogy ez is kirajzol 3 pontot a négyzetből.

Kísérletezgessünk egy kicsit! Cseréljük ki a 10-es sort erre:

10 FOR i=2 TO 4 STEP 1

itt i=2, i=3, majd i=4 értéknél ismétlődik a 30 és 40-es sor. Azután

10 FOR i=20 TO 40 STEP 10

Most az i nevű változó a 20, 30, 40 értékeket veszi fel.
Majd pedig

10 FOR i=4 TO 2 STEP -1


Jelen esetben pedig visszafelé számolunk, így először i=4, azután i=3, s végül i=2. A programot bármelyik változatban lefuttathatjuk, a képernyőn mindig ugyanaz rajzolódik ki: a FOR és NEXT közötti utasításokat mind a négy példában háromszor hajtatta végre a program. (Többek között ezért sincs kék programozó, aki ugyanazt a feladatot ugyanúgy oldana meg: a programnyelvek majdnem annyi kifejezési szabadságot engednek meg használójuknak, mint a beszélt emberi nyelv.)
De vajon miért kell ezt a FOR... NEXT-et ilyen bonyolultan használni? Miért nem elég annyit írni, hogy FOR 3? Nem rossz ötlet, de sajnos (vagy szerencsére) a BASIC nyelv megalkotói ezt nem így gondolták, s mint ezt látni fogjuk, ennek a látszólag komplikáltabb megoldásnak számos előnye lesz majd.
A NEXT (szó szerint azt jelenti: következő) szerepe tehát az, hogy visszaküldi a programot a FOR után álló sorra, mindaddig, amíg a számláló (most i) túl nem lépte a felső határt. Írhatnánk GOTO-t a NEXT helyett? Sejtjük, hogy nem, de ha tehetjük, mindig győződjünk meg feltevéseink helyességéről vagy éppen hibás voltáról. Cseréljük ki a 35-ös sort!

35 GOTO 10

Lefuttatva nem meglepő, hogy csak egy pontot látunk, hiszen visszatérve a 10-esre, mindig elölről kezdődik a számolás. S persze ez folytatódik, amíg a képernyő szélére nem ér a csík, mert a 35-ösből mindig visszamegy a 10-esre.
Hasonló a helyzet

35 GOTO 20

esetében is.
Tegyük hát vissza az eredeti

35 NEXT i

sort, azzal a nyugalommal, hogy már tapasztaltuk is, amit eddig csak sejtettünk.
Szaknyelven szólva: most a FOR és a NEXT utasításokkal ciklust szerveztünk. (Ez a szó végső soron a görögből ered, és kört jelent; most már; bizonyára világos, hogy miért épp így neveztük el az önmagába visszatérő folyamatot.)

A FOR a ciklus kezdete,
a NEXT a lezárása,
a FOR és a NEXT közötti utasítások adják a ciklus magját,
az i neve pedig ciklusváltozó.

Egyáltalán nem azért említettük ezeket a kifejezéseket, hogy bárki is most bemagolja, csupán annyit szerettünk volna elérni, ha esetleg egy másik, szintén a programozással foglalkozó könyvben utunkba akadnak ilyen szavak, ne higgyük azt, hogy valamiféle ravasz káromkodásról van szó.
E kis kitérő után folytassuk tovább a program átalakítását!

Most a 40-es, 50-es és 60-as sorokat dolgozzuk át egy kicsit. Az x koordináta mindhárom esetben azonos, az y pedig egyesével csökken. Ugye lelki szemeink előtt megjelent a

LET y=y-1

sor?

40 FOR i=1 TO 3 STEP 1
50 PLOT x,y
60 LET y=y-1
65 NEXT i
67 STOP

Szinte lemásoltuk a 10-35 sorokat, hiszen itt is 3 pontot rajzolunk, csak nem egymás mellé, hanem egymás alá. Mielőtt elindítjuk ennek a programrésznek a futását, ne feledjük törölni a 37-est! (Emlékszünk? 37 és ENTER.)
Ezzel megvan a négyzet két oldala. A ravaszabbak biztosan előre örülnek, mert tudni vélik, hogy hasonló lesz a folytatás, csak a LET y=y-1 helyett lesz egyszer

LET x=x-1

és

LET y=y+1

Nekik van igazuk!
Írjuk be egyszerre a négyzet két hátralévő oldalát rajzoló részt! Persze töröljük a 67-es sort!

70 FOR i=1 TO 3 STEP 1
80 PLOT x,y
90 LET x=x-1
95 NEXT i

(Ezzel készen is van az alsó oldal kirajzolását végző rész.)

100 FOR i=1 TO 3 STEP 1
110 PLOT x,y
115 LET y=y-1
120 NEXT i

A további sorokat érintetlenül hagyjuk.
Most látszólag ott tartunk, ahol tegnap. Ki tudunk rajzolni egy 4x4-es négyzetet. Ám mégis előre léptünk. Nézzük meg még egyszer az egyes részeket!

Rajzoljuk le az 5x5-ös változatot! Ugyanezzel a módszerrel persze akármilyen nagyságú négyzetet készíthetnénk.
Keressük meg a programban azokat a sorokat, amelyek a négyzet méreteiért felelősek! Nincs nehéz dolgunk, a 10-es, 40-es, 70-es és 100-as sorban kell

FOR i=1 TO 3 STEP 1

a 3-at 4-re, illetve bármilyen más számra átírni. A cseréhez - mint tudjuk - le kell hozni alulra az érintett sorokat. Emlékeztetőül: vigyük a > jelet (sormutatót) a kiválasztott sorhoz (lefelé CAPS SHIFT + 6; fölfelé CAPS SHIFT + 7), vagy írjuk be a

LIST 10

illetve

LIST 40

stb. sorokat.
Ezután az EDIT parancsra (CAPS SHIFT + 1) az üzenő sorba kerül a kiválasztott sor, s megtehetjük a kívánt módosítást. Így négy sor átírásával más négyzetet rajzol a program.

De ne álljunk meg ennyinél!
Kézenfekvő gondolat: ha mindegyik érintett sorban ugyanaz a szám áll a TO után, akkor ezt a számot tarthatjuk egy változóban (dobozban). Így, ha módosítani akarunk, akkor csak ennek a doboznak a tartalmát kell kicserélnünk. Nevezzük ezt az új változót p-nek! Javítsuk ki a 10-es, 40-es, 70-es és 100-as sort így:

FOR i=1 TO p STEP 1

Ne feledjük, a p-nek értéket kell adnunk. Ha nem tennénk, akkor

2 Variable not found, 10:1

hibaüzenettel jelezné a gép, hogy olyan nevű változóra hivatkozunk, amelynek még nincs értéke. Ezért illesszük be a

7 LET p=3

sort. Ezzel megint az eredeti 4x4-es négyzetet rajzolja a program, de már egyetlen számérték átírása elegendő a négyzet méretének megváltoztatásához.
Ha már elég sok értéket kipróbáltunk gondoljuk meg, mit lehetne még a négyzet kirajzolásában változtatni. A méretet, a kezdő helyet és az elmozdulást már csereberéltük. Jöhetne még például a szín és az egyes pontok egymástól való távolsága. A színezéssel majd külön részben foglalkozunk, annak viszont semmi akadálya, hogy az eddigi folytonos vonalakat szaggatottá tegyük.
Teendőink tehát a következők:

  1. Megkeressük azokat a sorokat, amelyek a pont helyét határozzák meg.
  2. Módosítjuk a megfelelő értékeket, és végzünk néhány kísérletet.
  3. Megpróbáljuk megtalálni a módot arra, hogy csak egy számot kelljen megadnunk, s a vonal ettől vagy folytonos, vagy megfelelően szaggatott lesz.

Menjünk sorban!

1. A FOR a NEXT-tel együtt megadja, hogy hány pontból áll a négyzet egy oldala, pontosabban annál eggyel kevesebbet ad meg. A PLOT magát a kirajzolást végzi, tehát nem lehet másról szó, mint a 30-as, 60-as, 90-es és 120-as sorokról. Itt történik a következő pont új helyének kiszámítása, méghozzá úgy, hogy valamelyik koordinátának (de csak az egyiknek) az értékét eggyel növeljük vagy csökkentjük, attól függően, hogy lefelé, felfelé, jobbra vagy balra mozdul a négyzet. A hangsúly most az "eggyel" szón van. Ez okozza, hogy a következő pont az előző mellé kerül.

2. Javítsuk ki az 1-et 2-re, így

30 LET x=x+2
60 LET y=y-2
90 LET x=x-2
120 LET y=y+2

Rosszalkodjunk egy kicsit! Rontsuk el a négyzetet! Ehhez elég annyi, hogy nem egyforma számot írunk a fenti sorokba. Például:

30 LET x=x+2
60 LET y=y-1
90 LET x=x-2
120 LET y=y+1

Mielőtt kipróbálnánk, rajzoljuk le, hogy mit várunk!

1 2 3 1
3     2
2     3
1 3 2 1

Egy téglalapot kaptunk. Ügye már le is vonhatjuk a következtetést: ahhoz, hogy téglalap készüljön, az x értékét ugyanannyival kell növelni (30), illetve csökkenteni (90). Persze ez az y-ra is vonatkozik (60, 100).
Torzítsuk tovább, de most előre rajzoljuk meg a kívánt ábrát, és csak utána határozzuk meg a megfelelő számokat!

30 LET x=x+2
60 LET y=y-2
90 LET x=x-1
120 LET y=y+1

Próbáljunk meg még egy-két változatot, de mindig gondoljuk meg előre, milyen ábrát fogunk kapni.
Egy tanulság: ha bármikor van egy ötletünk, ne legyünk restek kipróbálni, még akkor se, ha először butaságnak vagy fölöslegesnek tűnik.
No, de térjünk vissza eredeti tervünkhöz!

3. Ügye azt akartuk: csak egy számot kelljen átírnunk ahhoz, hogy megváltozzék a képpontok távolsága. Az eddigiek alapján talán már nem meglepő, hogy erre is egy dobozt (változót) használunk.

30 LET x=x+t
60 LET y=y-t
90 LET x=x-t
120 LET y=y+t

Már mondanunk sem kell, hogy a t-nek is kell kezdeti értéket adnunk. Például:

8 LET t=3

Elég sok változónk van már, lassan össze fogjuk keverni őket. Jó lenne valamilyen puskát írni a programba, amely eligazítana, ha valamit elfelejtenénk. Nincs gond, erre is létezik egy BASIC utasítás, mégpedig a

REM

mely után bármilyen szöveget szabadon beírhatunk. A REM az angol REMark (magyarul: megjegyzés) szónak a rövidítése.
A gép a program futása közben nem foglalkozik a REM-ekkel; tudja, hogy ezek csak a program készítőjének emlékeztető jegyzetei. (A REM elérése: K módban E.) Mielőtt beírnánk megjegyzéseinket, megjegyezzük azt is, hogy nem kell feltétlenül minden REM-et külön sorszámmal, külön sorba írni. Olyan BASIC nyelvjárás a Spectrumé, amely egy sorban több utasítást is megenged, ezeket kettősponttal választjuk el egymástól.
Ezt eddig csak azért nem mondtuk, nehogy fölösleges bonyodalmat okozzunk. Ezenfelül célszerű kerülni több utasítás egy sorba írását, mert ellenkező esetben könnyen áttekinthetetlenné tudjuk varázsolni a programlistát. A REM-et azonban, ha lehetséges, mindig írjuk abba a sorba, amelyikre vonatkozik. A teljes, javított, kiegészített lista. Így néz ki tehát:

3 LET x=100: REM kezdeti hely
4 LET y=120: REM kezdeti hely
7 LET p=5: REM a pontok szama
8 LET t=3: REM pontok tavolsaga
10 FOR i=1 TO p STEP 1
20 PLOT x,y
30 LET x=x+t
35 NEXT i
40 FOR i=1 TO p STEP 1
50 PLOT x,y
60 LET y=y-t
65 NEXT i
70 FOR i=1 TO p STEP 1
80 PLOT x,y
90 LET x=x-t
95 NEXT i
100 FOR i=1 TO p STEP 1
110 PLOT x,y
115 LET y=y+t
120 NEXT i
125 LET x=x+5
127 LET y=y+1
130 GO TO 10

Mentsük szalagra a programunkat KA32 néven!

FELADATOK:

  1. Módosítsuk a KA32 programot úgy, hogy különböző kezdőhelyekről, különböző irányokban haladva rajzoljon négyzeteket!

  2. Módosítsuk a KA32 programot úgy, hogy a négyzet helyett téglalapot vagy bármilyen más alakzatot rajzoljon, és a vízszintes és függőleges vonalak azonos sűrűségű pontsorokból álljanak!

4. nap - Már írni is tudunk a képernyőre

Kezdjük a tegnapi feladatok megoldásával!

1. Mint láttuk, az első kirajzolt négyzet bal felső sarkának helyét a 4-es és 6-os sorban adjuk meg. A 125-os határozza meg, hogy az új négyzet az előzőhöz képest hány képponttal lesz jobbra vagy balra. Ha az x-hez hozzáadunk, akkor messzebb lesz a képernyő bal szélétől, tehát jobbra került; ha elveszünk belőle, akkor balra. Ehhez hasonlóan ha a 127-esben az y-hoz hozzáadunk egy számot, akkor az új négyzet följebb kerül, ha pedig kivonunk , akkor lejjebb.

a) A bal felső sarokból a jobb alsó felé tartó négyzetsorozathoz

3 LET x=0
4 LET y=175
125 LET x=x+3
127 LET y=y-2

módosításokat kell beírnunk.

b) A bal alsóból a jobb felső felé tartó négyzetsorozat:

3 LET x=0
4 LET y=0
125 LET x=x+3
127 LET y=y+2

c) A jobb alsóból a bal felsőbe

3 LET x=255
4 LET y=0
125 LET x=x-3
127 LET y=y+2

d) A jobb felsőből a bal alsóba

3 LET x=255
4 LET y=175
125 LET x=x-3
127 LET y=y-2

2. Négyzettorzítási kísérleteinkben 1áttuk, hogy téglalap akkor keletkezett, ha az x-et (30, 90) és az y-t (60, 120) eltérő értékekkel módosítottuk. Ezért a t változó helyett vezessük be a tv (vízszintes ponttávolság) és a tf (függőleges ponttávolság) változókat!

3 LET x=100: REM kezdeti hely
4 LET y=120: REM kezdeti hely
7 LET p=5: REM a pontok szama
8 LET tv=6: REM ponttav vizsz
9 LET tf=4: REM ponttav fuggo
10 FOR i=1 TO p STEP 1
20 PLOT x,y
30 LET x=x+tv
35 NEXT i
40 FOR i=1 TO p STEP 1
50 PLOT x,y
60 LET y=y-tf
65 NEXT i
70 FOR i=1 TO p STEP 1
80 PLOT x,y
90 LET x=x-tv
95 NEXT i
100 FOR i=1 TO p STEP 1
110 PLOT x,y
115 LET y=y+tf
120 NEXT i
125 LET x=x+5
127 LET y=y+1
130 GO TO 10

Már napok óta ismerkedünk a számítógéppel, de még egy betűt sem írattunk ki vele. No, ennek is eljött az ideje! Persze a rajzolóprogramunkon még sokat fogunk dolgozni, de most öntsünk tiszta vizet a pohárba, azaz: egy NEW-val töröljünk ki mindent!

Betűk, számok, írásjelek és az 1-8 billentyűkön 1átható grafikai jelek (egyszóval karakterek) megjelenítésére a PRINT utasítás szolgál. A szó jelentése magyarul: nyomtass!
Ha K módban lenyomjuk a P billentyűt, máris láthatjuk a PRINT szót az alsó sorban. De ez önmagában még kevés. A PRINT után be kell írnunk, mit, hová és milyen színben akarunk a képernyőn megjeleníteni. Ne ijedjünk meg, nem kell mindig minden adatot megadnunk, a gép sajt kútfejéből választ helyet és színt, ha erre vonatkozólag mi semmit sem közlünk vele.
Próbáljuk először a számokat kiíratni!

PRINT 4

(majd ENTER). és a képernyő bal felső sarkában ott a 4-es szám. Folytassuk!

PRINT 1985

Mint látjuk, a gép egy sorral lejjebb kiírta a számot. Folytassuk a betűkkel!

PRINT zoli

Zoli helyett mindenki a saját nevét is beírhatja: az eredmény nem változik: a név helyett egy hibaüzenet vár ránk:

2 Variable not found, 0:1

Ugyanis a PRINT zoli hatására a gép a zoli nevű dobozban lévő számot szeretné kiírni, s mivel nem talál ilyen nevű dobozt, figyelmeztet a fenti üzenettel.
Tegyük a Zolit idézőjelek közé! (SYMBOL SHIFT + P)

PRINT "zoli"

és máris ott láthatjuk kiírva a nevünket. Pontosabban: a nevünknek ékezetek nélküli változatát. Akit Tamásnak hívnak, annak be kell érnie Tamassal - ez a magyar anyanyelvűek számára eleinte zavaró, de meg lehet szokni. Persze azért a magyar helyesírást, ha ebben a könyvben nem mindig követjük is, senki ne felejtse el!
Töröljük le a képernyőt (CLS), és írjuk be a következőket!

10 PRINT "elso"
20 PRINT "masodik"
30 PRINT "harmadik"

A képernyőn ez látható:

elso
masodik
harmadik

Próbáljunk következtetéseket levonni! Ha a hely- és színválasztást a gépre bízzuk, akkor a képernyő letörlése után a szöveg a legfelső sorba kerül, fehér alapon fekete színnel. Az újabb szöveg egy sorral lejjebb jelenik meg.
Módosítsuk a 10-es sort!

10 PRINT "elso";

A pontosvessző (;) az O betűn található, és a SYMBOL SHIFT és az O együttes lenyomásával jön elő.
Az eredmény:

elsomasodik
harmadik

Tehát a ; hatására a kiíratás ott folytatódik, ahol az előzőnél abbamaradt.
Cseréljük ki a pontosvesszőt vesszőre (SYMBOL SHIFT +N), és tegyünk a 20-as után is vesszőt!

10 PRINT "elso",
20 PRINT "masodik",
30 PRINT "harmadik"

Mint látjuk, a vessző hatása:

A teljesség kedvéért megjegyezzük, hogy az aposztróf (') jel (SYMBOL SHIFT + 7) is a következő sorba küldi az újabb szöveget. Próbáljuk ki ezt is! Egy utasításba beírhatunk több printelendő szöveget is, ha azokat a ; , vagy ' jelek valamelyikével elválasztjuk.

10 PRINT "elso"'"masodik"'"harmadik"
12 STOP
Egy PRINT utasításban persze nemcsak idézőjelek közé tett szövegből lehet több.
5 LET a=123
10 PRINT "az a nevu doboz tartalma=";a
12 STOP
A képernyőre a RUN hatására
az a nevu doboz tartalma=123

felirat kerül.
Most nézzük, hogy hely ügyben mit tehetünk!
Írás szempontjából tekintsük a képernyőt egy négyzethálós vagy - népszerűbb, ám, mint tudjuk, helytelen nevén - kockás füzetlapnak, melynek 22 sora van, soronként 32 betűhellyel úgy is mondhatnánk, hogy 22 sorból és 32 oszlopból álló négyzethálónk van.

Az alul levő 2 sor az üzenősor, közvetlenül nem használható. A sorok számozását a következő kis program illusztrálja:

5 FOR i=0 TO 21 STEP 1
6 PRINT i
10 NEXT i
12 STOP

Mielőtt lefuttatnánk, gondoljuk meg, hányszor fogja a gép végrehajtani a FOR és a NEXT közé ékelt PRINT utasítást!
Aki hirtelen rávágta, hogy 21-szer, az tévedett. Számoljunk utána: i=0 értéknél kerül e1őször sor a PRINT-re, i=1-né1 másodszor; tovább már folytatnunk sem kell... Amikor i=21, akkor már 22. alkalommal hajtódik végre a kiírató utasítás. Próbáljuk ki!
Mint látjuk, a legfelső sor a 0, az alatta lévő az 1. és így tovább, a legalsó még hasznos sor a 21. A soron belüli betűhely (más néven: oszlop) számozása balról jobbra történik. A bal szélső a 0, a jobb szélső a 31-es számú - ez összesen 32. így a betűhelyeket is két számmal azonosíthatjuk, az első a sor, a második az oszlop száma.
Az ábrán bejelölt négy hely:

 
sor
oszlop
bal felső sarok
0
0
bal alsó sarok
21
0
jobb felső sarok
0
31
jobb alsó sarok
21
31

Ez a számozási szisztéma más, mint a képpontoknál ott a bal alsó sarok a kiindulási hely. 8x8, azaz 64 képpont alkot egy karaktert (így nevezzük összefoglaló néven a betűt, számot, írásjelet és a grafikus jelet). Például a t betű esetében:

A vízszintesen egymás mellé férő 32 karakter, mindegyik 8 képponttal, éppen kiadja a 32-szer 8, azaz 256 képpontot. Ugyanígy függőlegesen is 22-szer 8 = 176.
Ha meg akarjuk adni a kiírandó szöveg helyét, akkor a PRINT után az AT szót (SYMBOL SHIFT + I) majd egymástól vesszővel elválasztva a sor- illetve oszlopszám értékét kell írnunk, ezt egy pontosvessző követi, s máris jöhet a kiírandó szöveg. (Az AT szó a magyar -nál, -né1 ragnak felel meg.)

PRINT AT 4,12;"proba"

Ha valahonnan kihagyjuk a megfelelő jelet, a villogó ? figyelmeztet a mulasztásunkra.
Hozzuk alapállapotba a gépet egy NEW paranccsal, s maris kezdhetjük a kísérletezgetést!


10 PRINT AT 0,0;"kutya"
20 PRINT "cica"

A RUN parancs kiadása után a kutya kiírása a bal felső sarokban kezdődött, a cica egy sorral lejjebb került.
Tegyünk a 10-es sor végére előbb pontosvesszőt (SYMBOL SHIFT + 0), majd vesszőt (SYMBOL SHIFT + N), az első esetben az eredmény

kutyacica

míg a másodikban

kutya          cica

A cica éppen a 16 oszlopszámú helyen kezdődik. Ha a kutya szó átlóg a képernyő jobb felébe

10 PRINT AT 12,0;"kutya",

akkor a cica már átkerül a következő sorba.
Írjuk be a

20 PRINT TAB 3;"cica"

sort. A TAB utasítást úgy érhetjük el, hogy E üzemmódban lenyomjuk a P betű billentyűjét. (A TAB szó a tabulatúra, magyarul táblázat rövidítése. Tabulátor billentyű van az írógépeken is, éppen a táblázatok készítésének segítésére.) A TAB-bal csak a kiírandó szöveg soron belüli helyzetét adhatjuk meg. Az utána írt szám mutatja, hogy a képernyő bal szélétől hány hellyel kerüljön beljebb a kiírás.
Írjuk be a

15 PRINT AT 21,0;"maci"

Mi fog történni?
A "maci" szó a legalsó sorba kerül, de miután a 15-ös sor végén se pontosvessző, se vessző nincs, a 20-ban kiíratandó cica szónak eggyel lejjebb kellene kerülnie. Viszont nincs több használható sor. Most mi lesz? A legegyszerűbb, ha ezúttal is előbb kipróbáljuk, aztán majd megbeszéljük a látottakat.

RUN (ENTER)

A kutya és a maci ott van a kívánt helyen , a cica viszont sehol, helyette egy kérdés az üzenősorban:

scroll?

(A "scroll" szó eredeti jelentése: papiruszból vagy pergamenből készült irattekercs; erre írtak régen az emberek.) Itt arról van szó, hagy a képernyőn nincs már hely az újabb szöveg kiírására, ezért a gép megkérdezi, hogy "feltekerheti-e" a képet. Bármely billentyű lenyomása beleegyezés (kivétel az N, a BREAK és a STOP). Ez annyit jelent, hogy a legfelső sor eltűnik, minden sor eggyel feljebb vándorol, és az új szöveg a 21-be kerül.
Ha még van kiíratandó szöveg, akkor a felfelé csúsztatás addig folytatódik, amíg az egész kép ki nem cserélődik, ekkor jön az újabb

scroll?

Írjuk be a következő programot!

10 FOR i=1 TO 50 STEP 1
20 PRINT i
30 NEXT i

A 22-es és 44-es szám kiírása után láthatjuk a scroll?-t. Mivel az utolsó részben 6 kiíratandó szám van hátra, ezért a kép ekkor már csak 6 sornyit csúszik feljebb.

A PRINT-et használjuk akkor is, ha egyszerűbb számításokat akarunk végezni. A műveleti jelek némileg eltérnek attól, ahogyan az iskolában tanították.

művelet
jel
billentyű
összeadás
+
SYMBOL SHIFT + K
kivonás
-
SYMBOL SHIFT + 7
szorzás
*
SYMBOL SHIFT + B
osztás
/
SYMBOL SHIFT + V
 
(
SYMBOL SHIFT + 8
 
)
SYMBOL SHIFT + 9

A műveletek sorrendje a megszokott, tehát először mindig az osztást vagy a szorzást végzi el a gép, s csak utána az összeadást illetve a kivonást.

PRINT 2+3*4

ez 14 lesz, nem pedig 20. 20-at akkor kapnánk, ha előbb a 2-t adnánk a 3-hoz, és utána szoroznánk 4-gyel. Ha mégis ezt a sorrendet szeretnénk, akkor zárójelbe kell tenni az összeadást:

PRINT (2+3)*4

A további műveletekkel, illette a függvényekkel később találkozunk.

S most következhet a színezés.
Mint ahogy a billentyűkön is láthatjuk, a ZX Spectrum 8 színt használ. Színtévesztők kedvéért leírjuk a magyar megfelelőket is:

0 black fekete
1 blue kék (sötétkék)
2 red vörös
3 magenta bíbor
4 green zöld
5 cyan világoskék
6 yellow sárga
7 white fehér

Ez sorrend telítettségi (magyarán: sötétségi) sorrendet is jelent; minél nagyobb az azonosító szám, annál világosabb a szín. Így többé-kevésbé a fekete-fehér készülékek tulajdonosai is élvezhetik a színezés előnyeit. Sajnos nem lehet mindig minden képpontot tetszőleges színűre festeni. Minden karakterhelynek (8x8 képpontból álló képernyőterületnek) csak 2 színe lehet: egy háttér- és egy tinta szín. Ha a megfelelő angol szavakat szó szerint fordítjuk, akkor a háttér színét papírnak (PRPER), a mintáét tintának (INK) nevezzük.

10 PRINT PAPER 1; INK 6;"maci"
20 PRINT PAPER 0; INK 5;" cica"
30 STOP

A PAPER és az INK szó E módban SYMBOL SHIFT és a C illetve az X billentyű lenyomásával érhető el.
Ha azonos papír- és tintaszínt választunk, akkor a mintát nem látjuk, bár ott van. Próbáliuk ki!

10 PRINT PAPER 4; INK 4;"maci"

Ha ezt az egysoros programot lefuttatjuk, egy 4 karakternyi zöld sávot látunk, amelyben ugyanolyan zöld betűkkel benne van a maci szó, bár látni természetesen nem látjuk.
Ezen felel minden színnek létezik egy fényes változata is. Ez utóbbit a BRIGHT 1 beírásával az egész karakterre tudjuk megadni. Azaz nem lehet egy karakteren belül a papírszín fényes kék, a tintaszín nem fényes sárga. Egy példa:

10 PRINT FLASH 1; PAPER 1; INK 6;BRIGHT 1;"maci"

A BRIGHT fényest, a FLASH villogást, villanást jelent szó szerint. Mindkettő E módban érhető el (SYMBOL SHIFT + B illetve V). Ha a BRIGHT, FLASH, PAPER vagy INK utasítást (a megfelelő számot utána írva) beolvasztjuk egy PRINT-be, akkor az csak arra a kiíratásra vonatkozik. De használhatjuk őket önállóan is. Például a FLASH 1 utasítást követő minden kiírt szöveg villogni fog, amíg egy FLASH 0 utasítást nem iktatunk a programba. Próbáljuk ki!

5 FLASH 1
10 PRINT "ez villogni fog"
20 PRINT "ez is"
30 FLASH 0
40 PRINT "ez mar nem"


Ehhez hasonlóan próbáljuk ki a fényesség, a papír- és tintaszín át- illetve visszakapcsolását is.
A hasznos képernyőterületet övező keret (angolul BORDER) színét is kívánság szerint állíthatjuk.

BORDER 4

Ez a parancs zöldre festi a keretet, a Fradi-szurkolóknak így mégis kellemesebb látvány a képernyő.

FELADATOK:

  1. Írjunk színeket váltogatva szövegeket a képernyő különböző részeire.
  2. Kísérletezzünk! Figyeljük meg, hogyan reagál a gép, ha
    - nem létező sor- illetve oszlopszámot adunk meg a PRINT AT-ben illetve PRINT TAB-ban;
    - nem létező azonosító számot adunk meg a PAPER, INK, FLASH, BRIGHT, BORDER utasításokban.

Azoknak, akik még törtszámokkal is megpróbálkoznának, jelezzük, hogy a tizedesvessző helyett pontot vár a gép!

5. nap - Feltételes módban

Kezdjük ma is a tegnapi feladatok megoldásával! Az elsőhöz csak némi fantázia kellett.
2. Akinek nem volt türelme ahhoz, hogy végigjátssza az egészet, az a negyedik könyvben megtalálhatja az ide vonatkozó táblázatokat.

Térjünk vissza a rajzoláshoz!
Töltsük be a tegnapelőtti, KA32 néven felvett programot!

3 LET x=100: REM kezdeti hely
4 LET y=120: REM kezdeti hely
7 LET p=5: REM a pontok szama
8 LET t=3: REM pontok tavolsaga
10 FOR i=1 TO p STEP 1
20 PLOT x,y
30 LET x=x+t
35 NEXT i
40 FOR i=1 TO p STEP 1
50 PLOT x,y
60 LET y=y-t
65 NEXT i
70 FOR i=1 TO p STEP 1
80 PLOT x,y
90 LET x=x-t
95 NEXT i
100 FOR i=1 TO p STEP 1
110 PLOT x,y
115 LET y=y+t
120 NEXT i
125 LET x=x+5
127 LET y=y+1
130 GO TO 10

Elég sok mindent tud már a négyzetrajzoló programunk. Megadható az első négyzet bal felső sarkának helye (x,y), a négyzet egy oldalát alkotó pontok száma (P) és a pontok távolsága (t). Keveset törődtünk eddig a 125, 127-es sorokban az x-hez illetve y-hoz hozzáadott értékekkel. Ezek határozzák meg az előzőhöz képest az új négyzet helyét. Jelen esetben az új hely 5 képponttal jobbra (LET x=x+5), és 1 képponttal feljebb (LET y=y+1) kerül. Az 5 és az 1 nem örök értékek, de azért tegyük ezeket is
egy-egy dobozba.

125 LET x=x+ev
127 LET y=y+ef

Persze ezeknek a változóknak is kell kezdeti értéket adni, még éppen van két üres sorunk (5,6).

5 LET ev=5: REM elmozdulas vizszintesen
6 LET ef=1: REM elmozdulas fuggolegesen

Próbáljuk ki, hogy tudja-e még ugyanazt a program, mint a betöltés után! Ha nem, akkor valamit véletlenül kitöröltünk az új sorok beírásakor.

Mit tehetnénk azért, hogy még ügyesebb programot kapjunk?
Jó lenne folyamatossá tenni a rajzolást. Eddig ugyanis a képernyő szélére érve egy hibaüzenettel leáll a program futása, mert a PLOT x,y utasításban az x vagy y érvénytelen értéktű. Kellene egy olyan utasítás, amelyik csak: akkor lép közbe, ha baj van, más szóval, amikor kirajzolandó négyzetünk kilógna a képből. Természetesen létezik ilyen, úgynevezett feltételes utasítás.
Feltételekkel a mindennapi életben is számtalanszor találkozunk, néha észre sem vesszük őket.

Például: HA lesz idom, AKKOR elmegyek moziba.
A feltétel: hogy van-e idom vagy nincs. A teljesülés esetén (tehát ha van időm)
A következmény: megyek moziba.

Egy másik: HA több mint 70000 Forintom lesz, AKKOR befizetek egy autóra.
A feltétel: 70000 Ft-nál több pénzem legyen, akár 70001 Ft is elegendő.
A következmény - a feltétel teljesülése esetén -: befizetek egy autóra.

Ilyen példákat számtalanul tudna mindenki sorolni. Nézzük, hogy lehet ezt a gép nyelvére lefordítani! Nem véletlenül írtuk csupa nagy betűkkel a HA és AKKOR szavakat. Az angolban és a BASIC-ben ezeknek az IF és THEN felel meg. A fenti mondat így írható át:
IF több mint 70000 Ft-om lesz, THEN befizetek egy autóra.

Jó, jó, tudjuk, hogy így még nem érti a gép. De az

IF p>70000 THEN PRINT "befizetek egy autora"

már egészen használható lesz. (IF- U betű lenyomása K módban. THEN - SYMBOL SHIFT + G)
A > jel (SYMBOL SHIFT + T) a 'nagyobb, mint' szavakat helyettesíti. Ugye feltűnt, hogy a gép mennyire gondoskodik rólunk?

A THEN kiírása után a torsor automatikusan K-ra vált, hiszen most egy BASIC szónak kell következnie. Ha egy ilyen utasítást kell végrehajtania a gépnek, a következő történik: előveszi a p nevű változó tartalmát, és összehasonlítja 70000-rel. Ha nagyobbnak találja, akkor végrehajtja a THEN után álló utasítást; jelen esetben kiírja a "befizetek egy autóra" szöveget, és folytatja a program végrehajtását a következő sorral. Ha a p nevű változó értéke nem volt nagyobb, mint 70000 - tehát vagy éppen 70000 volt, vagy annál is kevesebb -, akkor nem hajtja végre a THEN után álló utasítást, hanem rögtan a következő sorra ugrik.
Írjunk be a 200-as sorszámtól néhány sornyi próba programocskát!

200 LET p=60000
210 IF p>70000 THEN PRINT "befizetek egy autora"
220 STOP

Futtassuk le ezt a programrészt! Ha beírnánk a szokásos RUN (ENTER) sort, akkor elindulna a négyzetrajzolás, de nekünk most csak a 200 sortól kellene indítanunk a futást. Ezt a

RUN 200

parancs beírásával tehetjük meg.
Azt látjuk, hogy nem látunk semmit, csupán a gép jelzi, hogy a STOP utasításnál a 220-as sorban leállt.

STOP 220:1

Ez jól is van így, hiszen a feltétel nem teljesült. A p értéke jóval kisebb, mint 70000.
Nem kell azonban örökre lemondanunk az autóbefizetésről, mert tegyük fel, jön egy barátunk, és azt ígéri, hogy ad kölcsön 15000 Ft-ot. Így egy kicsit módosítanunk kell a dolgokat! A 200-as sor marad, hiszen a saját pénzünk még mindig csak 60000, de a 210-es változik:

210 IF p+15000>70000 THEN PRINT "befizetek egy autora"

RUN 200

És máris ott díszeleg a képernyő bal felső sarkában a szöveg

befizetek egy autora

Ugyanis a kölcsönpénzzel együtt már 75000 Ft-om van, ami elegendő a befizetéshez.
Mi is történt most? A gép a 210-es sorhoz érve elővette a p nevű doboz tartalmát, hozzáadott 15000-et, és azután vizsgálta meg, vajon nagyobb-e az összeg 70000-nél, s mivel nagyobbnak találta, végrehajtotta a THEN után álló PRINT utasítást. Annak eredményét láttuk is a képernyőn. Most a feltétel teljesítésétől függően egy PRINT-et hajt végre vagy hagy ki a gép, de mindenképpen az IF-et tartalmazó sor után folytatja a programot.

Megtehetjük azt is, hogy a feltétel teljesülése esetén egész más sorszámnál folytatódjon a program végrehajtása. Ekkor a THEN után GO TO-nak kell állnia.

200 LET p=60000
210 IF p+15000>70000 THEN GO TO 300
220 PRINT "nem fizetek be"
230 STOP
300 PRINT "befizetek"
310 STOP

A gép a 210-es sornál válaszúthoz érkezik. Ha a feltétel teljesül, akkor a 300-as sorra ugrik, ha nem, akkor a 220-assal folytatja.

Mielőtt továbblépnénk, összefoglaljuk azokat a jeleket, amelyekkel leírhatjuk a feltételeket:

jel
magyarázat
billentyű
>
nagyobb, mint SYMBOL SHIFT + T
<
kisebb, mint SYMBOL SHIFT + R
=
egyenlő SYMBOL SHIFT + L
<>
nem egyenlő SYMBOL SHIFT + W
<=
kisebb, mint
vagy egyenlő
SYMBOL SHIFT + Q
>=
nagyobb mint,
vagy egyenlő
SYMBOL SHIFT + E

Ezek után nyugodt szívvel kitörölhetjük a gyakorló programrészt (200-310). Sajnos a SPECTRUM nem ismer olyan BASIC utasítást, amely egyszerre több sort töröl, így a már ismert módon, egyenként (a sorszámok beírásával + ENTER) tüntessük el a fölösleges sorokat!

Most már nekiláthatunk a rajzolóprogram okosabbá tételéhez! Vizsgáljuk meg, mi a feltétele annak, hogy a négyzet a képernyőn maradjon! Ehhez célszerű vázlatokat rajzolnunk. Tegyük fel, hogy négyzetünk egy oldala 8 képpontból áll, a pontok folyamatos vonalat alkotnak. Helyezzünk el egy-egy ilyen négyzetet a képernyő négy sarkában úgy, hogy ne lógjanak ki!

Az első négyzet koordinátái (a bal alsó saroktól való távolság vízszintes és függőleges irányban) x=0, y=175. A 2. négyzeté 0,7 (nem 8, mert 7-ig 8 képpont van). Ha csúsztatgatunk egy képzeletbeli négyzetet az 1. és 2. között, úgy, hogy az mindig érintse a kép bal szélét, akkor annak x koordinátája mindig 0, az y pedig 7 és 175 közötti értékű lehet.

HA x<0      AKKOR a bal oldalon lóg ki;
HA y>175 AKKOR felül lóg ki;
HA y<7      AKKOR alul lóg ki.

Csúsztassuk a bal felső sarokban levő négyzetet a jobb felső sarok felé! Mint látjuk, az y koordináta végig 1755, az x pedig 0 és 248 közötti értéket vesz fel. A 249 már sok lenne, a négyzet jobb széle kilógna a képből.
Így az eddigi 3 feltétel mellett kaptunk egy negyediket is:

HA x>148 AKKOR a jobb oldalon lóg ki.

Persze az előző feltételek továbbra is érvényben maradnak. Ha a kép jobb szélén és alján is végigtoljuk a négyzetünket, ugyanezekkel a feltételekkel találkozhatunk. Ha 8 képpontból áll a négyzet egy oldala, akkor alul és jobb oldalt kapunk egy 8 képpontból álló tiltott sávot. A bevonalkázott sáv láthatóan éppen olyan széles, hogy a négyzet elférjen benne. Ha nagyobb négyzetet szeretnénk, akkor a sáv is automatikusan hízik.

9 képpontú négyzetoldal esetén a határértékek:

x<0
x>247 (247=255-9+1)
y<8     (7=0+9-1)
y>175

Máris megtehetjük az általánosítást:
Ha H darab végpontból áll egy négyzetoldal, más szóval a H nevű dobozban tároljuk a négyzet oldalhosszát, vajon hogyan lehet kiszámítani a H értékét? Folytonos vonal esetén, amikor t=1 (t a ponttávolság) az oldalhossz éppen a pontok száma + 1 (p+1).
Emlékezzünk vissza: a 4 képpont oldalhosszú négyzetet 4 darab 3 pontos részből rajzoltuk ki, tehát itt a pontok számán az egy ciklus teljes lefutása alatt kirajzolt pontok darabszámát értjük.
Mi a helyzet, ha a t nem 1?

Például: t=3 és p=5!

H=5*3+1

nyílván, ha t=4 és p=6, akkor

H=6+4+1

tehát a H értékét a p és t változókból

130 LET h=p*t+1

utasítással számolhatjuk ki. Ezzel a régi

130 GO TO 10

sor törlődik, ezért a visszaugrató utasítást írjuk be a 160-as sorba:

160 GO TO 10

Most jöhetnek az ellenőrző sorok!

135 IF x<0 THEN PRINT AT 0,0;"a bal oldalon log ki"
140 IF x>256-h THEN PRINT AT 0,0;"a jobb oldalon log ki"
145 IF y<h-1 THEN PRINT AT 0,0;" alul log ki "
150 IF y>175 THEN PRINT AT 0,0;" felul log ki "

Adjunk különböző értékeket az ev és et változóknak, hogy mindegyik: feltétel teljesülését ellenőrizhessük!
Példák: A kezdeti hely minden esetben: x=100 és y=120
ef=1 és ev=5 értékeknél a

a jobb oldalon log ki

üzenetet olvashatjuk, míg az ef=3 és ev=5 esetében a

felul log ki

kissé más a helyzet, ha ef=-17, ev=5. Megjelenik ugyan az

alul log ki

szöveg, de a négyzetek mintegy visszapattanva az alsó sorról, tovább rajzolódnak; a képernyő teteére érve viszont nem íródik ki a

felul log ki

szöveg, csak a hibaüzenet figyelmeztet a helytelen értékre. Ráadásul a visszapattanás után a pontok rajzolási iránya is megfordul, most éppen az óramutató járásával ellenkező.
Kövessük nyomon, mi is történt! Ehhez magát a gépet hívjuk segítségül. Írjuk be a

155 PRINT AT 1,0;"x= ";x;" y= ";y;

sort. Minden négyzet kirajzolás előtt ki íródik a négyzet bal felső sarkának koordinátája. S ha így futtatjuk le a programot, meg is van a megoldás.
Emlékszünk, hogy a PLOT után írt számok előjelét a gép nem veszi figyelembe, így negatív számokat is pozitívnak véve a rajzolás folytatódik. Viszont a képernyő tetejére érve az ellenőrzés nem működik, hiszen ott azt vizsgáljuk, hogy 175-nél nagyobb-e az y. A képen y=-167 1átható, de nem ez az utolsó y érték. Hogy mennyi, arról könnyen meggyőződhetünk

PRINT y

-178. A PLOT utasítás viszont nem figyeli a számadatok előjelét; számára a -178 ugyanannyi, mint +178, ami persze több, mint 175, ezért jogos a leállás meg a hibaüzenet.
Hasonló a helyzet az ef=1 és ev=-13 értékeknél is. Mint láttuk, egy gyanús jelenségnek viszonylag könnyű utána járni; nem kell mást tenni, mint az érintett változókat kiíratni, ezt még a leállás után is megtehetjük, mert a gép nem felejti el az értékeket.
Egyenlőre hagyjuk benn ezt a nyomkövető sort, így jobban megfigyelhetjük, hogy mi is történik, sőt még le is lassíthatjuk a dolgokat a

157 PAUSE 100

Utasítással, mely a nevéből is kitalálhatóan szünetet jelent, mégpedig a jelen esetben éppen 2 másodpercnyit.
(A PAUSE után írt szám arányos a várakozási idővel, így a PAUSE 50 1 másodpercet, míg a PAUSE 200 4 másodpercet jelent. A maximális érték 255 lehet. A PAUSE 0 viszont nem 0 várakozási időt jelent: ilyenkor mindaddig áll a program, amíg egy billentyűt le nem nyomunk.

Összefoglalva: bár a bal oldalon és alul nem csúszott ki a négyzet ám a negatív értékek kissé megzavarják a programot. Ezért a PRINT-ek helyett olyan utasítást kellene a THEN után tennünk, amely megváltozatja a nem kívánt értékeket, fenntartva ezzel a rajzolás folyamatosságát.
Ha jobbra ment volna ki a négyzet, annak oka az volt, hogy a 125-ben az x a hozzáadott ev (vízszintes eltolás) értékkel túl nagyra nőtt. Tudjuk azt, hogy ha levonnánk az x-ből (azaz az eddig pozitív ev-t negatívvá tennénk), akkor az balra mozdítaná a négyzetet. Mi sem egyszerűbb ennél!

LET ev=-ev

Ez annyit tesz: vegyük az ev értékét ellenkező előjellel, más szóval szorozzuk meg az ev-t -1-gyel s legyen ez az ev új értéke.
Ez az előjel fordító utasítás a bal oldali kicsúszásnál is ugyanilyen jól jön, mert akkor a negatív ev-ből pozitívat kell csinálni.
Módosítsuk az IF-es sorokat!

140 IF x>256-h THEN LET ev=-ev: LET x=x+ev

Tehát először megfordítottuk az ev előjelét s uána hozzáadtuk az x-hez.

Mint már korábban említettük, egy sorba több utasítást is írhatunk, ha azokat kettősponttal elválasztjuk egymástól. Hangsúlyozzuk azonban, hogy mindkét LET csak akkor kerül sorra, ha a feltétel teljesült.
Még egyszer gondoljuk át! A 140-ben a jobbra kilógás feltétele csak akkor teljesül, ha az x túl nagyra nőtt. Ezt csak az okozhatta, hogy a 125-ben valamilyen pozitív számot adtunk x-hez. Ezért ev-ből negatív számot csináltunk, s utána máris hozzáadtuk az x-hez, de egy negatív szám hozzáadása csökkenti az eredeti számot. Ezután a 125-ben mindig csökkenni fog az x értéke mindaddig, amíg valahol át nem fordul újra ellenkezőre az ev. Ez a valahol nem más, mint a

135 IF x<0 THEN LET ev=-ev:LET x=x+ev

Hasonló módon járunk el a

145 IF y<h-1 THEN LET ef=-ef:LET y=y+ef
150 IF y>175 THEN LET ef=-ef:LET y=y+ef

csupán az ev változó szerepét most az ef vette át.
Vegyünk egy mély lélegzetet, mert bizony nem kis nehézséget gyűrtünk most le, viszont reméljük, hogy megérte a fáradságot, hiszen most már akármennyi négyzetet lerajzol a programunk kicsúszás nélkül. Próbáljuk is ki!

RUN (ENTER)

Egy idő után nem látunk újabb négyzeteket, a program azonban nem állt le, csak a már meglévő pontok helyére rajzolódnak az újak. Ilyenkor BREAK-kel (CAPS SHIFT + SPACE) a program leállítható.

L Break into program

A futás újraindítható a

CONTINUE

(magyarul: FOLYTASD) paranccsal (C betű + ENTER).

Ha átírjuk a megfelelő változókat, egészen más rajzolatot kapunk. Ha nem félnénk attól, hogy a gőgösség vétkét vesszük magunkra, azt mondhatnánk: készítettünk egy mintatervező programot.

Vegyük fel a programot KA52 néven kazettára!

3 LET x=69: REM kezdeti hely
4 LET y=19: REM kezdeti hely
5 LET ev=9: REM vizsz. elmoz.
6 LET ef=2: REM fuggo. elmoz.
7 LET p=8: REM a pontok szama
8 LET t=1: REM pontok tavolsaga
10 FOR i=1 TO p STEP 1
20 PLOT x,y
30 LET x=x+t
35 NEXT i
40 FOR i=1 TO p STEP 1
50 PLOT x,y
60 LET y=y-t
65 NEXT i
70 FOR i=1 TO p STEP 1
80 PLOT x,y
90 LET x=x-t
95 NEXT i
100 FOR i=1 TO p STEP 1
110 PLOT x,y
115 LET y=y+t
120 NEXT i
125 LET x=x+ev
127 LET y=y+ef
130 LET h=p*t+1
135 IF x<0 THEN LET ev=-ev:LET x=x+ev

140 IF x>256-h THEN LET ev=-ev: LET x=x+ev
145 IF y<h-1 THEN LET ef=-ef:LET y=y+ef
150 IF y>175 THEN LET ef=-ef:LET y=y+ef
155 PRINT AT 1,0;"x= ";x;" y= ";y;"   "
157 PAUSE 100
160 GO TO 10

FELADATOK:

  1. A 3-8 sorokban előforduló változó értékek módosításával készítsünk különböző mintákat a képernyőn!

  2. Módosítsuk a KA 52 programot, hogy négyzet helyett téglalapot rajzoljon!

6. nap - Most a gép kérdez

Nem lennénk hívek önmagunkhoz, ha most elfeledkeznénk a tegnapi feladat megoldásáról. Töltsük hát be a KA51-es programot!
A 155-ös és a 157-es sort kitörölhetjük, ha nincs szükségünk az x, y kiírogatására. Mint már korábban is láttuk, a négyzetet könnyedén téglalappá torzíthatjuk, ha a pontok távolsága vízszintesen és függőlegesen nem azonos.

8 LET tv=4: REM pontok tavolsaga vizszintesen
9 LET tf=3: REM pontok tavolsaga fuggolegesen

Ezzel a 30-as és a 70-es sorban a t helyére tv, a 60-asban és a 115-ösben tf kerül.

30 LET x=x+tv
60 LET y=y-tf
90 LET x=x-tv
115 LET y=y+tf

Ennek megfelelően az oldalhosszúságnak sem elegendő egy változó (H).

130 LET hv=p*tv+1: REM vizszintes oldalhossz
132 LET hf=p*tf+1: REM fuggoleges oldalhossz

Persze a 140-es, és a 145-ös, sor is változik.

140 IF x>256-hv THEN LET ev=-ev: LET x=x+ev
145 IF y<hf-1 THEN LET ef=-ef: LET y=y+ef

S maris próbálhatjuk új művünket!

3 LET x=69: REM kezdeti hely
4 LET y=78: REM kezdeti hely
5 LET ev=9: REM vizsz. elmoz.
6 LET ef=2: REM fuggo. elmoz.
7 LET p=8: REM a pontok szama
8 LET tv=4: REM pontok tavolsaga vizszintesen
9 LET tf=3: REM pontok tavolsaga fuggolegesen
10 FOR i=1 TO p STEP 1
20 PLOT x,y
30 LET x=x+tv
35 NEXT i
40 FOR i=1 TO p STEP 1
50 PLOT x,y
60 LET y=y-tf
65 NEXT i
70 FOR i=1 TO p STEP 1
80 PLOT x,y
90 LET x=x-tv
95 NEXT i
100 FOR i=1 TO p STEP 1
110 PLOT x,y
115 LET y=y+tf
120 NEXT i
125 LET x=x+ev
127 LET y=y+ef
130 LET hv=p*tv+1: REM vizszintes oldalhossz
132 LET hf=p*tf+1: REM fuggoleges oldalhossz
135 IF x<0 THEN LET ev=-ev:LET x=x+ev

140 IF x>256-hv THEN LET ev=-ev: LET x=x+ev
145 IF y<hf-1 THEN LET ef=-ef: LET y=y+ef
150 IF y>175 THEN LET ef=-ef:LET y=y+ef
160 GO TO 10

Ezzel annyi variációs lehetőséghez jutunk, hogy már-már azt érezhetjük, végtelen sok fajta ábrát tudunk készíteni. Ha nem is próbáljuk ki az összeset, néhányat azért megmutatunk.
Például:

x=69
y=78
ev=-11
pf=2
p=13
tv=2
tf=3

Természetesen biztosan léteznek ennél sokkal jobb ábrák is.

Többször szóba kerültek már a színek. Itt az ideje, hogy kiszínezzük a képünket.
A PRINT-hez hasonlóan a PLOT-ba is beépíthetjük a PAPER, INK, BRIGHT és FLASH színező utasításokat. Persze most is érvényes az alapelv, hogy egy karakterben (8x8 képpontból álló részben) csak egy-egy papír- és tintaszínt adhatunk meg, illetve az egész karakterre érvényesen BRIGHT 1 vagy 0 és FLASH 1 vagy 0 értéket állíthatunk be.

PLOT PAPER 2; INK 6;46,75
PLOT PAPER 2; INK 6; FLASH 1;46,75

Mint látjuk, a színezés mindig az egész karakterre vonatkozik. Hogy a kiválasztott képpont melyik karakterhelyhez tartozik, azt a mellékletben található, úgynevezett raszterábrán nézhetjük meg.
Már előre gondoskodjunk az egyszerű színváltoztatási 1ehetőségekről. Minden PLOT x,y utasítást (20, 50, 80, 110) egészítsünk ki

PLOT PAPER pp; INK ti,x,y

alakúra, és már csak egy helyen, a program elején kell megadnunk a színeket. A 2 sorszámot még nem használtuk.

2 LET pp=7: LET ti=0: REM papir es tinta szin

s máris színesben láthatjuk a világot. Fekete-fehér tévét használók számára csak a szürke különböző árnyalatai jutnak, de így is megfigyelhetjük a karakteres színezési rendszert.
Ha egy kép annyira megtetszett, hogy szeretnénk megtartani, akkor a

SAVE "kep" SCREEN$

(a SCREEN$ elérése: E mód K) utasítással menthetjük ki.
Az elmentett kép a

LOAD "kep" SCREEN$

utasítással hozható vissza.
Az idézőjelek köze - ahogy eddig is tettük - bármilyen, legföljebb 10 betűs betű-szám kombinációt írhatunk.

Már viszonylag ügyes kis programunk van. Akár másnak is odaadhatnánk. Csakhogy aki nem ismeri a SPECTRUM sorok szerkesztési műveleteit, az nem tudja megváltoztatni a LET utasításokba előre beírt értékeket. Jó, jó, el lehetne magyarázni a legfontosabb tudnivalókat, de létezik erre egyszerűbb módszer is.
Azokban a sorokban, ahol kezdeti értékeket adunk meg, a LET-ek: helyére INPUT utasításokat kell írni. (A szó jelentése beadás, bevitel.) Mielőtt megcsináljuk a javításokat, próbáljuk egy kicsit kivesézni az INPUT-ot!
Írjuk be az

INPUT cica

parancsot! Az ENTER lenyomása után a sor elején egy villogó L vagy C látható, attól függően, hogy kis- vagy nagybetűs üzemmódban vagyunk. A gép mindaddig várakozik, amíg be nem írunk egy számot. Próbáljuk ki például a 123 értéket, a beírást az ENTER lenyomásával fejezzük be!

0 OK, 0:1

üzenet jelzi, hogy minden rendben. A képernyő egyébként üres, de a gép nem felejtette el az általunk beírt számot: a cica nevű dobozban tárolja. A

PRINT cica

paranccsal ellenőrizhetjük is.
Ez rendben is lenne, de a rajzolóprogramunkban több értéket kellene megadni (papírszín, tintaszín, kezdeti hely stb.), s vajon honnan fogja tudni a majdani felhasználó, hogy éppen melyik érték van soron? Ezen is lehet segíteni.

1000 INPUT "Hany eves vagy?";
1020 PRINT "Azt mondtad, hogy ";e;" eves vagy."

PUN 1000-rel lefuttatva:
A villogó L előtt a "Hany eves vagy?" szöveg olvasható, s így mindjárt világos, hogy mi a teendőnk.
Az 1020-as sorral 3 dolgot íratunk ki: elsőként az "Azt mondtad, hogy"-ot, s mivel az idézőjel után pontosvessző áll, ezért közvetlenül mellé az e változó tartalmát (az imént megkérdezett évek számát), majd az e után álló pontosvessző miatt folytatólagosan az "eves vagy" szöveget.

Futtassuk le újra, de most anélkül, hogy bármilyen számot beírnánk, rögtön nyomjuk le az ENTER-t! A gép nem bírja az ilyen lazaságokat, s a villogó L elé tolakodó kérdőjel máris figyelmeztet mulasztásunkra.
Próbáljunk most meg betűkkel válaszolni a kérdésre. Például írjuk be a

tizenegy

szót! A gépnek ezt eszében sincs elfogadni, ehelyett a

2 Variable not found, 1000:1

üzenetet írja ki. Az történt, hogy a gép - mivel számot vár - azt hiszi, a tizenegy nevű dobozban fogja azt megtalálni, de mivel ilyet nem talál, kénytelen a fenti üzenettel közölni hiányérzetét.
Ezek szerint a gép csak számokat tud tárolni? No nem, ez nem lenne ésszerű. Javítsuk ki az 1000-est!

1000 INPUT "Hany eves vagy?";e$

A $ jel elérése: SYMBOL SHIFT + 4.

RUN 1000

Most látjuk, hogy a villogó L két idézőjel közé szorult. Ide már bármilyen szöveget - betűkből, számokból, írásjelekből álló sorozatot - beírhatunk.
Hurrá! Hiszen ezek szerint elég a változónév után egy $ jelet tennünk, s máris elfogadja a gép, akár betűt, akár számot írunk. Csakhogy a gép másként kezeli az ilyen úgynevezett szöveges és a korábbi, számok tárolására használt - idegen szóval numerikus - változókat. Szúrjuk csak be ezt a sort:

1010 LET e$2+e$

Nem fogadja el a gép, csakúgy, mint az

1010 PRINT e$+1

sort sem.
Tehát a matematikai műveleteket a gép nem tudja elvégezni szöveges változókon.
Pontosabban: egy kivétel mégis van. Írjuk be a következőket:

1000 LET a$="harom"
1010 LET b$=" kismalac"
1020 LET c$=a$+b$
1030 PRINT c$

Mint látjuk, az 1020-as sorban a két szöveg egymás mellé téve kerül a c$ nevű dobozba.
Ám van lehetőség arra is, hogy szöveghez ily módon számot ragasszunk, mindössze idézőjelbe kell tennünk:

1000 LET a$="3"

No és mi a helyzet, ha a kívánt szám egy dobozban van? Például:

990 LET a=3

Az 1000-ben az a változónév elé STR$ kerül (elérése: E módban Y):

1000 LET a$=STR$ a

RUN 990

s ott van a kívánt két szó:

3 kismalac

Megnyugodhatunk: nem keveredett össze az a nevű numerikus és az a$ nevű szöveges változó, hiszen - mondtuk is már ezt - a gép külön kezeli őket. A STR$-ban az STR a string szó rövidítése, ez magyarra fordítva zsinórt (kissé szabadabban fordítva láncot) jelent. A szöveges változó idegen neve string-változó: ez az elnevezés azt akarja kifejezni, hogy ez a fajta doboz egy számokból, betűkből és jelekből álló, úgynevezett karaktersorozat, vagy más néven karakterlánc tárolására alkalmas. Tehát a STR$ szerepe nem más, mint az, hogy átalakítja az a változóban talált számot úgy , hogy az egy szöveges változóba betehető legyen.

Ha már itt tartunk, elmondjuk, hogy ez a fajta típusátalakítás visszafelé is működik. A VAL utasítással visszakapjuk a szöveges változó tartalmának értékét, feltéve, hogy az csak számokból állt. Így:

1030 LET e$="6"
1040 PRINT VAL e$+3

Vigyázzunk: a VAL elérése E módban J. Ha esetleg eközben a SYMBOL SHIFT-et is lenyomva tartjuk, akkor a VAL helyett VAL$ jelenik meg. Ez nagyon ritkán használatos, ezért most itt nem is magyarázgatjuk az értelmét.
S az eredmény: 9

Hirtelen elég sok újdonsággal találkoztunk, tekintsük át őket még egyszer!

Változók
Fajta Mit tárol Értékadás Név Példa
numerikus számot LET
INPUT
READ (erről később)
max. 255 betűből és számból álló karaktercsoport (mindíg betűvel kezdődik) 5
3.141
-26.2
szöveges
(más nlven karakteres vagy string)
betűt, számot, írásjeleket
(de a számokat is szövegként kezeli)
LET
INPUT
READ
egy betű és a $ jel hurrá
három
5rigó

A gép a változónevekben azonosnak tekinti a kis- és nagybetűket. Így összesen csak 26 különböző szöveget lehet tárolni? Látszólag igen, de nincs vész: lesz majd módunk sokkal több szöveg tárolására is.
Mint láttuk, a változóknak LET-tel és INPUT-tal lehet értéket adni.

LET   INPUT
A változó mindig ugyanazt az értéket kapja minden futtatásnál   Ehhez az utasításhoz érve a futás leáll, és mindaddig várakozik, míg a program felhasználója be nem ír egy értéket (típustól függően számot vagy szöveget); a változó értéke futásonként más és más lehet

Ezután töröljük ki a próbasorokat (220-1030), és térjünk vissza a rajzolóprogramunkhoz. Írjuk át a 2-9 sorok LET-jeit INPUT-ra! Íme a teljes kijavított lista!

2 INPUT "papir szin? ";pp: INPUT "tinta szin? ";ti
3 INPUT "kezdeti hely vi.koordinata? ";x
4 INPUT "kezdeti hely fu.koordinata? ";y
5 INPUT "vizszintes elmozdulas? ";ev
6 INPUT "fuggoleges elmozdulas? ";ef
7 INPUT "pontok szama? ";p
8 INPUT "pontok tavolsaga vizszintesen?";tv
9 INPUT "pontok tavolsaga fuggolegesen?";tf
10 FOR i=1 TO p STEP 1
20 PLOT PAPER pp; INK ti;x,y
30 LET x=x+tv
35 NEXT i
40 FOR i=1 TO p STEP 1
50 PLOT PAPER pp; INK ti;x,y
60 LET y=y-tf
65 NEXT i
70 FOR i=1 TO p STEP 1
80 PLOT PAPER pp; INK ti;x,y
90 LET x=x-tv
95 NEXT i
100 FOR i=1 TO p STEP 1
110 PLOT PAPER pp; INK ti;x,y
115 LET y=y+tf
120 NEXT i
125 LET x=x+ev
127 LET y=y+ef
130 LET hv=p*tv+1: REM vizszintes oldalhossz
132 LET hf=p*tf+1: REM fuggoleges oldalhossz
135 IF x<0 THEN LET ev=-ev:LET x=x+ev

140 IF x>256-hv THEN LET ev=-ev: LET x=x+ev
145 IF y<hf-1 THEN LET ef=-ef: LET y=y+ef
150 IF y>175 THEN LET ef=-ef:LET y=y+ef
160 GO TO 10

7. nap - Pihenés, de nem a gépnek

A hetedik nap a pihenésé. No de szó sincs henyélésről, kapcsolódjunk ki aktívan! Tervezzünk egy teljes képernyőnyi szöveget, mondjuk egy, névjegykártyát vagy megívót.
Változatosabbá tehetjük a kiírt szövegeket, ha helyenként inverz, azaz fordított betűvel írunk. No, nem fejjel lefelé állókra gondolunk, hanem a papír és tinta, színének megcseréléséről. Így:

10 INVERSE 1
20 PRINT "ez a szoveg inverzben latszik"
25 PRINT "ez is"
30 INVERSE 0
40 PRINT "ez mar nem inverz"

Az INVERSE elérése: E módban M.
Az egész olyan, mint egy kapcsoló. Az INVERSE 1 utasítással megcseréljük az eddig használt papír és tintaszínt. S mindaddig ez a változat marad, amíg egy INVERSE 0 utasítással vissza nem térünk az eredetire. Az INVERSE után csak a 0 vagy 1 számjegy írható, mivel ki- vagy bekapcsoljuk. Ha 2-215 közötti számot írunk utána,

K invalid colour,

255-nél nagyobb illetve negatív számok esetén:

B Integer out of range

hibaüzenet jelzi a hibánkat. Ha véletlenül tört számot írnánk , azt a gép a szokásos módon kerekíti.
Ha azt akarjuk, hogy csak egy szöveg legyen inverzben, nemcsak az a megoldás jó, hogy az adott PRINT utasítás elé teszünk egy INVERSE 1-et és utána egy INVERSE 0 utasítást, hanem az INVERSE 1-et beírhatjuk a PRINT-be s az adott szöveg kiírásakor automatikusan visszaáll az eredeti helyzet. Töröljük a 10-40 sorokat, és írjuk be:

10 PRINT INVERSE 1;"csak ez lesz inverz"
20 PRINT "ez mar nem"

Mindez talán nem volt nagyon meglepő, hiszen, ha emlékezünk, így működött a villogás (FLASH), a fényesség (BRIGHT) ki- és bekapcsolása és a papír- tintaszín változtatása is. Az inverz módot azonban még egy szövegen belül is ki- és bekapcsolhatjuk. Tegyük fel, a mozi szót akarjuk úgy kiírni, hogy az első két betűje inverz, a második kettő normál legyen, A PRINT és az idézőjel beírása után átkapcsolhatunk inverz módba az INV VIDEO paranccsal (CAPS SHIFT + 4). Látszólag semmi nem történt, de ha most lenyomjuk az M és az O billentyűt, akkor ez a két betű inverzben látszik már alul a beíró sorban is. Ezután a TRUE VIDEO paranccsal (CAPS SHIFT + 3) visszatérhetünk az eredeti állapothoz. A TRUE szó jelentése egyébként igazi, valódi. Így akár betűnként váltogathatjuk az inverz módot a normállal.
Ha eleget ismerkedtünk az inverz kiírással, következzék még egy lehetőség, amellyel változatosabbá tehetjük a képernyőre kerülő szöveget.

10 PRINT AT 0,0;"elozo"
15 PAUSE 200
20 PRINT AT 0,0;"ujabb"

Semmi meglepő, az előző sor 4 másodperc után nyomtalanul eltűnik, s helyébe az újabb lép.
Szúrjuk be a 10-es és a 20-as sorba az OVER 1 utasítást! (Az OVER elérése: E módban: SYMBOL SHIFT + N.) A 10-es láthatóan ugyanúgy működik, de a 20-a csak valami zavaros kriksz-krakszot ír ki. Pedig mindkettő jól működik. A helyzet kulcsa az OVER 1-ben van. Ennek hatása eltér a megszokott PRINT utasításoktól.
Eddig egy betű kiírása átfestette az egész 8x8 képpontból álló képernyőterületet, a betűrajzolat helyén tinta-, a maradék helyeken papírszínűre. Így egy új betű kiírásával az előző automatikusan eltűnik. Ugyanakkor OVER 1 hatására a PRINT másként viselkedik. Képzeljük el az egész képet úgy, mintha pici lapocskákból állna, ezek egy oldala papír-, a másik tintaszínű. Az ábrák rajzolatát a tintaszínű oldalával felfelé néző lapocskák alkotják. Az OVER 1 hatására a kiírandó betűk pontjainak helyén a lapocska megfordul, a többi helyen változatlan marad.
Mindez alighanem egy kicsit bonyolultan hangzik, de az ábránk talán mindent megvilágít:


Így már érthető az is, hogy üres helyre íráskor az OVER 1-nek nincs különleges hatása.
Próbáljuk ki a következőt!

10 PRINT AT 4,0;e"
20 PRINT AT 4,0;OVER 1;"'"

A ' jel (neve aposztróf) elérése: SYMBOL SHIFT + 7, s lám, ékezetet varázsoltunk az e betűre.
Egyébként az OVER 1 működése hasonlít a többi PRINT kiegészítő utasításhoz (PRIGHT, FLASH, INVERSE). Használhatjuk a PRINT-be beépítve, de külön utasításként. Ilyenkor - ahogy azt várnánk is - OVER 0-val lehet hatástalanítani. Ha 0 vagy 1-en kívül más számot írunk az OVER után, akkor ugyanazokat a hibaüzeneteket kapjuk, mint FLASH, BRIGHT és INVERSE esetében.
Eme kis kitérő után nekiállhatunk a tervezésnek! Engedjük el nyugodtan a fantáziánkat, de a jól sikerült végeredményt ne feledjük kazettán rögzíteni az utókor számára!


Második hét

1. nap - A szubrutin, avagy az alvállalkozó

Mielőtt nekigyűrkőznénk a második hétnek, gondoljunk vissza az előzőre! Van egy - még nem túl ügyes - rajzolóprogramunk, és tudtunk egy, képernyőnyi szöveget tervezni. Reméljük, hogy mindenki készített legalább egy, meghívót vagy névjegyet. Ugye ez nem semmi De hol van még az út vége?!
Folytassuk a munkát főművünkkel, a rajzolóprogrammal! Töltsük vissza a kazettáról, vagy gépeljük be az alábbi listát!

2 INPUT "papir szin? ";pp: INPUT "tinta szin? ";ti
3 INPUT "kezdeti hely vi.koordinata? ";x
4 INPUT "kezdeti hely fu.koordinata? ";y
5 INPUT "vizszintes elmozdulas? ";ev
6 INPUT "fuggoleges elmozdulas? ";ef
7 INPUT "pontok szama? ";p
8 INPUT "pontok tavolsaga vizszintesen?";tv
9 INPUT "pontok tavolsaga fuggolegesen?";tf
10 FOR i=1 TO p STEP 1
20 PLOT PAPER pp; INK ti;x,y
30 LET x=x+tv
35 NEXT i
40 FOR i=1 TO p STEP 1
50 PLOT PAPER pp; INK ti;x,y
60 LET y=y-tf
65 NEXT i
70 FOR i=1 TO p STEP 1
80 PLOT PAPER pp; INK ti;x,y
90 LET x=x-tv
95 NEXT i
100 FOR i=1 TO p STEP 1
110 PLOT PAPER pp; INK ti;x,y
115 LET y=y+tf
120 NEXT i
125 LET x=x+ev
127 LET y=y+ef
130 LET hv=p*tv+1: REM vizszintes oldalhossz
132 LET hf=p*tf+1: REM fuggoleges oldalhossz
135 IF x<0 THEN LET ev=-ev:LET x=x+ev

140 IF x>256-hv THEN LET ev=-ev: LET x=x+ev
145 IF y<hf-1 THEN LET ef=-ef: LET y=y+ef
150 IF y>175 THEN LET ef=-ef:LET y=y+ef
155 REM PRINT AT 1,0;"x= ";x"
157 REM PAUSE 1
160 GO TO 10

A 7. napon tanult OVER 1 és INVERSE 1 utasítások a PLOT-ot is kiegészíthetik.

1 PLOT OVER 1; 0,0
2 PLOT OVER 1; 0,0
3 STOP

Láthatóan nincs semmi érdekes a képen. Az 1-es sor kirajzol egy pontot, a múltkori hasonlattal élve: a tinta színű felével felfelé fordítja a lapocskát. A második PLOT OVER 1 visszafordítja a papírszínű felére, azaz letörli a pontot. No, ezzel biztosan érdekes rajzokat lehet csinálni. Töröljük ki az l-es, 2-es és 3-as sort!
A 20, 50, 80 és 110-es sorban kellene a PLOT-ot az OVER 1-gyel kiegészíteni. Egyetlen kis módosításért 4 sort átírni? Ez kicsit túlzásnak tűnik! S persze ugyanennyi változtatásra van szükség akkor is, ha át akarunk térni INVERSE 1-re, vagy akár visszatérni az eredeti állapothoz. Természetesen létezik egyszerűbb megoldás is. A fenti négy sor pontosan egyforma, tehát egyetlen sorral helyettesíthető. Peti lenne, ha mondjuk beírnánk a

200 PLOT OVER 1; PAPER pp; INK ti; x,y

sort, a 20, 50, 80 és 110-es sorokat pedig átírnánk

GO TO 200 -ra?

Addig rendben van a dolog, hogy a fenti négy sor mindegyikéből a 200-ra küldjük a programot, ahol valójában a pontrajzoló utasítás található. Igen ám, de hogy találunk vissza a 30, 60, 90 és 115-ös sorra? A csavarosabb eszűek nyílván azt mondják: valamilyen módon nyílván kellene tartani, hogy honnan ugrottunk a 200-ra, és ennek megfelelően kiszámíthatjuk, hova kell visszamenni. Meg lehetne csinálni, de ez a fajta probléma nagyon sűrűn előfordul. A BASIC nyelv megalkotói kitaláltak erre egy utasítást, pontosabban egy utasításpárt: a GO SUB-ot és a RETURN-t.
Ha valaki azt kérdezné, hogy ezek ugyanolyan elválaszthatatlan testvérek-e, mint a FOR és a NEXT, igennel válaszolnánk, hozzátéve azt, hogy a kérdező nagyon jól látja a dolgok lényegét. Azt sejtjük, hogy a GO SUB a GO TO-hoz valamennyire hasonlít, de egy kicsit azért más. A kettő közti különbséget egy kis hasonlattal jellemeznénk:

GO TO: Menj el, kisfiam, a nagymamához, ő majd megmondja, mi a teendőd.

GO SUB: Menj el, kisfiam, a nagymamához, s ha megcsináltad azokat a dolgokat, amiket ő kért tőled, azonnal gyere vissza!

Már írhatjuk is a módosításokat!
(GO SUB: K módban H)

20 GO SUB 200
50 GO SUB 200
80 GO SUB 200
110 GO SUB 200

S mivel a pont kirajzolása után nincs más teendő, vissza kell térni.

200 PLOT OVER 1; PAPER pp; INK ti; x,y
210 RETURN

(RETURN: K módban az Y)
A nagymamát kihagyva a dologból, az történik, hogy a 20-as sorból a program a 200-asra ugrik, végrehajtja a pont kirajzolását, s a RETURN hatására visszatér a 20-as után következő sorra, ami most éppen a 30. Ehhez hasonlóan az 50-esnél 50 - 200 - 210 - 60 a sorrend, s ez ugyanígy megy a 80 illetve 110-es sornál is.
A GO SUB a GO (menj) és a subroutine angol szavak összeolvasztásából született. A routine magyarított megfelelője a rutin szó, ami hétköznapi értelemben gyakorlottságot, ügyességet jelent. A szub-ot összetételekben szoktuk használni, úgy mint pl. szubtrópusi éghajlat. A szubrutin alatt egy elkülöníthető, önállóan működő programrészt értünk. Ez lehet akármilyen hosszú, tartalmazhat akármilyen utasításokat, csak a végén RETURN-nek kell állnia.
A RETURN jelentése: visszatérés (ejtsd: ritörn).
Összefoglalva: egy szubrutint csak egy GO SUB (ejtsd: gouszab) utasítással hívhatunk meg, a szubrutin végét a RETURN utasítás jelzi.

Egy dologra érdemes ügyelnünk: ha GO SUB nélkül kerülünk bele a szubrutinba, akkor a RETURN-höz érve a gép elbizonytalanodik, mert nem tudja, hova kell visszatérnie, s eme kétségeit egy hibaüzenet formájában adja tudtunkra.

7 RETURN without GO SUB

(magyarul: GO SUB nélküli RETURN)

A szubrutin alkalmazásának alapvető előnyei:
Ugyanazt a részprogramot egyszer kell beírnunk, s annyiszor hivatkozhatunk rá, ahányszor akarunk. Így nemcsak rövidebb programot írhatunk, hanem a javítás és a módosítás is egyszerűbb; és a program még áttekinthetőbb lesz. Megjegyezzük még, hogy egy szubrutin hívhat más szubrutinokat is, akár olyat is, amelyik maga is hív további szubrutinokat és így tovább.

Kezdhetjük a kísérletezgetést! Próbáljuk ki az OVER 1 mellett az OVER 0, INVERSE 1 és INVERSE 0 változatokat is!
Mint mondtuk, a szubrutinok használatával könnyebben áttekinthető programot tudunk készíteni. Nézzük meg, hogyan is lehetne ezt alkalmazni!
A 2-9 sorokban található kezdeti értékbeállító utasításokat számozzuk át 422-429 közötti sorszámokra! Tegyük a végére lezárásként a

439 RETURN

sort. A 420-ba írjunk egy megjegyzést, amely a szubrutin tartalmára utal, ilyesformán:

420 REM 420-439 a valtozok kezdeti ertekenek beallitasa

A program elején hívjuk meg az így alkotott szubrutinokat

4 GO SUB 420

Látszólag ez a változtatás nem túl hasznos, de holnap meg fogjuk látni, hogy mégsem volt hiábavaló. Mentsük ki a programot KB11 néven.

FELADAT:

1. Próbáljuk ki az alábbi kis progamot!

5 LET i=0: LET j=0
10 LET i=i+1
12 PRINT AT 0,0;i,j
15 GO SUB 50
18 PRINT "a"
20 RETURN
50 LET j=j+1
60 PRINT AT 0,0;i,j
70 GO SUB 10
80 PRINT "b"
90 RETURN

Néhány perc elteltével a képernyőn két szám:

6875      6874

s egy hibaüzenet olvasható

4 Out of memory error 60:1

(Jelentése: elfogyott a memória)
Próbáljuk megmagyarázni a jelenséget!

2. nap - A kocka el van vetve

Akinek sikerült magyarázatot adnia a tegnap felvetett problémára, két piros pontot is kiutalhat magának jutalmul (akit esetleg valami más jobban ösztönöz, beválthatja tetszés szerint bármire).

Kövessük végig a program futását!

5 - 10 - 12 - 15 - 50 - 60 - 70
      10 - 12 - 15 - 50 - 60 - 70
      10 - 12 - 15 - 50 - 60 - 70

És így ismétlődik tovább.
A 15. és 70. sorban szubrutinhívás történt, ugyanakkor a program RETURN-t mindig elkerülte. Talán ez okozta a bajt? Ennek megválaszolásához a szubrutin mint utasítás működését kell egy kicsit boncolgatnunk. Ugye azt már korábban megállapítottuk: a GO TO és a GO SUB között az a különbség, hogy az utóbbi esetében a gép tudja, hol hívták meg , s ha RETURN-nel találkozik, akkor a meghívást követő utasításhoz tér vissza (programunkban a 15 GO SUB 50 esetében a 18-ra, a 70 GO SUB 10 esetében pedig a 80-ra). Hogyan jegyzi meg a gép, hová kell visszamennie? Nyilván úgy, hogy ezt az információt valamilyen módon elrakja a memóriába, hogy majd elővegye, ha a RETURN-hoz ért. Csakhogy a mi esetünkben kizárólag az elrakások követték egymást,, az elővétel elmaradt.
Nincs olyan mély gödör, amelyik meg ne telne, ha elég kitartóan lapátolunk bele; ezért ne csodálkozzunk, hogy egyszer az erre fenntartott hely is betelik. Végül is most 6875-ször sikerült eltenni a 18-as sorszámot, s eggyel kevesebbszer a 80-ast. Magát az elrakás folyamatát nem részletezzük, csupán annyit jegyzünk meg, hogy mindig a legutóbb eltett értékeket veszi vissza a gép, így amit először rakott el, azt hozza vissza utolsóként.
Eddig állandóan arról beszéltünk, hogy a számítógépnek mindent hajszálpontosan elő kell írnunk, különben mindig éppen azt teszi, amit nem akarunk.

Aki már látott valamilyen játékprogramot, az tudja, hogy ott nem mindig egyformán játszódnak le a jelenségek, tehát vannak dolgok, melyekről a számítógép önállóan,

MINTEGY "VÉLETLENÜL" DÖNT.

A véletlen szónak több, egymástól bizonyos mértékig eltérő jelentése is van. Szoktuk azt mondani: Véletlenül otthon hagytam ezt vagy azt. Itt az "akaratunk, szándékunk ellenére" érte értelemben használtuk a véletlent. A "Véletlenül találkoztam Zolival" mondat azt jelenti, hogy nem beszéltük meg előre a találkozást. Véletlennek tulajdonítjuk, hogy az eldobott játékkocka melyik oldala kerül felülre. Pedig, ha pontosan tudnánk a dobás minden fizikai jellemzőjét (a dobás sebessége, iránya, az asztal felülete, a kocka alakja, felülete, stb.), akkor előre megmondhatnánk a dobás kimenetelét. Itt a véletlent olyan helyzetben használjuk, amikor nincs elég információnk a folyamatról, így a végeredményt nem tudjuk előre megmondani. Természetesen az ilyen véletlen jelenségeken alapulnak a szerencsejátékok is.
A számítógépünk képes egy számot véletlenszerűen előállítani. Erre az RND utasítást használjuk. Rövidítése az angol random (ejtsd: random), azaz véletlen szónak. Hívjuk elő az RND-t (E módban T), és nyomjuk le az ENTER-t! Bizony ott villog a kérdőjel, a gép nem érti, mit akarunk. Ez nem is véletlen, hiszen nem mondtuk meg, mit is kellene tennie a véletlen számmal. Például írassuk a képernyőre!

PRINT RND

Megjelenik egy hosszú szám:

.0011291504

Történelmi pillanat: előállítottunk (idegen szóval: generáltunk) egy véletlen számot. Kicsit furcsán néz ki, de nemsokára megbarátkozhatunk vele. Arról már volt szó, hogy a tizedesvessző helyett a BASIC (és az angol is) tizedespontot (.) használ. A tizedespont előtt áll még egy 0, de ezt spórolásból nem írta ki a gép. Ezt egyébként beíráskor mi is megtehetjük, azaz a 0 egész elhagyható, elég, ha a tizedesponttal kezdjük az ilyen törtek beírását.
Próbáljuk ki újra!

PRINT RND

S az eredmény: 0.08581543

Hűha! Mit lehet kezdeni az ilyen szörnyű hosszú tizedestörtekkel? Mindenesetre lehet őket vizsgálgatni. Írassunk ki belőlük mondjuk húszat!

10 FOR i=1 TO 20
20 PRINT RND
30 NEXT i

Ránézésre azt sejtjük, hogy a számok 0 és 1 közé esnek. Ha már itt vagyunk, ellenőrizzük a feltevésünket!

10 LET i=1
20 LET x=RND
30 IF x<=0 THEN PRINT x,i: STOP
40 IF x>=1 THEN PRINT x.i: STOP
50 LET i=i+1
60 GO TO 20

A 20-as sorban előállított véletlen számot az x változóban tároljuk
A 30-as sorban megvizsgáljuk, hogy x kisebb vagy egyenlő-e 0-val, ha ez teljesül, akkor kiírjuk azt a véletlen számot meg az i-t (ami nem mást tesz, mint nyilvántartja, hány véletlen számot generáltunk már), A kiírás után meg is áll a program, hogy leolvassuk a kívánt értékeket.
A 40-es sorban ehhez hasonlóan akkor íródik ki az x és az i értéke, ha az előállított véletlen szám 1 vagy annál nagyobb volt.
Ha egyik feltétel sem teljesül, akkor újabb véletlen számot kell generálnunk. Ehhez máris megnöveljük a darabszámlálót (50) és megyünk vissza a 20-ba újabb számért (60).

Ha elindítjuk a programot, mindaddig üres marad a képernyő, ameddig nem sikerült elállítani a 0 vagy annál kisebb, illetve 1 vagy ennél nagyobb számot. Hosszú percek fognak így eltelni. Ha valakit zavarna az üres képernyő, írja be a

25 PRINT AT 0,0; x,i

Sort! Így a kép tetején mindig leolvasható, milyen számot generált a gép, és hol tartunk. Nyugodtan hagyhatjuk futni a programot, kimehetünk inni valami frissítőt. Előbb-utóbb ott az eredmény a képernyőn, 0-tsikerült előállítania a gépnek.
Indítsuk újra a programot, ismét elmehetünk egy kis időre. Újra x=0 értéknél fog megállni a program.
Véletlen-e a véletlenek között, hogy NEM KERÜLT ELŐ az 1 vagy annál nagyobb, illetve negatív szám? Talán igen, talán nem. Járjunk utána!

Ehhez meg kellene vizsgálnunk, van-e valamilyen ismétlődés a számok sorozatában. Ehhez az x változóban tárolt véletlen számot addig kell összehasonlítanunk nagyobb s újabb véletlen számokkal, amíg azonosat nem találunk.

10 LET i=1
20 LET e=RND
25 PRINT AT 0,0;i
28 LET x=RND
30 IF x=e THEN PRINT i,x: STOP
50 LET i=i+1
60 GO TO 25

Az első véletlen szám az e változóba, második és az összes többi az x-be kerül; mivel a 60-ból a 25-be térünk vissza. Az e értéke nem módosul, így a 30-asban az elsőként generált véletlen számot hasonlítjuk az éppen soron levővel.
Újabb negyedóra, s máris kiderült: 65536 véletlen szám generálása után került elő újra ugyanaz a szám. Persze ez lehet véletlen is. Ismét csak ellenőrizzük! No de hogyan? Nem kell más, mint írjunk ki 20 véletlen számot, azután csináljunk 65516 (65536-20=65516)generálást, amelyeknek az eredményét nem vesszük figyelembe, majd az ezt követő 20 darab számot kiírjuk és összehasonlítjuk az előzővel.

10 FOR i=1 TO 20 STEP 1
20 PRINT AT i,0;RND
30 NEXT i
40 FOR i=1 TO 65516 STEP 1
50 LET x=RND
60 NEXT i
70 FOR i=1 TO 20 STEP 1
80 PRINT AT i,16;RND
90 NEXT i

A 10-30 és 70-90 sorban egyformán 20 darab véletlen számot írunk ki, a kiírás helyének megadásához felhasználtuk a ciklusváltozót (i); ez mondja meg, melyik sorba kerüljön a kiírandó szám: az első ciklusnál mindig a sor elejére, a másodiknál a 16. oszlopba. Így elértük, hogy a két húszas számcsoport megfelelő tagjai egymás mellé kerüljenek, ezzel az összehasonlítás szemmel láthatóan egyszerűbb. A 40-60 sorokban semmi más nem történik, mint a 65536 véletlen szám generálása.
A türelem nemcsak rózsát, de időnként végeredményt is terem. Kiderült, hogy 0 és 1 közé eső számok kerülnek elő, méghozzá úgy, hogy a 0 köztük van, de az 1 nem.
A véletlen számok nem is annyira összevisszák, hiszen csupán 65536 van belőlük (legalábbis a SPECTRUM ennyit tud csak előállítani), de azért ez sem kevés. Most már csak az a kérdés, milyen sorrendben jön elő ez a 65536 különböző szám. Hozzuk alapállapotba a gépet (kihúz-bedug), s írjuk be:

PRINT RND

Az eredmény már jól ismert:

.0011291504

Ha kikapcsoljuk, és újra be a

PRINT RND

Sort, megint csak a fenti számot kapjuk. Igen, úgy tűnik, hogy a különböző véletlen számok mindig ugyanabban a sorrendben jönnek elő, hacsak nincs egy olyan utasítás, amely ezt megváltoztatja. Van ilyen:

RANDOMIZE

(K módban a T). Kapcsoljuk ki újra a gépet, majd írjuk be:

10 RANDOMIZE
20 PRINT RND

Így az eredmény egészen más. Viszont ha a RANDOMIZE után 1-65535 közé eső számot írunk, akkor mindig ugyanazt a véletlen szám kerül elő. Próbáljunk ki néhányat!

10 RANDOMIZE 1
20 PRINT RND

Cseréljük ki a 10-es sort a következőkre:

RANDOMIZE 100
RANDOMIZE 65535
RANDOMIZE 0

Az utóbbi ugyanolyan hatású mit a szám nélküli RANDOMIZE.
A randomize (ejtsd: rendomájz) angol ige, jelentése: véletlenszerűen elrendez. Próbáljuk ki a felvett véletlen generálást ellenőrző programunkat kiegészíteni a RANDOMIZE 0, RANDOMIZE 1, RANDOMIZE 100, stb. utasításokkal.

Akkor foglaljuk össze!
A SPECTRUM 65536 darab, különböző, 0 és 1 közé eső véletlen számot tud előállítani, a 0 köztük van, az 1 nem. Ezek a számok mindig ugyanolyan sorrendben jönnek elő, a 65536. után a sorozat kezdődik elölről. Úgy képzelhetjük, mintha egy kör mentén lenne lerakva 65536 darab szám, és a RANDOMIZE-zal módosíthatjuk az első kitett érték helyét. A következő RANDOMI2E-ig a véletlen számok sorban kerülnek elő. Még csak annyit, hogy a gép valójában nem tárolja ezt a rengeteg számot (nincs is elegendő hely benne ekkora adattömeg számára), hanem mindig egy képlet segítségével számolja ki a következő értéket.
Tegyük számunkra élvezhetőbbé a véletlen számokat!

20 FOR i=1 TO 20
30 PRINT RND*10
40 NEXT i

Mit várunk? Minden véletlen számot 10-zel szoroztunk, így az értékek 0 és 10 közé esnek. Vajon köztük lehet-e a 10? Bizony nem, hiszen az eredeti számok között nem volt ott az 1, márpedig a 10-et csak 1-gyel szorozva lapunk 10-et. A törtek helyett jó lenne csak egész számokkal dolgoznunk. Ehhez

30 PRINT INT(RND*10)

módosítást kell beírnunk.

Az INT elérése: E módban R,
A ( elérése: SYMBOL SHIFT + 8
A ) elérése: SYMBOL SHIFT + 9

Az INT az angol INTEGER (ejtsd: intedzser), "egész szám" rövidítése.
Az INT hatására az RND*10 értékből lefelé kerekített egész szám keletkezik. Próbáljunk ki parancs módban egy-két értéket!

PRINT INT 5.2
5
PRINT INT 6.9
6
PRINT INT -2.3
-3
PRINT INT -3.9
-4

A zárójelekre azért volt szükség, mert anélkül a gép a műveleteket más sorrendben végezte volna el. Vegyük ki a két zárójelet, s futtassuk le így a programot! Csupa 0-t kapunk, ugyanis a gép így először a generált véletlen számot kerekítette le, ami természetesen minden esetben 0 lett, azt már hiába szorozta 10-zel, az eredmény ugyanúgy 0 maradt.
Cseréljük ki a 10-et 15-re, s a várakozásnak megfelelően 0 és 14 közötti számokat kaptunk. (Ha a sorból hiányozna valamelyik szám, indítsuk újra a programot, és előbb-utóbb biztosan előkerül mindegyik.) Vajon mit kell írni a 15 helyére, hogy 0 és 100 közé eső számokat kapjunk, úgy, hogy a 0 és a 100 is köztük legyen? A válasz természetesen 101. A szorzószám éppen azt határozza meg, hány darab különböző szám jöhet elő.

INT(RND*10)

esetében 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ez éppen 10 darab,

INT(RND*101)

Esetében 0 és 100 között 101 szám van a 0-t és a 100-at is beleértve.
Mi a helyzet akkor, ha 1 és 6 közé eső számokat szeretnénk generálni?

30 PRINT INT(RND*6)

Mint láttuk, 0 és 5 közé esőket csinál, ha a 6-ot 7-re cseréljük, akkor 0 és 6 közöttieket. Melyik változatot lehetne könnyebben módosítani a kívánt cél elérése érdekében?

 
INT (RND*6)
INT (RND*7)
meglevő:
0, 1, 2, 3, 4, 5
0, 1, 2, 3, 4, 5, 6
cél:
1, 2, 3, 4, 5, 6
1, 2, 3, 4, 5, 6

A második esetben csak a 0-t kell kihagyni a generált számok közül, ehhez - mint tudjuk - egy külön IF utasítást kellene beiktatnunk. Az elsőnél az egymás alá írt sorokból talán már nyilvánvaló, hogy csak 1-et kell hozzáadni a generált véletlen számhoz, s akkor éppen a kívánt értékeket kapjuk. Így:

30 PRINT INT (RND*6)+1

A számok helyett változók is lehetnek:

30 PRINT INT (RND*s)+h

De ne feledkezzünk el a kezdeti érték megadásáról:

10 LET s=6
15 LET h=1

Ezzel szimulálhatunk kockadobást. A szimulál latin eredetű szó, jelentése: tettet, színlel. Szimulánsnak hívjuk azt, aki úgy tesz, mintha beteg lenne, pedig egészséges. Most a szimulál igét olyan értelemben használtuk, hogy a számítógép jelen esetben HELYETTESÍTETTE A DOBÓKOCKÁT, elvégezte a kockadobást.
Milyen értékeket kell a h és s változónak adnunk, hogy

  1. 10 és 100 közötti számokat kapjunk?
  2. -10 és +10 közötti számokat kapjunk?

1. Mint láttuk, bármekkora is a szorzószám (s), az INT (RND*s) legkisebb értéke 0 lesz, hiszen az RND 0-tgenerál, és azt bármennyivel is szorozzuk, 0-t kapunk. Ezért ha a hozzáadott szám (h) 10, akkor az alsó határt már teljesítettük. A szorzószámnak (s) tehát annyinak kell lennie, mint ahány különbözőszám van a két határ között (a határértékeket is beleértve).
10 és 100 között 91 szám van.

1. 10
2. 11
3. 12
...
90. 99
91. 100

így:

10 LET S=91
15 LET h=10

2. A legkisebb érték -10; ez lesz a h értéke.
-10 és +10 között21 szám van:

1. -10
2. -9
3. -8
...
10. 0
...
20. 9
21. 10

10 LET s=21
15 LET h=-10

Az s értéke nem más, mint a két határkülönbsége+1.
Automatizáljuk az s és h kiszámítását! Az alsó és felsőhatár értékét INPUT kérdezze meg!

3 INPUT "also hatar? ";a
6 INPUT "felso hatar "; f
10 LET s=f-a+1
15 LET h=a

Pihenésül töröljük ki a memóriában lévő programot, és írjuk be a következő négy sort:

10 LET x=INT (RND*22)
20 LET y=INT (RND*32)
30 PRINT AT x,y; OVER 1;"*"
40 GO TO 10

Itt az ideje, hogy beépítsünk egy véletlen számokat előállító szubrutint a rajzolóprogramunkba! Már tudjuk, hogy a véletlent is kordában lehet tartani. Adjuk meg a határokat az alábbiak szerint!

pp: 0 - 7
ti:   0 -7
x:   70 - 180
x:   40 - 110
ev: -10 - +10
ef: -10 - +20
p:  2 - 12
tv: 1 - 5
tf:  1 - 5

A szubrutint írjuk a 250-270 sorokba!

250 REM a valtozok kezdeti ertekenek bealitasa veletlen szamokkal
252 LET pp=INT (RND*8)
254 LET ti=INT (RND*8)
256 LET x=INT (RND*111)+70
258 LET y=INT (RND*41)+70
260 LET ev=INT (RND*21)-10
262 LET ef=INT (RND*21)-10
264 LET p=INT (RND*11)+2
266 LET tv=INT (RND*5)+1
268 LET tf=INT (RND*5)+1
270 RETURN

A szubrutin azonban semmit nem ér meghívás nélkül.

5 GO SUB 250

Így feleslegessé vált a 4. sor? Látszólag igen, de ne töröljük ki! Nem biztos, hogy mindig mindent a véletlenre akarunk bízni, például elég sűrűn előjöhetnek szerencsétlen színkombinációk. Ennek elkerülése érdekében ti-nek és pp-nek adjunk állandó értékeket! A legegyszerűbb, ha először minden változónak fix értékeket adunk, majd a pp és a ti kivételével az összeset kicseréljük, hivatalosabb szóval: felülírjuk véletlen számokkal.
Ehhez elegendő az

5 GO SUB 256

módosítás. Ezzel kihagytuk a pp-nek és ti-nek véletlen értékeket adó sorokat.
Ha tv és tf változókkal szeretnénk ugyanezt tenni, akkor

265 GO TO 270

Beszúrással érhetünk célt. Így kis módosításokkal a kilenc változó bármelyikének adhatunk véletlen értékeket, a fennmaradók pedig megtartják az előző szubrutinban kapott állandó számot.
Sokkal nehezebb dolgunk ellen, ha minden alkalommal külön azokat is ki kellene válogatni, amelyeknek fix értékeket adunk. (A gép nem fog panaszkodni a túlmunka miatt.) Persze lehetne ezt fordítva is csinálni, azaz először véletlen számot tölteni mindegyik változóba, majd a kiválasztottakat felülírni állandó értékekkel.
Próbáljunk ki néhány változatot, majd mentsük ki KB21 néven.

Mint látjuk, programunk szép lassan hízik. Ezért egy újabb rész beépítése után mindig nézzük át az egészet!

4 GO SUB 420
5 GO SUB 250
10 FOR i=1 TO p STEP 1
20 GO SUB 200
30 LET x=x+tv
35 NEXT i
40 FOR i=1 TO p STEP 1
50 GO SUB 200
60 LET y=y-tf
65 NEXT i
70 FOR i=1 TO p STEP 1
80 GO SUB 200
90 LET x=x-tv
95 NEXT i
100 FOR i=1 TO p STEP 1
110 GO SUB 200
115 LET y=y+tf
120 NEXT i
125 LET x=x+ev
127 LET y=y+ef
130 LET hv=p*tv+1: REM vizszintes oldalhossz
132 LET hf=p*tf+1: REM fuggoleges oldalhossz
135 IF x<0 THEN LET ev=-ev:LET x=x+ev
140 IF x>256-hv THEN LET ev=-ev: LET x=x+ev
145 IF y<hf-1 THEN LET ef=-ef: LET y=y+ef
150 IF y>175 THEN LET ef=-ef:LET y=y+ef
160 GO TO 10
200 REM 200-210 rajzolas
201 PLOT PAPER pp; INK ti; OVER 1;x,y
210 RETURN
250 REM a valtozok kezdeti ertekenek bealitasa veletlen szamokkal
252 LET pp=INT (RND*8)
254 LET ti=INT (RND*8)
256 LET x=INT (RND*111)+70
258 LET y=INT (RND*41)+70
260 LET ev=INT (RND*21)-10
262 LET ef=INT (RND*21)-10
264 LET p=INT (RND*11)+2
266 LET tv=INT (RND*5)+1
268 LET tf=INT (RND*5)+1
270 RETURN
420 REM 420-439 valtozok kezdeti ertekenek beallitasa
422 LET pp=7: LET ti=0: REM papir es tintaszin
423 LET x=69: REM kezdeti hely
424 LET y=78: REM kezdeti hely
425 LET ev=-5: REM vizszintes elmozdulas
426 LET ef=2: REM fuggoleges elmozdulas
427 LET p=9: REM pontok szama
428 LET tv=2: REM pontok tavolsaga vizszintesen
429 LET tf=3: REM pontok tavolsaga fuggolegesen
439 RETURN

FELADATOK:

  1. Hogyan lehetne csak páros illetve csak páratlan számokat előállítani véletlenszerűen?

  2. Állítsuk elő véletlen számokat, melyek 1 és 100 köz esnek és 5-re végződnek!

3. nap - Billentyűfigyelés

Az előző napi feladatok megoldásai:

1. Írjuk egymás alá a páros számokat, írjunk mindegyik elé sorszámot!

1. 2
2. 4
3. 6

stb.

Ebből már láthatjuk is, hogy a megoldás kulcsa: szorozni kell kettővel.
Állítsuk elő a 100-nál kisebb páros számokat! Közülük a legnagyobb a 98., ezért induljunk ki az 1 és 49 közötti számokból (98/2=49)! Nevezzük ezt házi használatra alapsávnak!

10 FOR i=1 TO 20 STEP 1
20 LET alap=INT (RND*49)
30 PRINT AT i,2;alap
99 NEXT i

Ha az alapot 2-vel szorozzuk, megkapjuk a kívánt páros számokat.

40 LET paros=2*alap
50 PRINT AT i,6;paros

Ezután ugyanezt a páratlan számokra már gyerekjáték megcsinálni!

60 LET paratlan=paros-1
70 PRINT AT i,10;paratlan

A legnagyobb szám így 97, de nem lehet 2 hozzáadásával megoldani a dolgot, mert akkor a legkisebb szám 3 lesz. Az alapsávot kell átírnunk. A múltkor már megfigyeltük, hogy éppen annyi szám készül, amennyi az RND után álló szorzószám. No de 1 és 99 között éppen 50 darab páratlan szám van; cseréljük hát ki a 49-et 50-re!

20 LET alap=INT (RND*50)

és minden rendben van. Csak a jobb áttekinthetőség kedvéért használtunk ennyi változót, a páros számok esetében elég lett volna a:

10 FOR i=1 TO 20 STEP 1
20 PRINT AT i,2;(INT (RND*49)+1)*2
30 NEXT i

sorok beírása, s ha a 49-et átírjuk 50-re máris megvannak a kívánt páratlan számok is.

2. Itt már csak a megoldást közöljük:

10 FOR i=1 TO 20 STEP 1
20 PRINT AT i,2;(INT (RND*10))*10+5
30 NEXT i

Foglalkozzunk újra a rajzolóprogrammal, de még ne töltsük be! A legeredetibb ábrákat bizonyára mindenki akkor készítené, ha saját maga folyamatosan irányíthatná a rajzolást. Ennek sincs semmi akadálya. Kinézünk magunknak néhány billentyűt, mindegyiknek megfelel majd egy irány. Az egyik lenyomása megadja az új téglalap helyét. Már ismerünk egy utasítást, amellyel A PROGRAM FUTÁSA KÖZBEN VÁLASZOLHATUNK a gép kérdéseire, azaz adhatjuk meg vagy módosíthatjuk a változók értékét. Ez az utasítás az INPUT. Csakhogy ezzel most elég nehéz lenne dolgozni, hiszen az INPUT hatásara mindig leáll a program, megvárja, amíg beírunk egy számot vagy betűt, s csak az ENTER lenyomása után megy tovább.
Van azonban erre a célra egy sokkal hasznosabb utasítás, mégpedig az

INKEY$

Próbáljuk ki a következő kis programot!

10 IF INKEY$="c" THEN PRINT "Megnyomtad a C-t":STOP
15 PRINT AT 0,0;INT (RND*10)
20 GO TO 10

Egymás után jelennek meg a véletlen számok, mindaddig, amíg meg nem nyomjuk a 'c' billentyűt, ekkor kiíródik a

Megnyomtad a C-t

szöveg. Mi is történt? A gép időnként (másodpercenként 50-szer) megnézi, hogy vajon megnyomtuk-e valamelyik billentyűt. Ha igen, akkor a megnyomott billentyű bal felső részén látható betűt vagy számot beteszi az INKEY$ nevű speciális változóba. A speciális annyit jelent, hogy LET-tel nem tudunk értéket adni neki.
Azért próbáljuk ki!

LET INKEY$="c"

A villogó kérdőjel figyelmeztet arra, hogy valami olyat írtunk, amit a gép nem fogad el.
Az INKEY szó az INPUT és a KEY szavak összevonásából született. Az elsővel már találkoztunk, a második jelentése kulcs, vagy - ebben az esetben ez a fontos: billentyű - (ejtése: kí). Tehát az INKEY billentyű beolvasást, bekérést jelent; a hozzáragasztott $ pedig - ugyanúgy, mint közönséges változók esetén - jelzi, hogy a változóban karaktereket (betűt, számot, jelet) tárolhatunk.
Írjuk be a

5 PRINT AT 0,0;"z"
10 PRINT AT 0,0;INKEY$
20 GO TO 10

programocskát.
Indítás után, amíg nem nyomunk le semmit, addig a z ott díszeleg a bal felső sarokban. Ilyenkor az INKEY$-ban egy úgynevezett üres karakter (üres string) van, ami azt jelenti, hogy a PRINT-nek nincs mit kiírnia, ezért marad ott a z. Az üres karaktert ne tévesszük össze a szóköz (space) billentyűvel, mert ha azt nyomjuk le, akkor a z eltűnik. Próbáljuk végig az egész billentyűzetet! Ha egyidejűleg a CAPS SHIFT-et is lenyomva tartjuk, a nagybetűk kerülnek a képre, a SYNBOL SHIFT segítségével a billentyű bal felső sarkában látható piros jelek, szavak, ahogy ezt idáig megszoktuk.
Az INKEY$ segítségével a program leállítása nélkül kérdez tőlünk a gép. Olyan ez, mint egy üzenőfüzet, ahová a program futása közben is írhatunk. (A játékprogramok futása közben is hasonló módon avatkozhatunk be az eseményekbe: a program figyeli, hogy melyik billentyűt nyomjuk meg, és aszerint módosítja a továbbiakat.)

Most töltsük he a KB21 programot!
Egy ábra berajzolása a 120. sorban fejeződik be, a 125 és 127 módosítja és állítja be az újnak a helyét. Ezért a 120 és a 125 közé kell beszúrnunk a billentyűfigyelést. Persze ez is egy szubrutin lesz. Elsőként csak négy irányt veszünk figyelembe. Legyen a 4 kiválasztott billentyű az 5,6,7,8. Csupán azért, mert a felettük levő nyilak segítik az irány kiválasztását. A megnyomott billentyűnek megfelelően az ev és ef változóknak kell valamilyen értéket adnunk. Mint tudjuk, az

ev a vízszintes,
ef a függőleges eltolást jelentette.

Irány
billentyű
ev
ef
bal
5
-1
0
jobb
8
+1
0
fel
7
0
1
le
6
0
-1

Most már írhatjuk magát a kiegészítést:

300 IF INKEY$="5" THEN LET ev=-1:LET ef=0
310 IF INKEY$="6" THEN LET ev=0:LET ef=-1
320 IF INKEY$="7" THEN LET ev=0:LET ef=1
330 IF INKEY$="8" THEN LET ev=1:LET ef=0
340 RETURN

Ne feledkezzünk el a meghívásról sem:

122 GO SUB 300

Próbáljuk ki néhányszor az új műveletet, aztán csináljuk meg a 8 irányú mozgatást!
Jelöljük ki a billentyűket az ábrának megfelelően!

Persze bármilyen más elrendezést is választhattunk volna. Kis táblázatunk mutatja az irányoknak megfelelő ev és ef értékeket:

Irány
billentyű
ev
ef
fel
t
0
1
jobbra-fel
y
1
1
jobbra
h
1
0
jobbra-le
b
1
-1
le
v
0
-1
balra-le
c
-1
-1
balra
d
-1
0
balra-fel
r
-1
1

Ezek után már a kisujjunkból kirázzuk ezt a néhány sort:

300 REM billentyu figyeles
302 LET b$=INKEY$
305 IF b$="t" THEN LET ev=0:LET ef=1
310 IF b$="y" THEN LET ev=1:LET ef=1
320 IF b$="h" THEN LET ev=1:LET ef=0
330 IF b$="b" THEN LET ev=1:LET ef=-1
340 IF b$="v" THEN LET ev=0:LET ef=-1
350 IF b$="c" THEN LET ev=-1:LET ef=-1
360 IF b$="d" THEN LET ev=-1:LET ef=0
370 IF b$="r" THEN LET ev=-1:LET ef=1
380 IF b$="f" THEN LET ev=0:LET ef=0
390 RETURN

A kiválasztott billentyűre nem elég egyszerűen ráütni, folyamatosan nyomva kell tartanunk, és csak akkor engedjük el, ha a gép már végrehajtotta a változtatást.

Legyünk telhetetlenek! A billentyűvel ne csak az elmozdulást vezéreljük, hanem az OVER 1 - OVER 0 váltását is (mint emlékszünk, ez utóbbi a normál üzemmód). Ehhez a pontot kirajzoló szubrutinban kell az OVER 1-ben az 1 helyére egy változónevet írnunk - legyen ez ov, csak azért, hogy emlékeztessen az OVER szóra.

201 PLOT PAPER pp; INK ti; OVER ov;x,y

Ne feledkezzünk el a kezdeti értékek megadásáról!

430 LET ov=1: REM OVER 1 vagy 0 bekapcsolasa

Az lenne a jó, ha ugyanaz a billentyű, amelyik az irányt meghatározza, állítana be az ov értékét 0-ra illetve 1-re. Mint láttuk, a kis- és nagybetűket a CAPS SHIFT-tel tudjuk váltani. Így a t és T egyaránt a felfelé mutató irányt jelentené, de az egyik az OVER 1-et, a másik pedig az OVER 0-t kapcsolna be.
Módosíthatjuk így is:

305 IF b$="t" THEN LET ev=0:LETef=1:LET ov=1
307 IF b$="T" THEN LET ev=0:LETef=1:LET ov=0

Ez nem a legelegánsabb megoldás, hiszen 8 újabb sor beírását igényli.
Ha a b$ változó értéke t vagy T, akkor ugyanazokat az értékeket kell ev-be és ef-be írnunk, csak az ov eltérő, de ezzel most ne törődjünk. Ez a mondat így hangzik, ha "lefordítjuk BASIC-re":

IF b$="t" OR b$="T" THEN LET ev=0:LET ef=1

újdonság csupán az OR szó, jelentése az angolban és a BASIC-ben: VAGY.
Ha bármelyik feltétel teljesül, akkor a gép a THEN után álló utasítást vagy utasításokat hajtja végre. Különben a következő sorra lép. A fentiek szerint módosítsuk a 305 és 370 közötti sorokat!

305 IF b$="t" OR b$="T" THEN LET ev=0:LET ef=1
310 IF b$="y" OR b$="Y" THEN LET ev=1:LET ef=1
320 IF b$="h" OR b$="H" THEN LET ev=1:LET ef=0
330 IF b$="b" OR b$="B" THEN LET ev=1:LET ef=-1
340 IF b$="v" OR b$="V" THEN LET ev=0:LET ef=-1
350 IF b$="c" OR b$="C" THEN LET ev=-1:LET ef=-1
360 IF b$="d" OR b$="D" THEN LET ev=-1:LET ef=0
370 IF b$="r" OR b$="R" THEN LET ev=-1:LET ef=1

Egyezzünk meg abban, hogy ha a kiválasztott iránybillentyűvel együtt a CAPS SHIFT-et is lenyomtuk, akkor az ov értéke legyen 0, ellenkező esetben 1. Most mar csak azt kellene eldöntenünk, vajon kis- vagy nagybetűt nyomtunk-e le. Beírhatnánk az

IF b$="T" OR b$="Y" OR b$="H" OR b$="B" OR b$="V" OR b$="C" OR b$="D" OR b$="R"

sort. Hat ez elég szörnyű lenne. Van persze más lehetőség is, de mielőtt elárulnánk a megoldást, tegyünk egy kis kitérőt! Egyszer, még az első napok valamelyikén említettük, hogy a számítógép mindent számok formájában tárol, így van ez a betűkkel is. Egy kicsit olyan ez, MINT EGY TITKOSÍRÁS, ahol a betűket számok helyettesítik. (Ha már szóba került megjegyezzük: a normál írás titkosírássá alakítását kódolásnak vagy sifrírozásnak; a megfejtését - azaz a titkosírás olvashatóvá változtatását - dekódolásnak, vagy desifrírozásnak nevezzük idegen szóval.)
A gép titkosírásának kulcsát a CODE utasítás segítségével tudhatjuk meg, pl.

PRINT CODE "a"

az eredmény

97

ugyanígy

PRINT CODE "A"

az eredmény: 65

A dekódoló, azaz az adott számhoz tartozó betűt visszaadó utasítás a CHR$. Ezt is Kipróbálhatjuk:

PRINT CHR$ 65

és megkaptuk az A betűt.
Így egyenként is végigpróbálgathatjuk az egész betűkészletet, ha nagyon ráérünk, de sokkal gyorsabb, ha írunk rá egy kis programot.

1000 FOR i=32 TO 255 STEP 1
1010 PRINT i,CHR$ i
1020 NEXT i

Így egy sorban látható a szám és a megfelelő betű, jel vagy akár szó, hiszen - mint látjuk - a BASIC kulcsszavakat is egy számmal kódolja saját maga számára a gép. A nagybetűk kódjait a 65-30, a kisbetűkét a 97-122 számok adják. A 144-164 számok is a nagybetűknek felelnek meg; ezek valójában a grafikus (G) üzemmód betűi, amelyeknek mintázatát egy megfelelő program segítségével meg lehet változtatni. Ezzel lényegében 21 darab tetszőleges formájú karaktert készíthetünk - és természetesen használhatunk - ugyanúgy, mint a most meglevőket. Ezeket gyakran udg karaktereknek nevezik. Az udg a "user defined graphics" (magyarul: a felhasználó által megadott rajzolat; kiejtése: júzer
difájnd grefiksz) szavak kezdőbetűiből összerakott szó.
A későbbiekben majd mi is készítünk magunknak saját karaktereket (nem lesz nehéz!). Most azonban térjünk vissza rajzolóprogramunkhoz! Az 1000-1020 sorokat törölhetjük. A fentiekből következően elég megvizsgálnunk, hogy a b$ változóban levő betű kódja 64-nél nagyobb-e ÉS 91-nél kisebb-e. Ugyanez BASIC-ben:

385 IF CODE b$>64 AND CODE b$<91 THEN LET ov=1

Nem túl nagy logikai bravúr rájönni, hogy az AND jelentése: ÉS. Az OR-hoz hasonlóan ez is azonos az angolban és a BASIC-ben, Kiejtése: end. Az AND-del összekapcsolt feltételek mindegyikének teljesülnie kell ahhoz, hogy a program a THEN után álló utasítást hajtsa végre.
Az AND-et (ÉS) és az OR-t (VAGY) logikai műveleteknek nevezzük (az összeadás, kivonás, osztás és szorzás neve aritmetikai művelet). Az AND és az OR művelet alaposabb megértetésére két apró példát hozunk fel.

Az első esetben elég az egyik feltételnek igaznak lennie. Ha mindkettő teljesül, az nem baj. A második példában bármelyik feltétel nem teljesül ez már elég ahhoz, hogy ne tudjuk megnézni a filmet.

Gondoskodnunk kell még az OVER visszaállításáról is, ha kisbetűt nyomtunk meg.

386 IF CODE b$>96 AND CODE b$<123 THEN LET ov=0

Ha mindig látni akarjuk, hogy milyen irány érvényes, akkor írassuk ki a képernyő bal felső sarkába az éppen lenyomott betű jelét!

303 PRINT AT 0,0;b$

Ha egy mar megkezdett rajzot magára hagyunk, akkor az éppen meglevő értékekkel a rajzolás folytatódik. Iktassuk be a megállítás lehetőségét! Ez legyen az 'f' billentyű!

380 IF b$="f" OR b$="F" THEN LET ev=0: ef=0

Ha lenyomjuk az f-et, mindig az utolsó ábra kirajzolása ismétlődik.
Vegyük fel a programot KB33 néven!

1 REM kb33
4 GO SUB 420
5 GO SUB 250
10 FOR i=1 TO p STEP 1
20 GO SUB 200
30 LET x=x+tv
35 NEXT i
40 FOR i=1 TO p STEP 1
50 GO SUB 200
60 LET y=y-tf
65 NEXT i
70 FOR i=1 TO p STEP 1
80 GO SUB 200
90 LET x=x-tv
95 NEXT i
100 FOR i=1 TO p STEP 1
110 GO SUB 200
115 LET y=y+tf
120 NEXT i
122 GO SUB 300
125 LET x=x+ev
127 LET y=y+ef
130 LET hv=p*tv+1: REM vizszintes oldalhossz
132 LET hf=p*tf+1: REM fuggoleges oldalhossz
135 IF x<0 THEN LET ev=-ev:LET x=x+ev
140 IF x>256-hv THEN LET ev=-ev: LET x=x+ev
145 IF y<hf-1 THEN LET ef=-ef: LET y=y+ef
150 IF y>175 THEN LET ef=-ef:LET y=y+ef
160 GO TO 10
200 REM 200-210 rajzolas
201 PLOT PAPER pp; INK ti; OVER ov;x,y
210 RETURN
250 REM a valtozok kezdeti ertekenek bealitasa veletlen szamokkal
252 LET pp=INT (RND*8)
254 LET ti=INT (RND*8)
256 LET x=INT (RND*111)+70
258 LET y=INT (RND*41)+70
260 LET ev=INT (RND*21)-10
262 LET ef=INT (RND*21)-10
264 LET p=INT (RND*11)+2
266 LET tv=INT (RND*5)+1
268 LET tf=INT (RND*5)+1
269 LET ov=1
270 RETURN
300 REM billentyu figyeles
302 LET b$=INKEY$
303 PRINT AT 0,0;b$
305 IF b$="t" OR b$="T" THEN LET ev=0:LET ef=1
310 IF b$="y" OR b$="Y" THEN LET ev=1:LET ef=1
320 IF b$="h" OR b$="H" THEN LET ev=1:LET ef=0
330 IF b$="b" OR b$="B" THEN LET ev=1:LET ef=-1
340 IF b$="v" OR b$="V" THEN LET ev=0:LET ef=-1
350 IF b$="c" OR b$="C" THEN LET ev=-1:LET ef=-1
360 IF b$="d" OR b$="D" THEN LET ev=-1:LET ef=0
370 IF b$="r" OR b$="R" THEN LET ev=-1:LET ef=1
380 IF b$="f" OR b$="F" THEN LET ev=0:LET ef=0
385 IF CODE b$>64 AND CODE b$<91 THEN LET ov=0
386 IF CODE b$>96 AND CODE b$<123 THEN LET ov=1
390 RETURN
420 REM 420-439 valtozok kezdeti ertekenek beallitasa
422 LET pp=7: LET ti=0: REM papir es tintaszin
423 LET x=69: REM kezdeti hely
424 LET y=78: REM kezdeti hely
425 LET ev=-5: REM vizszintes elmozdulas
426 LET ef=2: REM fuggoleges elmozdulas
427 LET p=9: REM pontok szama
428 LET tv=2: REM pontok tavolsaga vizszintesen
429 LET tf=3: REM pontok tavolsaga fuggolegesen
439 RETURN

FELADATOK:

  1. Szüntessük meg a rajzoló program önállóságát, azaz ne ismételje az ábrák rajzolását, hanem mindig várakozzon a következő billentyű lenyomásáig!

  2. Tegyük lehetővé a színváltoztatást a program futása közben is!

  3. Készítsünk olyan véletlenszám-generátort, amely a következő számokból válogat:
    -5, 0, 5, 17, 197

4. nap - Fiókba tett dobozok (avagy tömbösített változók)

Kezdjük kivételesen az utolsó feladat megoldásával!

3. Sajnos a kívánt számok között semmilyen összefüggés nincs, így valami újat kell kitalálnunk. A sorszámozás most is hasznos lesz:

1. -5
2. 0
3. 5
4. 17
5. 197

Az 1 és 5 közötti számokat könnyen elő tudjuk állítani, de hogyan lesz 1-ből -5, a 2-ből 0 stb? Jobb híján elintézhetjük egy-egy IF utasítással:

10 LET i=INT(RND*5)+1
20 IF i=1 THEN LET vsz=-5
30 IF i=2 THEN LET vsz=0
40 IF i=3 THEN LET vsz=5
50 IF i=4 THEN LET vsz=17
60 IF i=5 THEN LET vsz=197
70 PRINT vsz

A vsz változóba valóban belekerül a kívánt számok közül valamelyik, de képzeljük el, hogy mi lenne, ha 100 számból állna a kívánságlista! Ugyanennyi IF utasításra lenne szükség. Hát ez így nem igazán jó. Kellene egy olyan tároló, amelybe BELETEHETJÜK AZ ÖSSZES KÍVÁNT SZÁMOT, s ebből bármelyiket egy utasítással elővehetjük. Hogy éppen melyiket vesszük elő, azt a véletlen segítségével előállított sorszám adja meg. Most jön a már-már szokásos fordulat: létezik olyan BASIC utasítás, amely éppen erre szolgál!
A változókat az egyszerűbb megértés kedvéért dobozoznak tekintettük. Most egy kicsit tovább kell bonyolítanunk a hasonlatot. Képzeljük el, hogy veszünk 5 dobozt, és ezeket betesszük egy névvel ellátott fiókba. Ha ki akarunk venni valamit a fiókból, akkor azt mondjuk: kérem a k nevű fiók 3. dobozában lévő számot! A fiókot szaknyelven tömbnek nevezzük. Bekapcsolás után a gép magától nem hoz létre tömböt, ezért ha ilyet akarunk, azt külön utasítással kell megadnunk.
Hozzuk alapállapotba a gépet!

10 DIM k(5)

Ezzel létrehoztunk egy számok tárolására alkalmas tömböt (fiókot), amely 5 változót (dobozt) tartalmaz. Ilyenkor még 0-t találunk mindegyik változóban.
A DIM a dimension (méret, dimenzió) angol szó rövidítése (ejtése: dájmensn); elérése K módban a D lenyomása.
A közönséges változókhoz hasonlóan léteznek olyan tömbök is, amelyekben szöveget tárolhatunk, de erről majd később.
Győződjünk meg arról, hogy tényleg 0 van-e fiókunk dobozaiban:

PRINT k(1)

Ezzel azt is megmutattuk, hogyan lehet elővenni egy tömb adott elemét: a név után zárójelbe tesszük a kívánt számot. A név csak egy betűből állhat, így összesen 26 tömbünk lehet, de ne féljünk, sokáig elég lesz . A gép nem fogja összekeverni a k tömb változót a közönséges k vagy k1, k2 változókkal; éppen amiatt, hogy a kívánt elemszámot zárójelek közé tettük. Emlékszünk, hogy a közönséges változók neveit betűkből és számokból rakhatjuk össze, így véletlenül sem lehet mondjuk k(2) nevű közönséges változó. A DIM utasításban a zárójelbe tett számot, azaz a tömb méretét csak a szabad memóriaterület korlátozza; hogy pontosan mikor mennyi áll rendelkezésre, az például attól is függ, hogy maga a programunk milyen hosszú.
Ellenőrizzük a tömb többi elemét:

PRINT k(2)
PRINT k(3)

stb.

Ha nem létező elemszámot (idegen szóval indexszámot) adunk meg, a következő hibaüzenetet kapjuk (például 6-os elem jelen esetben már nincs):

PRINT k(6)
3 Subscript wrong

szó szerint: az index rossz (ejtése: szabszkript rong).
He negatív számot, 0-t, vagy 65535-nél nagyobbat írunk be, akkor a már ismert

B integer out of range

hibaüzenet olvasható.
Eleget láttuk már a nullákat, adjunk értékeket a tömb különböző elemeinek, ez ugyanúgy történhet, mint a közönséges változóknál.

20 LET k(1)=-5
30 LET k(2)=0
40 LET k(3)=5
50 LET k(4)=17
60 LET k(5)=197

Ellenőrizzük is:

70 PRINT k(1)
80 PRINT k(2)
90 PRINT k(3)
100 PRINT k(4)
110 PRINT k(5)

Használhatjuk LET helyett az INPUT-ot is, ilyenkor a program futása közben, egyesével adhatjuk meg tömbünk elemeinek értékét:

20 INPUT k(1)
30 INPUT k(2)
40 INPUT k(3)
50 INPUT k(4)
60 INPUT k(5)

A 20 és 60 közötti sorokban levő utasítások az indexszám (zárójelben levő szám) kivételével azonosak, ugyanez a helyzet a 70 és 110 közöttiek esetében is. Ilyenkor megtakaríthatunk néhány programsort, ha ciklusba foglaljuk az egyforma utasításokat. Mivel 5 INPUT illetve PRINT utasításról van szó, ezért így kezdhetjük:

20 FOR i=1 TO 5 STEP 1

Maga a ciklusváltozó fogja mutatni, hogy éppen melyik tömbelemnél tartunk.

30 INPUT k(i)
40 NEXT i

Amikor először találkoztunk a ciklusokkal, jeleztük: egyszer jól jón még, hogy a ciklusszámlálásra egy külön változót használunk. Hasonló módon írjuk át a PRINT-eket is! Töröljük az 50-es sort!

60 FOR i=1 TO 5 STEP 1
70 PRINT k(i)
80 NEXT i

A 90-es, 100-as és a110-es sort szintén kidobhatjuk: eljárt fölöttük az idő. A két ciklus egymástól független, az első befejeződik, mielőtt a második elkezdődne, ezért nyugodtan használhatjuk ugyanazt a nevű ciklusváltozót.
Ez így rendben is lenne, de mint tudjuk, az INPUT-tal csak akkor érdemes értéket adni a változóknak, ha minden futás alkalmával eltérő számokat akarunk megadni. Ha a 30-as helyére a

30 LET k(i)=-5

sort írjuk, akkor a tömb összes eleme -5-tel lesz egyenlő. De ne keseredjünk el, itt is van kiút: ehhez az kell, hogy a programunk tudjon olvasni. Márpedig tud, csak eddig nem kértük rá. Persze könyvet, újságot, ilyesmit nem, csupán ADATOKAT TUD OLVASNI, de ez nekünk éppen elég lesz.
Fix adatainkat egy úgynevezett DATA sorba írhatjuk. Micsoda véletlen: a szó jelentése adat (angolos kiejtése déta, de nyugodtan mondhatjuk magyarosan datának, a legnagyobb programozók közül is sokan így ejtik).

90 DATA -5,0,5,17,197

A DATA elérése: E módban D.
A DATA utasítást önmagában nem értelmezi a gép, átfut rajta, mintha ott sem lenne. De létezik egy külön utasítás: a READ (magyarul: olvass, kiejtése ríd), amely képes kiolvasni a DATA-ból az adatokat. Már csak az a kérdés, hogy melyiket olvassa ki, s hova kerül, amit kiolvasott.

30 READ k(i)

Haladjunk visszafelé a kérdések megválaszolásával. A kiolvasott adat a READ után álló változóba kerül, jelen esetben a k nevű tömb i-edik vá1tozójába. Az i értéke attól függ, hányadszor hajtja végre a ciklust a gép: az első ráfutáskor 1, az utolsónál 5.
A kérdés első felének megválaszolásához futtassuk le a programot!

-5
0
5
17
197

Látjuk, a gép a beolvasást a DATA sor elején kezdte, és szépen egymás után vette elő az értékeket. Vegyük rá a gépet egy újabb olvasásra,

READ k(1)

Az eredmény egy hibaüzenet:

E Out of Data

Magyarul elfogytak az adatok (ejtsd: aut of déta). Ez nem csoda, hiszen már az összes adatot beolvastuk a K tömbbe.
Futtassuk le újra a programot!

Ismét rendben van minden, tehát a RUN hatására a gép visszaállt a DATA első számához úgy képzelhetjük a dolgot, hogy a gép a futás kezdetén sorba rakja az adatokat, ezen kívül az első adathoz odatesz egy mutatót, amolyan könyvjelzőt, jelezve, hogy innen kell olvasni, ha READ utasítással találkozik. Ez a könyvjelző sehol sem látható, csak a gép memóriájában van jelen, ezért nem is kell tovább foglalkoznunk vele. Még annyit sem mondunk meg róla, hogy angolul pointernek nevezik, mint azt a bizonyos fekete foltos, fehér vadászkutyát.
Egy adat beolvasása után a könyvjelző eggyel odább kerül.
Most adjuk ki a

GO TO 20

parancsot, hiszen ezzel is újraindítjuk a kiolvasási ciklust. A megszokott számok helyett újra a hibaüzenet díszeleg a képernyő alján:

E Out of DATA 30:1

A gép azt mondja, hogy a 30-as sorban olvasni akart, de nem volt adata. A GO TO 20 nem állította vissza az adatmutatót az első adathoz.
Írjunk be újabb 5 adatot, ezt tegyük a 100-as sorba:

100 DATA 8,12,22,37,51
RUN

-5
0
5
17
197

Az új adatok nem kerültek sorra, de ha GO TO 20-szal újraindítjuk az olvasást, ez is megtörténik.
Nem meglepő, hogy az adatok sorbarakása a DATA-K sorszáma szerint történt. A könyvjelzőt azonban nemcsak a gép állíthatja be: mi is megtehetjük ezt a RESTORE utasítással - jelentése visszaállít, restaurál (ejtsd: risztőr), elérhető E módban az S lenyomásával.

15 RESTORE 100
RUN

8
12
22
37
51

Tényleg a 100-ban levő adatok kerültek a k tömbbe.
Egy újabb GO TO 20-szal meggyőződhetünk arról, hogy a gép az adatsor végére ért, annak ellenére, hogy a 90-ben levő adatok nem kerültek sorra. Igazolva ezzel azt, hogy a RESTORE 100 nem rendezi át az adatokat, csak a mutatót rakja a 100-as sor első adatához.
Még egyszer hangsúlyozzuk: a DATA-k bárhol lehetnek a programban, sorszámaik csak az adatok sorbarendezését határozzák meg. A READ utasítással nemcsak számokat olvastathatunk a DATA-ban, hanem mást is - de ezzel majd később foglalkozunk.
Mint láttuk, a program GO TO és RUN paranccsal egyaránt elindítható. Az utóbbi letörli a képernyőt, törli az összes változót, és a könyvjelzőt visszateszi a legelső DATA-hoz.
Végre visszatérhetünk a kitűzött feladathoz:

10 DIM k(5)
20 FOR i=1 TO 5 STEP 1
30 READ k(i)
40 NEXT i
45 LET v=INT(RND*5)+1)
50 PRINT v,k(v)
90 DATA -5,0,5,17,197

A 20-40-es sorokban feltöltjük a K tömböt az előre megadott 5 számmal, a 45-ben előállítunk egy 1 és 5 közé eső véletlen számot, és betesszük a v változóba. Az 50-ben kiírjuk a v-t, valamint a tömb v-edik elemét.

Folytassuk az 1. feladat megoldásával!
Töltsük be a rajzolóprogram KB33 néven felvett változatát!
A program önállóságán azt értettük, hogy ha a megkezdett rajzot magára hagyjuk, akkor az éppen meglevő ev és ef értékeknek megfelelően a rajzolás tovább folytatódik. Ezt egyszerűen megszüntethetjük két módon is.

304 LET ev=0: LET ef=0

Így ha a 305-370 sorok feltételeinek egyike sem teljesül, akkor az ev=0, ef=0 értékek érvényesek, tehát a rajzolat nem megy odább.
A másik módszer:

382 IF b$="" THEN GO TO 302

Mindaddig, amíg a b$-ben egy üres karakter van, visszatérünk a billentyűbeolvasáshoz, így a szubrutin végrehajtása csak akkor ér véget, ha valamelyik billentyűt lenyomjuk. Így ha nem a kiválasztott billentyűk egyikét nyomtuk le, hanem bármely másikat, akkor a rajzolás a régi értékekkel folytatódik.

A 2. feladat megoldására is több módszer kínálkozik.
Minden színt más billentyűvel kapcsolhatnánk be. Ez azonban nagyon elnyújtana a billentyűfigyelő szubrutint. Célszerűbb, ha egy billentyű lenyomására (legyen az a p) "kiugrunk" színt váltani.

388 IF b$="p" THEN GO SUB 400
390 RETURN
400 REM 400-410 szinvalasztas
405 INPUT "Papirszin:";pp
408 INPUT "Tintaszin:";ti
410 RETURN

Ha a P-t nyomjuk le, akkor teljesül a 388-ban írt feltétel, s a folytatás a 400-as szubrutin lesz. Ennek befejezésekor a program visszatér a 388-os utáni sorra, a 390-re, ami "véletlenül" szintén RETURN, ezért ezután a 125. sor következik.
Most kivételesen jó lett volna a

388 IF b$="p" THEN GO TO 400

is, mert úgy a 410-es sor RETURN-je hatásara kerültünk volna vissza a 125. sorra. Természetesen ilyen GO SUB - GO TO cserét kizárólag akkor csinálhatunk, ha a következő sor RETURN, így egy picit gyorsabban fut le a program. Most ez az időnyerés nem érzékelhető, de lehetséges olyan eset, amikor számottevően rövidül egy ilyen módosítástól a program futási ideje.
Jó lenne, ha nemcsak a rajzolás végeredményét lehetne rögzíteni, hanem a kiindulási értékeket is. Különösen akkor számíthat ez, amikor a véletlen állítja be a kezdeti értékeket. Összesen 10 olyan változónk van, melyeknek értékei befolyásolják a rajzot. Ezek a

pp, ti, x, y, ev, ef, p, tv, tf, ov

Ezeket célszerű egy tömbben tárolni. Láttuk, hogy a tömb elemei viszonylag egyszerűen elővehetők. Ráadásul lehetőség van rá, hogy a már értékekkel feltöltött tömböt - akárcsak magát a programot - magnókazettán rögzítsük. Ezt egy más alkalommal beolvasva a magnóról máris visszaállítottunk egy korábbi kezdeti állapotot.
Ehhez sajnos sokat kell módosítanunk a programon: át kell írni a 252-268 és a 422-430 sorokat és emellett létre kell hozni a K tömböt.

1 REM kb41
2 DIM k(10)
4 GO SUB 420
5 GO SUB 250
10 FOR i=1 TO p STEP 1
20 GO SUB 200
30 LET x=x+tv
35 NEXT i
40 FOR i=1 TO p STEP 1
50 GO SUB 200
60 LET y=y-tf
65 NEXT i
70 FOR i=1 TO p STEP 1
80 GO SUB 200
90 LET x=x-tv
95 NEXT i
100 FOR i=1 TO p STEP 1
110 GO SUB 200
115 LET y=y+tf
120 NEXT i
122 GO SUB 300
125 LET x=x+ev
127 LET y=y+ef
130 LET hv=p*tv+1: REM vizszintes oldalhossz
132 LET hf=p*tf+1: REM fuggoleges oldalhossz
135 IF x<0 THEN LET ev=-ev:LET x=x+ev
140 IF x>256-hv THEN LET ev=-ev: LET x=x+ev
145 IF y<hf-1 THEN LET ef=-ef: LET y=y+ef
150 IF y>175 THEN LET ef=-ef:LET y=y+ef
160 GO TO 10
200 REM 200-210 rajzolas
201 PLOT PAPER pp; INK ti; OVER ov;x,y
210 RETURN
250 REM a valtozok kezdeti ertekenek bealitasa veletlen szamokkal
252 LET pp=INT (RND*8): LET k(1)=pp
254 LET ti=INT (RND*8): LET k(2)=ti
256 LET x=INT (RND*111)+70: LET k(3)=x
258 LET y=INT (RND*41)+70: LET k(4)=y
260 LET ev=INT (RND*21)-10: LET k(5)=ev
262 LET ef=INT (RND*21)-10: LET k(6)=ef
264 LET p=INT (RND*11)+2: LET k(7)=p
266 LET tv=INT (RND*5)+1: LET k(8)=tv
268 LET tf=INT (RND*5)+1: LET k(9)=tf
270 RETURN
300 REM billentyu figyeles
302 LET b$=INKEY$
303 PRINT AT 0,0;b$
305 IF b$="t" OR b$="T" THEN LET ev=0:LET ef=1
310 IF b$="y" OR b$="Y" THEN LET ev=1:LET ef=1
320 IF b$="h" OR b$="H" THEN LET ev=1:LET ef=0
330 IF b$="b" OR b$="B" THEN LET ev=1:LET ef=-1
340 IF b$="v" OR b$="V" THEN LET ev=0:LET ef=-1
350 IF b$="c" OR b$="C" THEN LET ev=-1:LET ef=-1
360 IF b$="d" OR b$="D" THEN LET ev=-1:LET ef=0
370 IF b$="r" OR b$="R" THEN LET ev=-1:LET ef=1
380 IF b$="f" OR b$="F" THEN LET ev=0:LET ef=0
382 IF b$="" THEN GO TO 302
385 IF CODE b$>64 AND CODE b$<91 THEN LET ov=0
386 IF CODE b$>96 AND CODE b$<123 THEN LET ov=1
387 IF b$="p" THEN GO SUB 400
390 RETURN
400 REM 400-410 szinvalasztas
405 INPUT "papir szin? ";pp
408 INPUT "tinta szin? ";ti
410 RETURN
420 REM 420-439 valtozok kezdeti ertekenek beallitasa
421 LET pp=7: LET k(1)=pp: REM papir szin
422 LET ti=0: LET k(2)=ti: REM tintaszin
423 LET x=69: LET k(3)=x: REM kezdeti hely
424 LET y=78: LET k(4)=y: REM kezdeti hely
425 LET ev=-5: LET k(5)=ev: REM vizszintes elmozdulas
426 LET ef=2: LET k(6)=ef: REM fuggoleges elmozdulas
427 LET p=13: LET k(7)=p: REM pontok szama
428 LET tv=2: LET k(8)=tv: REM pontok tavolsaga vizszintesen
429 LET tf=3: LET k(9)=tf: REM pontok tavolsaga fuggolegesen
430 LET ov=1: LET k(10)=ov: REM OVER1 vagy OVER 0
439 RETURN

Vegyük fel a programot KB41 néven!
Rajzoljunk néhány ábrát, s a leginkább tetszőnél mentsük ki a K tömböt! Ennek módja a következő:

SAVE "KEZDOADAT" DATA k()

A KEZDOADAT a szalagon levő adatblokk neve, ilyen névvel kell majd betölteni is; a DATA szó itt arról értesíti a gépet, hogy adatokat, nem programot mentünk ki. A K a tömb neve, a két zárójel feltehetően arra utal, hogy tömböt viszünk ki. Ennél részletesebb felvilágosítást csak azok adhatnának, akik a SFECTRUM BASIC-jét megalkották. Azért e tanácstalanság, mert csak a tömbök vihetők ki szalagra, a közönséges változók nem lehet a külön zárójeleknek látszólag nincs különösebb értelmük.
A már kimentett adatokat szokás szerint ellenőrizzük is:

VERIFY "KEZDOADAT" DATA k()

A betöltést mindig magával a programmal kezdjük, s csak ezután hozzuk be az adatokat! (Fordítva nem megy.) A kimentett adat-tömb használatához azonban még szükséges egy-két módosítás elvégzése.

FELADATOK:

1/a. Gondoskodjunk arról, hogy a futtatás előtt betöltött K adattömb értékei átkerüljenek a megfelelő változókba (pp, ti, stb.)!

1/b. Hogyan lehetne a billentyűlenyomások sorozatát is kimenteni magnóra?

2. Készítsünk olyan véletlenszám-előállító programot, amely elsőként előállít 7 darab 1 és 100 közé eső számot, majd ebből a készletből választ ki 20 darab hármas csoportot, s ezt kiírja a képernyőre!

5. nap - Ciklus a ciklusban

Kezdjük a 2. feladat megoldásával!
A T darab véletlen számot tároljuk a v nevű tömbben!

10 DIM v(7)
20 FOR i=1 TO 7
30 LET v(i)=INT(RND*100)+1
40 NEXT i

Nézzük meg, hogyan lehet egy hármas csoportot előállítani, és lehetőleg egy sorba kiíratni! Először próbáljunk meg egyet, ehhez kell egy 1 és 7 közé eső véletlen szám, ami megadja, hogy a v tömb melyik elemét vegyük elő.

55 KET k=INT(RND*7)+1

Írjuk a sor bal szélére a kiválasztott tömb elemeit!

60 PRINT TAB 0;v(k)

A következő kerüljön a 10-es helyre!

65 LET k=INT(RND*7)+1
70 PRINT TAB 10;v(k)

Ha kipróbáljuk, láthatjuk, hogy a két szám nem került egy sorba. A gépnek igaza van, a PRINT utasítás végén nem volt ott a pontosvessző, ezért automatikusan új sort kezdett. Tegyük oda a 60 és 70-es sorok végére a pontosvesszőt!
A harmadik szám kerüljön a 20-as pozícióba!

75 LET k=INT(RND*7)+1
80 PRINT TAB 20;v(k);

Ha már megvan 3, abból könnyen csinálhatunk 20-szor annyit, elég ha az 55-80 sorokat körbevesszük egy ciklussal.

50 FOR i=1 TO 20 STEP 1
90 NEXT i

A 80-as sor végén a pontosvesszőnek nincs hatása, ugyanis az újabb PRINT (60) a 0-s pozícióba akar írni, a 20-ból már nem lehet visszamenni ugyanannak a sornak az elejére, ezért a következő sor elején folytatódik a kiírás.
Az 55-60, a 65-70 és a 75-80 sorpárok szinte teljesen azonosak, csupán a TAB után írt számok eltérőek. Az ilyen ismétlődés, a vak is látja, ciklusért kiált! Miután az i ciklus belsejében vagyunk, az új ciklusunk változójának adjuk a j nevet. Mivel háromszori ismétlésről van szó

FOR j=1 TO 3 STEP 1

Mit Kell írnunk a TAB után?
A ciklus j=1, j=2, majd j=3 értékekkel fut, ezekhez kell hozzápárosítani a TAB 0, TAB 10, TAB 20 értékeket. Írjuk a számokat egymás mellé, ez már többször segített az összefüggések megtalálásában.

J
TAB

1
2
3

0
10
20

A gyakorlott rejtvényfejtők máris rávágják a választ; reméljük, hogy a többieknek sincs szükségük sok töprengésre. Vegyink el a j-ből egyet, és a maradékot szorozzuk tízzel, vagy előbb szorozzuk tízzel, és utána vegyünk el belőle tízet. Természetesen mindkét megoldás remek. (Jöhet a következő kérdés.)

55 FOR j=1 TO 3 STEP 1
65 LET k=INT(RND*7)+1
70 PRINT TAB (j-1)*10;v(k);
90 NEXT j

A 60 és 75 sorokat törölni kell.

Figyeljük meg, az i ciklus belsejében van a j ciklus. Szaknyelven ezt úgy mondják, hogy egymásba ágyaztuk, vagy EGYMÁSBA SKATULYÁZTUK A CIKLUSOKAT. Akár több ilyet is csinálhatunk, csupán arra kell ügyelnünk, hogy a legutoljára elkezdett ciklust kell először befejezni.

FOR i=...
...
FOR j=...
...
FOR k=...
...
NEXT k
...
NEXT j
...
NEXT i

1/a. feladat
Kezdetnek töltsük be a Kb41 néven felvett programot.
Az adattömb betöltése is lehet a programnak része, ehhez a LOAD is sorszámot kap:

3 LOAD "kezdoadat" DATA k()

Ezzel a k tömb "kezdoadat" néven kimentett adatai töltődnek be; a tömb adatainak átírását a pp, ti, . stb. változókba a 450-es szubrutin fogja elvégezni. Ennek meghívása csak a tömb betöltése után történhet:

3 LOAD "kezdoadat" DATA k(): GO SUB 450
450 REM 450-479 a felvett ertekek beirasa a valtozokba
455 LET pp=k(1)
457 LET ti=k(2)
459 LET x=k(3)
461 LET y=k(4)
463 LET ev=k(5)
465 LET ef=k(6)
467 LET p=k(7)
469 LET tv=k(8)
471 LET tf=k(9)
473 LET ov=k(10)
479 RETURN

Csakhogy hiába töltöttük fel a változókat az előre felvett értékekkel, a 4 és 5 sorban meghívott szubrutinok átírják őket. Ezeket akkor át kell ugornunk, így a 3-as sor végére be kell szúrnunk egy GO TO-t!

3 LOAD "kezdoadat" DATA k(): GO SUB 450: GO TO 10

Ha viszont nem óhajtunk a kazettán lévő adatokat használni, akkor a 3-as sort át kell ugrani.

2 DIM k(10): GO TO 4

Ez utóbbi GO TO 4 beírásával vagy törlésével tudunk választani a kétféle kezdeti érték megadási mód között. Ez így nem túl elegáns, szebb lenne, ha a program megkérdezné, hogy mit szeretnénk, és a válasznak megfelelően történne a kezdeti értékek beállítása. Mivel erre a program elején nincs elegendő hely, így legyen ez is egy szubrutin, mondjuk a 600-as sortól kezdődően.

2 DIM k(10)
4 GO SUB 600

A 3 és 5-ös sort töröljük ki!

600 REM kerdezes
605 INPUT "Akarsz kazettarol adatokat betolteni i/n";v$
610 IF v$="n" THEN GO TO 660
620 IF v$="i" THEN GO TO 630
625 GO TO 605
630 INPUT "Milyen neven vetted fel a kazettara?";n$
640 LOAD n$ DATA k()
645 GO SUB 450
650 RETURN
660 GO SUB 420
665 GO SUB 256
670 RETURN

A 605-ben igen vagy nem választ adhatunk, pontosabban a megfelelő kezdőbetűvel kell válaszolnunk, ezt jelzi az i/n jelölés. Ha nem a két betű valamelyikét írtuk be, akkor sem a 610-ben, sem a 620-ban megadott feltétel nem teljesül, így a

625 GO TO 605

visszaküld a 605-os sorba, és újra felteszi a kérdést. Ha nemmel (n) válaszoltunk akkor ugyanaz történik, mint a korábbi változatokban. Először feltöltjük a változókat állandó értékekkel (GO SUB 420), majd egy részüket átírjuk véletlen számmal (GO SUB 256). Igenlő válasz esetén a gép megkérdezi, hogy milyen néven vittük ki kazettára az adatokat. Ezután betölti a megadott néven felvett K adattömböt. Ha rossz nevet adtunk meg, magunkra vessünk. (Nem árt az sem, ha gondosan csatlakoztatjuk a magnót, ha betesszük a megfelelő kazettát, stb.)
A sikeres betöltés után a 450-es szubrutin áttölti a tömb elemeit a pp, ti,... stb. változókba, s már mehetünk is rajzolni.

Ha le is ellenőriztünk minden új részt, jöhet az 1/b. feladat.
Nyilvánvaló, hogy a billentyűlenyomásokat is tömbben kellene tárolni, részint mert könnyen elővehető bármelyik elem, másrészt így egyszerűen kimenthető magnóra.
Mivel a lenyomott billentyű egy betűvel azonosítható (ilyen szempontból számjegyek is betűnek számítanak), s átmenetileg idáig is egy karakter- (string-) változóban tároltuk (b$), kézenfekvő, hogy olyan tömböt kell majd használnunk, amely betűk tárolására alkalmas. A közönséges vá1tozókhoz hasonlóan itt is a $ jel mutatja ezt a külön tulajdonságot Tegyük fel, hogy 1000 billentyűlenyomást akarunk tárolni. Az ehhez szükséges tömböt

3 DIM t$(1000,1)

utasítással definiálhatjuk. (Definiál: meghatároz; főleg matematikai könyvekben találkozhatunk sokat ezzel a szóval.)
A zárójelben álló első szám az elemek darabszámát jelöli, a második pedig azt adja meg, hogy hány betűből állhat egy elem. A mi esetünkben az 1 éppen elegendő, ha nagyobb számot írnánk oda, azzal csak a memóriát pazarolnánk.
A tömbökkel kapcsolatos műveleteket ugyanúgy használhatjuk, pl.

LET t$(13)="c"

vagy

PRINT t$(6)

Az akadékoskodók most közbevethetik: minek szenvedünk itt egy betűk tárolására alkalmas tömbbel? Hiszen - mint tudjuk - a számítógép úgyis mindent számok formájában tárol, az adott betűhöz tartozó számot egy CODE utasítással előhívhatjuk, és akkor ezt már betehetjük a múltkor megismert, számok tárolására szolgáló, úgynevezett numerikus tömbbe. Ez igaz is, csakhogy egy szám tárolása ötször annyi memóriát igényel, mint egy betűé!
Ettől függetlenül mindenki nyugodtan kételkedjen, akadékoskodjon, s lehetőség szerint próbáljon meggyőződni feltevése helyességéről.

Gondoljuk át, hogy milyen új programrészek beépítésére lehet szükség!

  • a lenyomott billentyű tárolása
  • a tárolt billentyűértékek előhívása
  • Választás a kétféle üzemmód között (1. rajzolás, 2. visszajátszás)
  • váltás az üzemmódok között

Mint látjuk, a funkciók gyarapodásával egyszerre bonyolultabb lesz az egész program működését irányító úgynevezett vezérlőprogram. A 600-as sorban már elkezdtük egy ilyen vezérlőprogram kialakítását, az új funkciók beépítésével ezt is folytatni fogjuk, de így a 600-tól kezdődő programba nem GO SUB-bal ugrunk.

4 GO TO 600

ALAKÍTSUK SZUBRUTINNÁ az önállóan működő programrészeket!

  10-120 téglalap rajzolása
125-150 értékmódosítás és ellenőrzés

122 RETURN
160 RETURN

Így eltűnik a régi 122-es sor a billentyűfigyelő szubrutinmeghívása, de ezt később majd pótoljuk. Ezzel a két programrész szubrutinná vált.

9 REM 9-122 teglalap rajzolasa
124 REM 124-160 ertekmodositas, ellenorzes

Térjünk vissza a vezérlőprogramhoz! A 650 és 670 RETURN-je már érvényét vesztette. Írjuk be:

650 GO TO 670

Akármelyik módon állítottuk be a kezdeti értékeket, utána egy választás következik.

  • rajzolás billentyűvel
  • visszajátszás
  • befejezés (STOP)

670 INPUT "rajzolsas / visszajatszas / stop";v$

Értékelnünk kell a válaszokat:

675 IF v$="s" THEN STOP
680 IF v$="r" THEN GO TO 700
690 IF v$="v" THEN GO TO 755
695 GO TO 670

Ha nem az r, s vagy v billentyűk egyikét nyomtuk le, a program visszatér a 670-es sorba, és újra megkérdezi, hogy mit választunk.
A rajzolás és a visszajátszás többször követheti egymást, ezért időnként szükség lehet a képernyő letörlésére.

500 REM 500-540 kepernyo torles
510 INPUT "toroljunk? i/n";v$
520 IF v$="n" THEN RETURN
530 IF v$="i" THEN CLS: RETURN
540 GO TO 510

Ha a feltett kérdésre n (nem) a válasz, akkor a szubrutin véget ér anélkül, hogy bármi egyéb történne; i (igen) válasz esetén megtörténik a képernyő törlése, és csak ezután következik a RETURN.
A tárolást egyszerűen beépíthetjük a billentyűzetfigyelő szubrutinba. Szükségünk van egy változóra (legyen a neve j), amely azt mutatja, hogy a tömb hányadik elemébe írunk. Ha nem nyomtunk le egy billentyűt sem, akkor a b$="", azaz egy üres karakter van benne, ezt fölösleges lenne eltenni.
Az eredeti

303 PRINT AT 0,0;b$

Sor számát írjuk át 304-re, és a 303-ba kerüljön a tárolás - később majd hasznát látjuk ennek az apró cserének.

303 IF b$<>"" THEN LET t$(j)=b$: LET j=j+1

A j értékét növelni kell, nehogy az újabb b$ értéket a tömbnek ugyanabba az elemébe írjuk.
Ha elölről kezdjük a rajzolást, akkor a j-be 1-et kell írnunk, ha az előzőt folytatjuk, akkor a j értéke változatlan marad.

550 REM kezdes vagy folytatas
560 INPUT "Kezdesvagy folytatas? k/f";v$
570 IF v$="f" THEN RETURN
580 IF v$="k" THEN LET j=1: RETURN
590 GO TO 560

Most már minden segédprogramot elkészítettünk, folytathatjuk a rajzoló rész megírásával.
Először azt kell eldöntenünk, hogy a kezdésről vagy folytatásról van-e szó.

700 GO SUB 550

Ezután a képernyő törlésének lehetősége következik:

710 GO SUB 500

Majd sorozatban

  • egy téglalap kirajzolása
  • billentyűfigyelés
  • értékmódosítás
  • visszatérés a téglalap rajzolásához.

715 GO SUB 9
720 GO SUB 300
740 GO SUB 124
750 GO TO 715

A rajzolás így vég nélkül folytatódna, csak a BREAK paranccsal lehetne leállítani. Iktassunk be egy sort, ami figyeli mondjuk a q billentyűt, s ha úgy találta, hogy lenyomtuk, akkor térjen vissza a program a rajzolás-visszajátszás választáshoz!

730 IF b$="q" THEN GO TO 670

A b$ változóba már a 300-as szubrutin beletette a lenyomott billentyű betűjelét.

Nézzük a visszajátszást!
Kezdődjön ez is egy képernyőtörlés választásával!

755 GO SUB 500

Indítsuk a visszajátszást az elejétől!

758 LET j=1

Jöhet egy téglalap kirajzolása!

760 GO SUB 9

Billentyű beolvasás helyett a t$ tömb soron levő elemét (a j változó mutatja, hogy melyik a soron levő) átírjuk a b$-ba.

770 LET b$=t$(j)

Ezután a 300-as szubrutinból kikerüljük magát a billentyűbeolvasást és a tárolást (302, 303), csak a kiírást és az ellenőrzést hívjuk meg.

780 GO SUB 304

Ha a q betűt találtuk a tömbben, akkor ez volt az utolsó eltett érték, így vége a visszajátszásnak, vissza kell térni a választáshoz:

790 IF b$="q" THEN GO TO 670

Ellenkező esetben a folytatáshoz megnöveljük eggyel a j-t, hogy a tömb következő elemét írhassuk át a b$-ba.

800 LET j=j+1

Még kell egy értékmódosítás:

805 GO SUB 124

és visszatérhetünk az újabb téglalap rajzolásához:

810 GO TO 760

Még egy apróság: Tegyük be a t$ tömb első elemébe a "q" értéket, biztosítva ezzel azt, hogy csak akkor lehessen visszajátszani, ha már tároltunk adatokat.

3 DIM t$(1000,1): LET t$(1)="q"

Bizony, tekintélyes méretűre nőtt már a programunk. Vegyük fel Kb52 néven!

1 REM kb52
2 DIM k(10)
3 DIM t$(1000,1): LET t$(1)="q"
4 GO TO 600
9 REM 9-122 teglalap rajzolas
10 FOR i=1 TO p STEP 1
20 GO SUB 200
30 LET x=x+tv
35 NEXT i
40 FOR i=1 TO p STEP 1
50 GO SUB 200
60 LET y=y-tf
65 NEXT i
70 FOR i=1 TO p STEP 1
80 GO SUB 200
90 LET x=x-tv
95 NEXT i
100 FOR i=1 TO p STEP 1
110 GO SUB 200
115 LET y=y+tf
120 NEXT i
122 RETURN
124 REM 124-160 ertekmodositas ellenorzes
125 LET x=x+ev
127 LET y=y+ef
130 LET hv=p*tv+1: REM vizszintes oldalhossz
132 LET hf=p*tf+1: REM fuggoleges oldalhossz
135 IF x<0 THEN LET ev=-ev:LET x=x+ev
140 IF x>256-hv THEN LET ev=-ev: LET x=x+ev
145 IF y<hf-1 THEN LET ef=-ef: LET y=y+ef
150 IF y>175 THEN LET ef=-ef:LET y=y+ef
160 RETURN
200 REM 200-210 rajzolas
201 PLOT PAPER pp; INK ti; OVER ov;x,y
210 RETURN
250 REM 250-270 valtozok kezdeti ertekenek bealitasa veletlen szamokkal
252 LET pp=INT (RND*8): LET k(1)=pp
254 LET ti=INT (RND*8): LET k(2)=ti
256 LET x=INT (RND*111)+70: LET k(3)=x
258 LET y=INT (RND*41)+70: LET k(4)=y
260 LET ev=INT (RND*21)-10: LET k(5)=ev
262 LET ef=INT (RND*21)-10: LET k(6)=ef
264 LET p=INT (RND*11)+2: LET k(7)=p
266 LET tv=INT (RND*5)+1: LET k(8)=tv
268 LET tf=INT (RND*5)+1: LET k(9)=tf
270 RETURN
300 REM billentyu figyeles
302 LET b$=INKEY$
303 IF b$<>"" THEN LET t$(j)=b$: LET j=j+1
304 PRINT AT 0,0;b$
305 IF b$="t" OR b$="T" THEN LET ev=0:LET ef=1
310 IF b$="y" OR b$="Y" THEN LET ev=1:LET ef=1
320 IF b$="h" OR b$="H" THEN LET ev=1:LET ef=0
330 IF b$="b" OR b$="B" THEN LET ev=1:LET ef=-1
340 IF b$="v" OR b$="V" THEN LET ev=0:LET ef=-1
350 IF b$="c" OR b$="C" THEN LET ev=-1:LET ef=-1
360 IF b$="d" OR b$="D" THEN LET ev=-1:LET ef=0
370 IF b$="r" OR b$="R" THEN LET ev=-1:LET ef=1
380 IF b$="f" OR b$="F" THEN LET ev=0:LET ef=0
382 IF b$="" THEN GO TO 302
385 IF CODE b$>64 AND CODE b$<91 THEN LET ov=0
386 IF CODE b$>96 AND CODE b$<123 THEN LET ov=1
387 IF b$="p" THEN GO SUB 400
390 RETURN
400 REM 400-410 szinvalasztas
405 INPUT "papir szin? ";pp
408 INPUT "tinta szin? ";ti
410 RETURN
420 REM 420-439 valtozok kezdeti ertekenek beallitasa
421 LET pp=7: LET k(1)=pp: REM papir szin
422 LET ti=0: LET k(2)=ti: REM tintaszin
423 LET x=69: LET k(3)=x: REM kezdeti hely
424 LET y=78: LET k(4)=y: REM kezdeti hely
425 LET ev=-5: LET k(5)=ev: REM vizszintes elmozdulas
426 LET ef=2: LET k(6)=ef: REM fuggoleges elmozdulas
427 LET p=13: LET k(7)=p: REM pontok szama
428 LET tv=2: LET k(8)=tv: REM pontok tavolsaga vizszintesen
429 LET tf=3: LET k(9)=tf: REM pontok tavolsaga fuggolegesen
430 LET ov=1: LET k(10)=ov: REM OVER1 vagy OVER 0
439 RETURN
450 REM 450-479 a felvett ertekek beirasa a valtozokba
455 LET pp=k(1)
457 LET ti=k(2)
459 LET x=k(3)
461 LET y=k(4)
463 LET ev=k(5)
465 LET ef=k(6)
467 LET p=k(7)
469 LET tv=k(8)
471 LET tf=k(9)
473 LET ov=k(10)
479 RETURN
500 REM 500-540 kepernyo torles
510 INPUT "toroljunk? i/n";v$
520 IF v$="n" THEN RETURN
530 IF v$="i" THEN CLS: RETURN
540 GO TO 510
550 REM kezdes vagy folytatas
560 INPUT "Kezdesvagy folytatas? k/f";v$
570 IF v$="f" THEN RETURN
580 IF v$="k" THEN LET j=1: RETURN
590 GO TO 560
600 REM 600-670 kerdezes
605 INPUT "Akarsz kazettarol adatokat betolteni i/n";v$
610 IF v$="n" THEN GO TO 660
620 IF v$="i" THEN GO TO 630
625 GO TO 605
630 INPUT "Milyen neven vetted fel a kazettara?";n$
640 LOAD n$ DATA k()
645 GO SUB 450
650 GO TO 670
660 GO SUB 420
665 GO SUB 256
670 INPUT "rajzolsas / visszajatszas / stop (r/v/s)";v$
675 IF v$="s" THEN STOP
680 IF v$="r" THEN GO TO 700
690 IF v$="v" THEN GO TO 755
695 GO TO 670
700 GO SUB 550
710 GO SUB 500
715 GO SUB 9
720 GO SUB 300
730 IF b$="q" THEN GO TO 670
740 GO SUB 124
750 GO TO 715
755 GO SUB 500
757 GO SUB 450
758 LET j=1
760 GO SUB 9
770 LET b$=t$(j)
780 GO SUB 304
790 IF b$="q" THEN GO TO 670
800 LET j=j+1
805 GO SUB 124
810 GO TO 760

FELADATOK:

  1. Tegyük bele a Kb52 programba annak a lehetőségét, hogy ne csak a legelejéről lehessen kezdeni a visszajátszást!

  2. Hogyan lehetne megoldania Kb52-ben, hogy a visszajátszott rajz ne az eredeti helyére kerüljön?

6. nap - Kör, egyenes, körív

A megoldásokhoz töltsük be a Kb52 programot!

1. A visszajátszás a 755. sorban kezdőik, a 758. sorban a j értékét kell átírni, és máris kész vagyunk.

758 INPUT "Hol kezdjuk a visszajatszast?";j

Akadályozzuk meg, hogy túl nagy értéket lehessen megadni. Ehhez nyilván kell tartania a programnak, hogy hány "lépést" tett a rajzolás, azaz hány értéket tettünk be a t$ tömbbe. A rajzolás végén az y értékét át kell írni egy változóba, legyen ez lsz:

730 IF b$"q" THEN LET lsz=j: GO TO 670

így már ellenőrizhetjük a 758-ban beadott j értékét:

719 IF y>=lsz THEN GO TO 758

2. A visszajátszás kezdetén a program megkérdezheti a felhasználót, hogy hova kéri a rajzot:

756 INPUT "uj rajz helye? x koord";x
757 INPUT "uj rajz helye? y koord";y

Természetesen elfordulhat, hogy a megadott x,y értékekkel nem kapják vissza az eredeti ábrát, de ezzel most ne törődjünk.

Sokféle rajzot készítettünk már, de még messze nem használtuk ki a SPECTRUM ezirányú képességét. Gépünk ugyanis tud KÖRT, KÖRÍVET ÉS EGYENEST RAJZOLNI. Kezdjük az elsővel!

A körrajzoló utasítás a CIRCLE (angolul is kört jelent, ejtése szörkl). Elérése: E módban a SYMBOL SHIFT + H.
Mit kell tudnunk ahhoz, hogy pontosan megrajzoljunk egy kört? Nyilván a középpont helyét, ahova a körző hegyét szúrjuk, és a sugarát, ami megmondja, mekkorára nyissuk a körző szárát. Mint tudjuk, egy pont megadásához 2 szám kell. Ezért a CIRCLE-t követően 3 számot kell beírnunk, vesszővel elválasztva őket egymástól. Az első kettő a kör középpontjának X és Y koordinátája, a harmadik a kör sugara.
Rajzoljunk a képernyő közepére egy céltáblát!

1000 FOR i=1 TO 30 STEP 2
1010 CIRCLE 127,87,i
1020 NEXT i

A PLOT-hoz hasonlóan a CIRCLE-t is felszerelhetjük a PAPER, INK, OVER, INVERSE, FLASH, BRIGHT kiegészítésekkel. Szúrjuk be az 1010-be az OVER 1-et!

1010 CIRCLE OVER 1;127,87,i
1030 GO TO 1000

Az elfogadott értékek; a kör

A sugár negatív értékét a gép elfogadja ugyan, de nem veszi figyelembe. A

CIRCLE 100,120,10

és

CIRCLE 100,120,-10

ugyanazt a kört rajzolja.
Ha az adott tartományokon belüli értékeket adunk meg, akkor a kör kirajzolása elindul, de abban az esetben természetesen megáll a folyamat, ha a körív kilógna a képből. Ebből is látható, hogy a gép a kör kirajzolását visszavezeti pontok megjelenítésére. A hibaüzenet a mar megszokott

B Integer out of range

Alakítsuk át rajzolóprogramunkat úgy, hogy a téglalapok helyett köröket rajzoljon! Gondoljuk végig, milyen változtatásokra lesz szükség!

   
szubrutin
1. téglalap helyett kör rajzolása
9
2. kezdeti értékék beállítása állandó számokkal
420
3. kezdeti értékek beállítása véletlen számokkal
250
4. felvett értékék beírása a változókba
450
5. határok figyelése
124

1. A viszonylag hosszú téglalaprajzoló szubrutinbál csak ennyi marad:

9 REM kor kirajzolasa
10 CIRCLE PAPER pp; INK ti, OVER ov;x,y,r
20 RETURN

Eddig az x,y értékpár a téglalap bal felső sarkának helyét adta meg, most a kör közepét. A kör sugarának latin neve radiusz, ezért jelöltük r-rel, a matematika könyvekben is így találkoztunk vele.

2., 3., 4. A téglalap rajzolásához szükséges változók közül a p, tv és a tf feleslegessé vált. Ezzel a kezdeti érték megadások is rövidebbek lesznek.

427 LET r=10:LET k(7)=r:REM a kor sugara

A 428, 429 sorok törölhetők.

264 LET r=INT(RND*20)+1:LET k(7)=r

Ezzel a kör sugara 1-20 Közötti érték lehet.
A 266 és 268 sorokra szintén nincs szükség.

467 LET r=k(7)

A 469 és 471 sorok törölhetők.

5. A határértékek figyelése is egyszerűsödik; nincs szükség a vízszintes és függőleges hosszúság (hv, hf) kiszámítására, hiszen a középponthoz képest a kör alsó és felső, illetve jobb és bal széle egyaránt éppen sugárnyi távolságra van. Egy kis vázlatrajz most is segíteni fog.
Rajzoljunk a kép 4 sarkába egy-egy kört!

 
 

A kör középpontja nem kerülhet az egyenesen kívülre.

135 IF x<r THEN LET ev=-ev:LET x=x+ev
140 IF x<255-r THEN LET ev=-ev:LET x=x+ev
145 IF y<r THEN LET ef=-ef:LET y=y+ef
150 IF y<175-r THEN LET ef=-ef:LET y=y+ef

A 130 és 132 sor törölhető.

S máris próbálhatjuk a körök rajzolását! Ha kiiktatjuk a 382-es sort, akkor a gép nem vár billentyűlenyomásra, hanem a meglevő értékekkel folytatja a rajzolást.

Mentsük ki a programot Kb61 néven, majd hozzuk alapállapotba a gépet!

1 REM kb61
2 DIM k(10)
3 DIM t$(1000,1): LET t$(1)="q"
4 GO TO 600
9 REM kor kirajzolasa
10 CIRCLE PAPER pp; INK ti, OVER ov;x,y,r
20 RETURN
124 REM 124-160 ertekmodositas ellenorzes
125 LET x=x+ev
127 LET y=y+ef
135 IF x<r THEN LET ev=-ev:LET x=x+ev
140 IF x>255-r THEN LET ev=-ev:LET x=x+ev
145 IF y<r THEN LET ef=-ef:LET y=y+ef
150 IF yy175-r THEN LET ef=-ef:LET y=y+ef
160 RETURN
200 REM 200-210 rajzolas
201 PLOT PAPER pp; INK ti; OVER ov;x,y
210 RETURN
250 REM 250-270 valtozok kezdeti ertekenek bealitasa veletlen szamokkal
252 LET pp=INT (RND*8): LET k(1)=pp
254 LET ti=INT (RND*8): LET k(2)=ti
256 LET x=INT (RND*111)+70: LET k(3)=x
258 LET y=INT (RND*41)+70: LET k(4)=y
260 LET ev=INT (RND*21)-10: LET k(5)=ev
262 LET ef=INT (RND*21)-10: LET k(6)=ef
264 LET r=INT (RND*20)+1: LET k(7)=r
270 RETURN
300 REM billentyu figyeles
302 LET b$=INKEY$
303 IF b$<>"" THEN LET t$(j)=b$: LET j=j+1
304 PRINT AT 0,0;b$
305 IF b$="t" OR b$="T" THEN LET ev=0:LET ef=1
310 IF b$="y" OR b$="Y" THEN LET ev=1:LET ef=1
320 IF b$="h" OR b$="H" THEN LET ev=1:LET ef=0
330 IF b$="b" OR b$="B" THEN LET ev=1:LET ef=-1
340 IF b$="v" OR b$="V" THEN LET ev=0:LET ef=-1
350 IF b$="c" OR b$="C" THEN LET ev=-1:LET ef=-1
360 IF b$="d" OR b$="D" THEN LET ev=-1:LET ef=0
370 IF b$="r" OR b$="R" THEN LET ev=-1:LET ef=1
380 IF b$="f" OR b$="F" THEN LET ev=0:LET ef=0
382 IF b$="" THEN GO TO 302
385 IF CODE b$>64 AND CODE b$<91 THEN LET ov=0
386 IF CODE b$>96 AND CODE b$<123 THEN LET ov=1
387 IF b$="p" THEN GO SUB 400
390 RETURN
400 REM 400-410 szinvalasztas
405 INPUT "papir szin? ";pp
408 INPUT "tinta szin? ";ti
410 RETURN
420 REM 420-439 valtozok kezdeti ertekenek beallitasa
421 LET pp=7: LET k(1)=pp: REM papir szin
422 LET ti=0: LET k(2)=ti: REM tintaszin
423 LET x=69: LET k(3)=x: REM kezdeti hely
424 LET y=78: LET k(4)=y: REM kezdeti hely
425 LET ev=-5: LET k(5)=ev: REM vizszintes elmozdulas
426 LET ef=2: LET k(6)=ef: REM fuggoleges elmozdulas
427 LET r=10: LET k(7)=r: REM a kor sugara
430 LET ov=1: LET k(10)=ov: REM OVER1 vagy OVER 0
439 RETURN
450 REM 450-479 a felvett ertekek beirasa a valtozokba
455 LET pp=k(1)
457 LET ti=k(2)
459 LET x=k(3)
461 LET y=k(4)
463 LET ev=k(5)
465 LET ef=k(6)
467 LET r=k(7)
473 LET ov=k(10)
479 RETURN
500 REM 500-540 kepernyo torles
510 INPUT "toroljunk? i/n";v$
520 IF v$="n" THEN RETURN
530 IF v$="i" THEN CLS: RETURN
540 GO TO 510
550 REM kezdes vagy folytatas
560 INPUT "Kezdes vagy folytatas? k/f";v$
570 IF v$="f" THEN RETURN
580 IF v$="k" THEN LET j=1: RETURN
590 GO TO 560
600 REM 600-670 kerdezes
605 INPUT "Akarsz kazettarol adatokat betolteni i/n";v$
610 IF v$="n" THEN GO TO 660
620 IF v$="i" THEN GO TO 630
625 GO TO 605
630 INPUT "Milyen neven vetted fel a kazettara?";n$
640 LOAD n$ DATA k()
645 GO SUB 450
650 GO TO 670
660 GO SUB 420
665 GO SUB 256
670 INPUT "rajzolsas / visszajatszas / stop (r/v/s)";v$
675 IF v$="s" THEN STOP
680 IF v$="r" THEN GO TO 700
690 IF v$="v" THEN GO TO 755
695 GO TO 670
700 GO SUB 550
710 GO SUB 500
715 GO SUB 9
720 GO SUB 300
730 IF b$="q" THEN GO TO 670
740 GO SUB 124
750 GO TO 715
755 GO SUB 500
757 GO SUB 450
758 LET j=1
760 GO SUB 9
770 LET b$=t$(j)
780 GO SUB 304
790 IF b$="q" THEN GO TO 670
800 LET j=j+1
805 GO SUB 124
810 GO TO 760

FOLYTASSUK AZ EGYENESSEL, pontosabban az egyenes szakasszal!
Az utasítás neve DRAW (ejtsd dró). Az angolban a szónak több jelentése is van, itt a rajzol, vonalat húz értelemben használjuk. Elérése: K módban a W lenyomásával.
A pontosság kedvéért: az egyenes végtelen hosszú; szakaszról akkor beszélünk, ha az egyenest két ponttal lehatároljuk. Ezek szerint egy szakasz megrajzolásához meg kellene adnunk a kezdőpontját és a végpontját, ám valójában a gép csak a végpontot várja tőlünk, s a kezdőpontot azonosnak tekinti azzal, ahol az előző rajzot befejeztük, akár pontot, akár egyenest, akár kört rajzoltunk. Hogy a körnek nincs kezdőpontja? Ez igaz - akkor, ha s kör már készen van. A Spectrum viszont mindig jobboldalt kezdi a kör rajzolását, ennélfogva a kezdő- és végpontja egybeesik ugyan,de van mind a kettő.
No és mi történik akkor, ha most kezdjük a rajzolást, tehát nincs előző rajz, vagy ha nem ott akarjuk kezdeni a rajzot, ahol a régit befejeztük? Erre is van mód. Ekkor egy PLOT utasítással megadhatjuk a kezdőpontot.
Most már ideje lesz a tettek mezejére lépni.

1000 PLOT 100,120
1010 DRAW 10,40

RUN 1000

A kezdőpont a 100,120 koordinátájú hely, a végpont pedig ehhez képest 10 képponttal jobbra és 40-nel följebb került. Tehát a szakasz végpontját mindig az előző rajz befejezéséhez képest kell megadnunk, ebből következőn a DRAW után írt számok negatívak is lehetnek. Számszerűen: az első szám, a vízszintes elmozdulás -255 és +255 között, a második, a függőleges elmozdulás pedig -175 +175 között. A kör rajzolásához hasonlóan, ha a megadott tartományokba eső értékeket írunk be, a gép elkezdi behúzni ez egyenest, ám ha valahol a határba ütközik, természetesen jön a

B Integer out of range

hibaüzenet.
Rajzoljuk meg a képernyőt középen vízszintesen átszelő egyenest!

1000 PLOT 0,87
1010 DRAW 255,0

S az egyenes balról jobbra kirajzolódik, a rajzolás vége a 255,87 pont. csináljuk mindezt az ellenkező irányban is:

1000 PLOT 255,87
1010 DRAW -255,0

Az eredmény ugyanaz, mint korábban, bár most a rajzolás végpontjának koordinátája: 0,87.
A függőleges egyenes alulról felfelé:

1020 PLOT 127,0
1030 DRAW 0,175

s talán magától érthetődően

1020 PLOT 127,175
1030 DRAW 0,-175

ugyanaz, csak lefelé.

Játszadozzunk egy kicsit a vízszintes és függőleges egyenesekkel! Ha egymás után többször ki akarjuk rajzolni bármelyiket, érdemes ciklust készítenünk. Maradjunk most a balról jobbra irányú változatnál. Milyen kezdőpontok jöhetnek számításba?

0,0
0,1
0,2
...
0,175

Kézenfekvő a ciklus:

1000 FOR i=0 TO 175 STEP 2

A STEP 2 miatt nyilván minden második pontsorba kerül egyenes.

1010 PLOT 0,i

Ezzel berajzoltuk a bal szélre a kezdőpontot:

1020 DRAW 255,0

vízszintes egyenest húz teljes képszélességben

1030 NEXT i

A STEP értékek átírogatásával különböző sűrűségű vonalsorozatokat kaphatunk.
Rakjuk ki a képre a függőlegeseket is! Itt a kezdőpont az alsó vízszintes sorba kerül, a lehetséges koordinátaértékek

0,0
1,0
2,0
...
255,0

Ugyanúgy, mint az előbb

1040 FOR i=0 TO 255 STEP 3

Természetesen használhatjuk újra az i-t mint ciklusváltozót, hiszen az előző ciklus az 1030-as sorbán véget ért.

1050 PLOT i,0

a kezdőpont berajzolása az alsó sorba,

1060 DRAW 0,175

a maximális hosszúságú függőleges egyenes

1070 NEXT i

s máris van egy rácsos ábránk, ahol az ab téglalap mérete a két STEP érték átírásával módosítható.
Tegyük könnyebben kezelhetővé a változtatást, a STEP értékeket adjuk meg INPUT-tal:

990 INPUT "Vizszintes meret";v
995 INPUT "Fuggoleges meret";f
1000 FOR i=0 TO 175 STEP f

A vízszintes egyenesek lépésköze határozza meg a függőleges rácsméretet.

1040 FOR i=0 TO 255 STEP v

A függőleges vonalak távolsága adja meg a vízszintes rácsméretet.

Különböző v és f értékeket beírva elég sok értékpár adódik, jó lenne mindegyiket kipróbálni, csakhogy elég unalmas mindig újra s újra beírni az értékeket. No de többek között arra jó a számítógép, hogy az ilyen monoton munkától megkíméljen. A v értéke 2 és 11 között változzon, az f értéke pedig 2 és 10 között. Hány különböző értékpár jöhet így létre? A v-nek 10 különböző értéke van (aki nem hiszi, számoljon utána), az f-nek 9.
Kezdjük el egymás alá írni az értékeket, persze ne összevissza, hanem valamilyen rendszer szerint. Vegyük a legkisebb f értéket, és vegyük hozzá növekvő sorrendben a v-ket, aztán vegyük az eggyel nagyobb f-et, és újra párosítsuk hozzá az összes v-t, mindaddig folytatva, amíg a legnagyobb f-fel is meg nem csináltuk.

f 2 2 2 2 2 2 2 2 2 2
v 2 3 4 5 6 7 8 9 10 11

Így 10 párt kaptunk, de csak egyetlen f értékkel végeztünk. Mivel 9 különböző f van, ezért összesen 9*10=90 értékpárt alkothatunk, s így 90 fajta rácsos ábrát készíthetünk.
Az f és a v léptetésére is egy-egy ciklust kell használnunk, ezek nem lehetnek egymástól függetlenek, mert a v minden értékelnél végig kell pörgetni az f ciklust. Erre jó a ciklusok egymásba ágyazása, amivel tegnap már találkoztunk. A külső ciklus legyen az f, a belső a v. Így először az f=2 függőleges méretű rácsokból kapjuk meg az összeset, ahogy a v végigfut a 2-10 értékeken , s csak akkor jön az f=3, és így tovább.

980 FOR f=2 TO 15 STEP 1
985 FOR v=2 TO 10 STEP 1
1000 FOR i=0 TO 175 STEP f
1010 PLOT 0,i
1020 DRAW 255,0
1030 NEXT i
1040 FOR i=0 TO 255 STEP v
1050 PLOT i,0
1060 DRAW 0,175
1070 NEXT i
1080 NEXT v
1090 NEXT f

Így szépen egymás után megrajzolható a 90 különböző rácsozat. Ha a v és f ciklusok határait megnöveljük, még többféle változathoz jutunk. Minden rajz befejezése után iktassunk be egy kis szünetet, majd töröljük le képet!

1072 PAUSE 200
1074 CLS

Ha PAUSE 200 helyett PAUSE 0-át írunk, akkor a gép addig várakozik, amíg le nem nyomunk egy billentyűt.

Bár úgyis mindenki rájönne, de azért megmondjuk: a DRAW-ba is betehetők a szokásos kiegészítések, mint PAPER, INK, BRIGHT, FLASH, OVER, INVERSE. Vegyük fel a programot Kb-62 néven, s hozzuk alapállapotba a gépet!
Eddig rengeteg vízszintes és függőleges vonalat húztunk, ideje lenne már valamilyen ferde vonalas ábrát készíteni. Kezdjük egy derékszögű háromszöget!

Ez 3 egyenes, ehhez 3 DRAW utasítás kell; a kezdőpont legyen a 100,120 pont.

1000 LET x=100
1010 LET y=120
1020 PLOT x,y

Ezzel megvan a kiinduló pont (A). A B-be egy 7 képpontból álló vízszintes egyenessel juthatunk, tehát a rajzolandó szakasz végpontjának x koordinátája 7-tel nagyobb, mint a kiindulóponté, az y koordináta ugyanennyi.

1030 DRAW 7,0

Ezután egy 10 hosszúságú függőleges következik:

1040 DRAW 0,10

Most a C-ben vagyunk, a visszajutás A-ba 7 lépés balra, 10 lépés lefelé.

1050 DRAW -7,-10

Ha az x-et és az y-t átírjuk, a háromszög más helyre kerül.
Rajzoljunk egy másik ábrát!

A beírt számok az A ponthoz mint kezdőponthoz viszonyított értékek. Az A pont helyét a kezdőpont koordinátai adják meg.

1000 LET x=100
1010 LET y=120
1020 PLOT x,y
1030 DRAW 10,8

Ezzel a B pontig készen vagyunk. B-ből C-be 19 képpontnyi hosszúságú függőleges vonal visz (8-ból 19-et kell elvenni, hogy -11 legyen az eredmény):

1040 DRAW 0,-19

Hasonlóan megadhatjuk a C-ből D-be, D-ből E-be s végül az E-ből A-ba mutató egyeneseket.

1050 DRAW -22,0
1060 DRAW 0,19
1070 DRAW 12,-8

Így nehézkes a módosítás, ezért tegyük ciklusba, az egyenesek rajzolását, a DRAW után álló két szám helyett változókat kell írnunk, ezek felfrissítéséről egy READ gondoskodik. A szükséges adatokat egy DATA-ban tárolhatjuk.

1000 LET x=100
1010 LET y=120
1020 PLOT x,y
1040 FOR i=1 TO 5 STEP 1
1050 READ v,f
1060 DRAW v,f
1070 NEXT i
1100 DATA 10,8,0,-19,-22,0,0,19,12,-8

Így a módosítás sokkal egyszerűbb, elég a megfelelő adatokat kicserélni vagy átírni a DATA-ban, és az 1040-es sorban a ciklusszámlálót kell az egyenesek számának megfelelően beállítani. Tehetjük ezt egy külön változóval is:

1030 LET esz=5
1040 FOR i=1 TO esz STEP 1

esz az egyenesek száma. Miután egy egyenes kirajzolásához két adat kell, így a DATA-ban legalább 2*esz számú adatnak kell lennie, sőt még azt is megtehetjük, hogy az esz értékét is beírjuk a DATA elejére.

1100 DATA 5,10,8,0,-19,-22,0,0,19,12,-8

Ekkor az 1030-ba LET helyett READ kerül:

1030 READ esz

Itt az ideje, hogy ezt is beépítsük a rajzolóprogramba. (A legutóbbi változatot Kb61 néven vettük fel.) De nem kell kitörölnünk a mostani sorokat, és a Kb61 meghívása után újra beírni. Programot betölteni nem csak a LOAD, hanem a MERGE utasítással is lehet. (A szó ejtése mőrdzs, jelentése egybeolvaszt, összevon, egyesít; elérése E módban SYMBOL SHIFT +T). A MERGE érintetlenül hagyja azokat a sorokat, amelyek újonnan behozandó programban nem szerepelnek. Mivel a benn lévő program 1000-nél kezdődik, a régi pedig 960-nál véget ért, így ezek szépen megférnek egymás mellett.

MERGE "kb61"

Az egyenesrajzolóból szubrutint csinálunk:

1080 RETURN

A kezdeti helyet beállító 1000 és 1010-es sorra nincs szükség. Tegyük be a DRAW-ba a PAPER, INK, OVER kiegészítéseket!

1060 DRAW PAPER pp;INK ti; OVER ov;v,f

Az új szubrutinunk a 9. sorban kezdődő körrajzolást váltja fel. A cserére két lehetőségünk is van: vagy átírjuk a 715 és 760 sorokat

715 GO SUB 1020
760 GO SUB 1020

vagy a fenti sorokban meghagyjuk a GO SUB 9-et, és a 10-es sort írjuk át

10 GO TO 1020

Az első megoldás hátránya, hogy meg kell keresnünk az összes helyet, ahol meghívtuk a 9-es szubrutint, s kicserélni 1020-ra. Ellenben előny, hogy megmarad a körrajzolás lehetősége is. Maradjunk ennél a változatnál.
Először ne a billentyűről vezérelve próbáljuk, hagyjuk a gépet önállóan alkotni! Ehhez ki kell iktatnunk a 382-t. Vagy beírjuk a

381 GO TO 385

sort, vagy a 382-es sor legelejére beszúrunk egy REM-et, és ezzel az itt levő utasítást a gép csupán megjegyzésnek tekinti.
Az indítás után a program egy ábrát kirajzol, majd

E Out of DATA, 1030:1

hibaüzenettel leáll, ami azt jelenti, hogy elfogyott az adat, a READ-nek nincs mit olvasnia. Ja persze! Az első ábra rajzolásakor az összes adatot felhasználtuk. Ha újra akarjuk olvasni őket, akkor be kell tennünk egy RESTORE-t

1025 RESTORE 1100

Többször futtatva a programot lesz olyan eset, amikor a képernyő széléhez érve a rajzolás leáll.

B Integer out of range,1060:1

Nem működik a határérték figyelés. Miért is működne, az erre a célra szolgáló 135-150 sorok még mindig úgy, tudják, hogy egy r sugarú kört rajzolunk. Hogyan lehetne úgy átalakítani őket, hogy a szabályos kör helyett a mostani szabálytalan ábránál is működjenek? A kör esetében az x,y-nal megadott középponthoz képest éppen r távolságra van az ábra alja, teteje, jobb illetve bal széle. Ezek a távolságok az új rajznál természetesen nem azonosak. De ha valamilyen módon meghatároznánk őket, s beírnánk a megfelelőt a 135-150 sorokba, akkor ezzel megoldottak a határfigyelést.
A 4 méretet jelöljük a következő módon:

xb: x irányú halra
xj: x irányú jobbra
yl: y irányú lefelé
yf: Y irányú felfelé

Az ábráról a méretek könnyen leolvashatók:

xb=12 xj=10 yf=8 yl=11

A programsorok módosítása már egyértelmű:

135 IF x<xb THEN LET ev=-ev:LET x=x+ev
140 IF x>255-xj THEN LET ev=-ev:LET x=x+ev
145 IF y<yl THEN LET ef=-ef:LET y=y+ef
150 IF y<175-yf THEN LET ef=-ef: LET y=y+ef

Az xj, xb, yf, yl változóknak értéket adó utasítások alkossanak külön szubrutint!

850 REM tavolsagok megadasa
851 LET xb=-12
853 LET xj=10
855 LET yf=8
857 LET yl=-11
860 RETURN

Ennek meghívására mindenképpen szükség van, akár új rajzot készítünk, akár a régi adatokat töltjük vissza kazettáról. Ezért

602 GO SUB 850

A szokásos visszajátszás üzemmód most nem működik, hiszen nincs lenyomott billentyű, amit tárolni lehetne. Mégis megismételhetünk egy rajzot, ha a megfelelő helyről újraindítjuk a programot. Ez a sor a 645, mert a kazettáról betöltést már elkerültük, s itt történik a k tömbbe eltett kezdeti értékek átírása a pp, t, ... stb. változókba.

Vegyük fel a programot Kb65 néven!

1 REM kb65
2 DIM k(10)
3 DIM t$(1000,1): LET t$(1)="q"
4 GO TO 600
9 REM kor kirajzolasa
10 CIRCLE PAPER pp; INK ti, OVER ov;x,y,r
20 RETURN
124 REM 124-160 ertekmodositas ellenorzes
125 LET x=x+ev
127 LET y=y+ef
135 IF x<xb THEN LET ev=-ev:LET x=x+ev
140 IF x>255-xj THEN LET ev=-ev:LET x=x+ev
145 IF y<yl THEN LET ef=-ef:LET y=y+ef
150 IF y>175-yf THEN LET ef=-ef: LET y=y+ef
160 RETURN
200 REM 200-210 rajzolas
201 PLOT PAPER pp; INK ti; OVER ov;x,y
210 RETURN
250 REM 250-270 valtozok kezdeti ertekenek bealitasa veletlen szamokkal
252 LET pp=INT (RND*8): LET k(1)=pp
254 LET ti=INT (RND*8): LET k(2)=ti
256 LET x=INT (RND*111)+70: LET k(3)=x
258 LET y=INT (RND*41)+70: LET k(4)=y
260 LET ev=INT (RND*21)-10: LET k(5)=ev
262 LET ef=INT (RND*21)-10: LET k(6)=ef
264 LET r=INT (RND*20)+1: LET k(7)=r
270 RETURN
300 REM billentyu figyeles
302 LET b$=INKEY$
303 IF b$<>"" THEN LET t$(j)=b$: LET j=j+1
304 PRINT AT 0,0;b$
305 IF b$="t" OR b$="T" THEN LET ev=0:LET ef=1
310 IF b$="y" OR b$="Y" THEN LET ev=1:LET ef=1
320 IF b$="h" OR b$="H" THEN LET ev=1:LET ef=0
330 IF b$="b" OR b$="B" THEN LET ev=1:LET ef=-1
340 IF b$="v" OR b$="V" THEN LET ev=0:LET ef=-1
350 IF b$="c" OR b$="C" THEN LET ev=-1:LET ef=-1
360 IF b$="d" OR b$="D" THEN LET ev=-1:LET ef=0
370 IF b$="r" OR b$="R" THEN LET ev=-1:LET ef=1
380 IF b$="f" OR b$="F" THEN LET ev=0:LET ef=0
382 IF b$="" THEN GO TO 302
385 IF CODE b$>64 AND CODE b$<91 THEN LET ov=0
386 IF CODE b$>96 AND CODE b$<123 THEN LET ov=1
387 IF b$="p" THEN GO SUB 400
390 RETURN
400 REM 400-410 szinvalasztas
405 INPUT "papir szin? ";pp
408 INPUT "tinta szin? ";ti
410 RETURN
420 REM 420-439 valtozok kezdeti ertekenek beallitasa
421 LET pp=7: LET k(1)=pp: REM papir szin
422 LET ti=0: LET k(2)=ti: REM tintaszin
423 LET x=69: LET k(3)=x: REM kezdeti hely
424 LET y=78: LET k(4)=y: REM kezdeti hely
425 LET ev=-5: LET k(5)=ev: REM vizszintes elmozdulas
426 LET ef=2: LET k(6)=ef: REM fuggoleges elmozdulas
427 LET r=10: LET k(7)=r: REM a kor sugara
430 LET ov=1: LET k(10)=ov: REM OVER1 vagy OVER 0
439 RETURN
450 REM 450-479 a felvett ertekek beirasa a valtozokba
455 LET pp=k(1)
457 LET ti=k(2)
459 LET x=k(3)
461 LET y=k(4)
463 LET ev=k(5)
465 LET ef=k(6)
467 LET r=k(7)
473 LET ov=k(10)
479 RETURN
500 REM 500-540 kepernyo torles
510 INPUT "toroljunk? i/n";v$
520 IF v$="n" THEN RETURN
530 IF v$="i" THEN CLS: RETURN
540 GO TO 510
550 REM kezdes vagy folytatas
560 INPUT "Kezdes vagy folytatas? k/f";v$
570 IF v$="f" THEN RETURN
580 IF v$="k" THEN LET j=1: RETURN
590 GO TO 560
600 REM 600-670 kerdezes
602 GO SUB 850
605 INPUT "Akarsz kazettarol adatokat betolteni i/n";v$
610 IF v$="n" THEN GO TO 660
620 IF v$="i" THEN GO TO 630
625 GO TO 605
630 INPUT "Milyen neven vetted fel a kazettara?";n$
640 LOAD n$ DATA k()
645 GO SUB 450
650 GO TO 670
660 GO SUB 420
665 GO SUB 256
670 INPUT "rajzolsas / visszajatszas / stop (r/v/s)";v$
675 IF v$="s" THEN STOP
680 IF v$="r" THEN GO TO 700
690 IF v$="v" THEN GO TO 755
695 GO TO 670
700 GO SUB 550
710 GO SUB 500
715 GO SUB 1020
720 GO SUB 300
730 IF b$="q" THEN GO TO 670
740 GO SUB 124
750 GO TO 715
755 GO SUB 500
757 GO SUB 450
758 LET j=1
760 GO SUB 1020
770 LET b$=t$(j)
780 GO SUB 304
790 IF b$="q" THEN GO TO 670
800 LET j=j+1
805 GO SUB 124
810 GO TO 760

850 REM tavolsagok megadasa
851 LET xb=12
853 LET xj=10
855 LET yf=8
857 LET yl=-11
860 RETURN

1000 LET x=100
1010 LET y=120
1020 PLOT x,y
1025 RESTORE 1100
1030 READ esz
1040 FOR i=1 TO esz STEP 1
1050 READ v,f
1060 DRAW PAPER pp;INK ti;OVER ov;v,f
1070 NEXT i
1080 RETURN
1100 DATA 5,10,8,0,-19,-22,0,0,19,12,-8

Kitűzött céljaink közül a körrel és az egyenessel végeztünk, még A KÖRÍV VAN HÁTRA. Ezt is a DRAW utasítással rajzolhatunk:

1200 PLOT 40,60
1210 DRAW 20,50

Idáig semmi új, a 40,60 koordinátájú pontot egy egyenes köti össze a 60,110 koordinátájúval (40+20=60, 60+50=110).
Írjunk a DRAW-ba a két koordinátaérték után egy harmadik számot, legyen ez a 2:

1210 DRAW 20,50,2

S mint látható, a két pontot a gép most egy körívvel kötötte össze.
Próbáljunk ki néhány értéket!

1190 FOR i=0 TO 2 STEP 0.2
1210 DRAW 20,50,i
1220 NEXT i

A 0 értéknél egyenest rajzolt a gép, a növekvő i értékeknek megfelelően pedig egyre jobban kerekedő körívet kapunk. Próbálkozzunk negatív számokkal!

1190 FOR i=0 TO -2 STEP -0.2

A körívek a másik oldalra kerülnek. Úgy is mondhatjuk, hogy negatív értékeknél az óramutató járásával megegyezően, pozitív értékeknél pedig ezzel ellentétes irányba húzza a körívet a gép. Ha félkörívet szeretnénk, akkor az i-nek a PI (ejtsd: pí) értékét kell adnunk. A számot a kör kerületének területének számításánál használjuk a leggyakrabban. Értékét pontosan megmondani nem lehet, ugyanis egy végtelen hosszúságú tizedes tört, 3.14-dal szoktuk közelíteni. A gép pontosabb értéket tart a "fejében", ezt meg is nézhetjük:

PRINT PI

A PI elérése E módban M, a gépnek nincs külön betűformája.

A DRAW-ba írt harmadik szám és a körív mérete közötti pontos összefüggést nem részletezzük (a beírt szám az ívhez tartozó középponti szöget adja meg radiánban), de érdemes kipróbálni a PI/2, a 3*PI/2, az 5*PI, a 10*PI stb. értékeket.

7. nap - Egy-két apró trükk

Már nagyon sok komoly dolgot csináltunk, itt az ideje, hogy tréfálkozzunk egy Kicsit. Írjuk be a

POKE 23606,8

sort. No, ez rossz tréfa volt.
Mint látjuk, a karakterek kissé átrendeződtek. Semmi baj, a gépet nem rontottuk el mindörökre: a tápegység kihúzása és ismételt bedugása mindent visszaállít eredeti állapotába. A magyarázatot egy kicsit messzebb kell kezdenünk. Sokszor említettük már a memória szót, amit annyival intéztünk el, hogy itt tárolja a számítógép a beírt programot. Most először különbséget kell tennünk a ZX SPECTRUM 48K és 16K típusú változata között. Egyelőre minden, amit mondunk, a 48K-ra vonatkozik.
Egyáltalán:

MIT JELENT AZ, HOGY 48K?

A gép memóriája nem egy hatalmas zsák, ahová mindent összevissza be lehet dobálni: a memóriában rend van. A rendelkezésre álló hely 65536 kis egységből áll, magunk között egy ilyen egységet nevezzünk rekesznek! Egy rekeszben 1 byte (ejtsd bajt) információt találhatunk. Ez éppen elegendő arra, hogy beleférjen egy 0 és 255 közé eső egész szám.
A 65536 byte = 64Kbyte (ejtsd Kilobájt; a K betű a Kilo rövidítése).
A Kbyte = 1024 byte, így jön ki 64*1024 = 65536. No de a Kilo, ezt mindenki tudja, ezerszerest jelent!

1 km = 1000 m
1 kg = 1000 g stb.

Igen, csakhogy a számítógép kettes számrendszerben dolgozik, s ott az 1000 nem kerek szám, kerek viszont az 1024 (ennek okáról majd később).
Miért 48K-s a gépünk, ha 64K azaz 64 Kbyte memóriája van? Azért, mert a 64K-ból 16K pontosan 16368 byte) már foglalt, méghozzá kitörölhetetlen, átírhatatlan adatokkal. Így szabad használatra csak 48K marad, illetve még annyi sem. Abban a 16K-ban nagyon fontos dolgok vannak. Ezek segítségével képes a gép értelmezni a BASIC utasításainkat, itt van elraktározva a betűk, számok, jelek rajzolatának kódja, s itt van az egész működését irányító vezérlőprogram. Nagy baj lenne, ha ebből bármi is elveszne, ezért vannak ezek az információk (programok, adatok) úgynevezett "csak olvasható" memóriában (angol rövidítése: ROM) elraktározva.
Még egyszer hangsúlyozzuk: ebbe a memóriarészbe sem adatot bevinni, azaz írni, sem adatot kitörölni belőle nem lehet. A szabad 48K-ból 6932 byte a képernyő számára van fenntartva. Ezen a területen tárolja a gép, hogy a képernyőn milyen mintájú és színű ábrák vannak. Ezenfelül még a gép használ néhány száz byte területet, ahol saját maga számára fontos, de változó értékű adatokat tárol.
Már tudjuk, hogy adatokat csak úgy lehet tárolni, ha ismerjük a helyet, ahova tettük őket. A SPECTRUM a 65536 memóriarekeszét 0 ... 65535 számokkal azonosítja. Egy rekesz tartalmát kiírathatjuk a képernyőre, legyen ez mondjuk a 40000 számú.

PRINT PEEK 40000

A PEEK (ejtsd pík) angol jelentése kiles, kukucskál; a BASIC-ben az utána írt számnak megtelelő memóriahelyről kimásolja az ott talált számot. (elérése: E módban O)

LET x=PEEK 40000

utasítással nem a képernyőre, hanem az x nevű változóba kerül a kimásolt érték.
A beíró utasítás a POKE (ejtsd pók, angol jelentse: belök, beszúr; elérése K módban O).

POKE 40000,13

S ezzel a 40000-es memóriahelyre beírtuk a 13-at. Ki is próbálhatjuk:

PRINT PEEK 40000

s a képernyőn ott a 13.
Mint említettük, egy memóriahelyre csak 0 és 255 közötti egész számok vihetők be. Ha 255-nél nagyobb értékekkel próbálkozunk, akkor a szokásos hibaüzenet jelentkezik:

B Integer out of range

A -255 és 0 közötti negatív számoknál viszont egy kis furcsasággal találkozunk.

POKE 40000,-1
PRINT PEEK 40000
255

POKE 40000,-2
PRINT PEEK 40000
254

Mi is történik? A titok könnyen megvilágítható: képzeljük el azt, hogy egy körlap szélére felírtuk a számokat 0-tól 255-ig. Az óramutató járásával egyező irányt tekintsük pozitívnak, az ellenkezőt negatívnak. Az előjel tehát most irányt jelöl.
Induljunk a 0 helytől, ha előre megyünk (+ irány), azt pozitív számokkal jelöljük, ha hátra akkor negatívokkal. Így -1 lépés megtételével a 255-öshelyre léptünk, -2-vel 254-re, stb. Valami ehhez hasonló történik a fenti POKE utasítások esetében is, mindezért ismét csak a kettes számrendszer a felelős.
A -255-nél kisebb negatív számoknál már újra az ismert hibaüzenetet kapjuk. A tört számokat most is a kerekítési szabályok szerint kerekíti a gép.

Talán sokakban felmerült, hogyan tud a számítógép negatív, tört vagy 255-nél nagyobb egész számokkal dolgozni, ha csak 0 ás 255 közötti egészeket tárol. A válasz nagyon egyszerű. Gondoljunk arra, hogy a tízes számrendszerben bármilyen szám leírásához elegendő a 10 számjegy, sőt az európai nyelvek átlagosan 30-40 betűs ABC-i elegendők a teljes szókincs leírásara. Így a 256-féle különböző szám bőven elegendő. Persze ennek az az ára, hogy egy szám tárolására 5 byte-ot használ el a gép. Ezzel az esetek többségében kellő pontossággal tud számolni, ugyanakkor sokszor az 5-ből byte megspórolható lenne.
A rajzolóprogramunk billentyűértékeinek tárolásakor említettük, hogy tárolhatjuk közvetlenül a billentyű betűjelét, vagy a betűjelnek megfelelő számot. A dolog lényege, hogy végül is a gép mindkét módszernél számokat tárol (mást nem is tud). Mi az első módot választottuk, ehhez egy szöveges tömböt definiáltunk,

DIM t$(1000,1)

méghozzá úgy, hogy az 1000 db szó mindegyike csak 1 karakterből áll, a gép így ilyenkor minden karakter számára 1 byte helyet foglal le, ugyanis bármelyikük kódja 32 és 255 közötti szám.
Ha közvetlenül számokat tároltunk volna, akkor egy numerikus tömböt kellett volna definiálnunk,

DIM t(1000)

ahol nincs módunk a gép tudomására hozni, hogy milyen számokat akarunk elrakni, ezért ő felkészül a legrosszabbra, s 5 byte helyet lefoglal minden egyes számnak. Így az utóbbi módszer memóriaigénye ötször akkora.
Az egészből annyi tanulság vonható le, hogy a SPECTRUM a számok tárolását elég memóriafaló módon végzi, így bizonyos esetekben 0 és 255 Közé eső számoknál) helyet takaríthatunk meg, ha numerikus változó helyett karakterest használunk, vagy ha a tárolást közvetlenül a memóriába írással oldjuk meg (erre szolgál a POKE utasítás). Csakhogy A POKE-KAL NAGYON KELL VIGYÁZNI, mert, mint láttuk, akár egyetlen ilyen utasítással is meg lehet bolondítani a gépet.

Ideje szétnéznünk egy kicsit a memóriában. Többször emlegettük már a 16 Kbyte (16384 byte) nagyságú, nem átírható tartalmú, úgynevezett ROM-ot. Ez a 0-16383 memóriahelyeken, vagy más szóval memóriacímeken található.
Ide hiába próbálunk beírni bármilyen értéket, nem történik semmi pl.

POKE 10000,13
PRINT PEEK 10000

s az eredmény 255.
Pedig formailag minden rendben volt, ezért a gép, nem figyelmeztetett hibaüzenettel. Tartalmi hibát vétettünk, mert olyan helyre próbáltunk írni, ahová lehetetlen. A 16384-es memóriahelyen (címen) kezdődik a képernyőmemória,

POKE 16384,255

s a képernyő bal felső sarkában egy vízszintes csíkot láthatunk. A hossza éppen 8 képpontnyi. Egy 8x8 képpontból álló mező 8 byte-nyi helyet igényel. Az egész kép 24*32=768 ilyen mezőből (vagy ahogy neveztük, karakterhelyből) áll. Összesen tehát 768*8=6144 byte memória szükséges a teljes kép megjelenítéséhez. S mindez csak a mintára elegendő. A színek további 768 byte-ot foglalnak el.
Mint már említettük, minden karakterhelyhez egy papír- és egy tintaszín adható, és még lehetőség van a FLASH (villogás) és a BRIGHT fényesség ki- és bekapcsolására is. Ezzel 23295-ig meg is lennénk.
A további memóriafelosztást sajnos nem tudjuk ilyen módon megbeszélni; részint azért, mert egyes területek szerepét nem lehetne pár szóval elmondani, másreszt azért, mert a területek alsó és felső határai sokszor nem állandó értékek, hanem az igénynek megfelelően csúsztathatók ide-oda. Így sokkal gazdaságosabban kihasználható a rendelkezésre álló memória.
A gép működése szempontjából rendkívül fontos a 23296-23551 memóriacímek közötti úgynevezett rendszerváltozó-terület. Itt találhatók azok a bizonyos változó adatok, amelyek a gép működéséhez elengedhetetlenül szükségesek. Egy ilyen rendszerváltozót írtunk át a mai nap elején, amikor is a gép összekeverte a karaktereket. Ugyanis a 23606 és 23607 memóriacímeken tárolja a gép a karakterek mMintázatának kezdőcímét.

No és miért pont 2 byte szükséges egy memóriacím tárolásához? Mondhatnánk azt, hogy 1 kevés, 3 pedig sok. A 2 byte felfogható egy kétjegyű számnak; igaz, hogy egy kicsit szokatlan, mert mindkét számjegy értéke 0 és 255 közötti szám lehet. Ez némileg eltér a megszokott tízes számrendszertől, ahol ugye csak 0 és 9 közötti számjegyek vannak. Ám ez az eltérés kisebb, mint első pillanatban gondolhatnánk. A tízes számrendszerben az egy számjeggyel leírható legnagyobb szám a 9. A 10-et már csak két helyiértéken tudjuk megadni, a nagyobb helyiértéken levő 1-es számjegy 10-et ér, a 2 20-at és így tovább. Amikor azt mondjuk, hogy 38, akkor lényegében azt értjük rajta, hogy 3*10.+8*1.
A mostani esetben a legnagyobb "számjegyünk" 255, ezért a nagyobb helyiértékeken levő 1-es 256-ot ér, a 2-es 2*256-ot stb. Ez akkor (ugye könnyű kitalálni?) 256-os számrendszer. S vajon mekkora itt a helyiértékkel leírható legnagyobb szám?

255*256+255=35535

Ó, éppen ez a legnagyobb memóriacím érték! Micsoda véletlen!? Szó sincs véletlenről,a dolgok kulcsa a kettes számrendszerben keresendő, de ne ijedjünk meg, most nem fogunk elmélyedni benne.
Hozzuk alaphelyzetbe a gépet, és írjuk be a

PRINT PEEK 23606+256*PEEK 23607

parancsot! Ezzel megtudtuk, hogy a karakterminták kezdőcíme alaphelyzetben 15360.
Figyeljük meg, hogy a kisebb helyiérték a kisebb memóriacímen található, ez ugye abból látszik, hogy a nagyobb címről kiolvasott értéket megszoroztuk 256-tal, ezért csak ez lehet a nagyobb helyiérték. Ez a sorrend minden memóriacím tárolásának esetében is. Kettőt rögtön kipróbálhatunk. Töltsük be bármelyik programunkat! Van olyan rendszerváltozó, amely a BASIC program elejét mondja meg:

PRINT PEEK 23635+256*PEEK 23636

egy másikból pedig a BASIC program végét olvashatjuk ki:

PRINT PEEK 23627+256*PEEK 23628

s a két szám különbsége adja a memóriában lévő program hosszát.
Nézzünk meg két másik rendszerváltozót!

PRINT PEEK 23561
35

PRINT PEEK 23562
25

POKE 23561,1

Ezután próbáljunk meg bármit beírni! A gép hadarni kezdett, egy billentyű lenyomásra többször kiírta a szót. Túl rövid idő telik el két billentyűlenyomás között. Jelenleg csak 1/50 másodperc, elég nehéz úgy megérinteni a billentyűt, hogy ne ismételjen. A bekapcsoláskor a változóban levő érték (35) 35/50 másodpercre növeli ezt az időt, s ez már elegendő hosszúnak tűnik. A 23561 címen található szám végül is egy számlálót állít be a gép számára.
Próbáljuk meg a másik memóriahelyet is átírni!

POKE 23562,1

Ez a késleltetési idő (alapállapotban 5) akkor jut érvényre, amikor folyamatosan nyomunk egy billentyűt. Itt a rövidebb idő hasznos lehet, ha egy sor szerkesztésekor gyorsabban akarunk törölni, vagy a cursort mozgatni.
Próbáljuk ki a

POKE 23561,0
POKE 23562,0

sorokat! A várakozási idő nemhogy nullára csökkenne, hanem jelentsen megnövekszik, éppen 256/50 értékre, ez több, mint 5 másodperc. Ennek magyarázatába most nem mélyedünk bele, inkább próbáljuk ki a

POKE 23609,100

sort. S ezután minden billentyűlenyomást egy sípoló hang kísér, amely előbb-utóbb ugyan zavaró lehet, de mégis hasznos abból a szempontból, hogy egyértelműen jelzi, amikor a gép elfogadta a lenyomott billentyűt. A számmal a hang hosszát tudjuk befolyásolni. Az alapérték 1 volt, itt olyan rövid a hang, hogy nem is halljuk.

Mindez, amit idáig elmondtunk, egyformán érvényes a 16K-s és 48K-s géptípusokra is, annyi eltéréssel, hogy az előbbinél csak 16384 byte átírható memóriaterület van.
S még valamit! Olyan sokat emlegettük, hogy a képernyő két alsó sorába nem tudunk írni. No ezért elnézést kérünk, mert lehet. Így:

10 PRINT #1; AT 0,0;" Ide is lehet irni"
15 PRINT #1; 1,0;"Ha vege a futasnak, eltunik a szoveg"
20 GO TO 20

A 20-as sornál a program önmagában kering, s így sosem lesz vége, csak ha BREAK-kel megállítjuk; tehát a szövegünk mégis látható maradt.


Harmadik hét

1. nap - Rajzoljunk grafikont

A számítógép egyik legvonzóbb tulajdonsága az, hogy véletlen jelenségeket tud előállítani. Már önmagában ezért is érdemes volna ismerkedni, kísérletezgetni vele. Kezdjük azzal, hogy készítünk egy programot, amely grafikusan megjeleníti, hogy az egyes előállított véletlen számok milyen gyakran fordulnak elő. A képernyő vízszintesen 256 pontból áll, így egymás mellé 256 függőleges vonal rajzolható. Ha tehát 1 és 256 közötti véletlen számokat készítünk, akkor mindegyik kaphat egy függőleges vonalat, melynek hossza attól függ, hogy hányszor került elő az adott szám.
Gondoljuk végig feladatainkat!

  1. véletlenszám-előállítás
  2. az előfordulási gyakoriság nyilvántartása
  3. gyakoriság megjelenítése

1. Itt nincs sok dolgunk

100 LET r=INT (RND*256)+1

2. A 256 különböző véletlen számunk van, így ugyanennyi változó kell ahhoz, hogy tárolhassuk, melyik hányszor fordult elő. Ezt a 256 változót nyilván együtt érdemes kezelni, azaz egy 256 elemes tömböt célszerű használnunk.

10 DIM g(256)
20 LET g(r)=g(r)+1

A kapott véletlen szám az r változóban van. A tömb r-edik eleméhez hozzáadunk egyet.

3. A megjelenítés

Például ha az r,g(r) koordinátájú pont megjelenése annyit jelent, hogy az r értékével egyenlő véletlen szám már g(r)-szer fordult elő.

130 PLOT r,g(r)
140 GO TO 100

A program rendben elindul, de előbb-utőbb meg fog állni

B Integer out of range 130:1

hibaüzenettel.
Mit találhatott túl nagynak? Nincs túl sok lehetőség

PRINT r
256

Jogos. A véletlen számok 1 és 256 között mozognak, ellenben a PLOT-ban a vízszintes koordináta 0-255 közötti érték lehet, Ezért módosítsuk a 130-at!

130 PLOT r-1,g(r)

Ha van elég türelmünk, akkor figyeljük egy darabig: olyan ez, mint a fű növése. Jó lenne egy kicsit pontosabb adatokat kapni, más szóval statisztikát készíteni. Ehhez persze kellően NAGY SZÁMÚ KÍSÉRLETET KELL VÉGEZNÜNK. Legyen ez a szám, mondjuk 10240-ig ha teljesen egyenletesen elosztva követnék egymást a véletlen számok, akkor mindegyik 40-szer fordulna elő. Persze biztosan lesznek átlag fölöttiek meg átlag alattiak is.

90 FOR i=1 TO 10240 STEP 1
100 LET r=INT (RND*256)+1
120 PLOT g(r)=g(r)+1
130 PLOT r-1,g(r)
140 NEXT i

Lényegében van egy 255 számhól álló adathalmazunk, amely akármilyen forrásból is származhatna. Mi most a SPECTRUM által gyártott véletlen számok előfordulási gyakoriságát vizsgálgatjuk, de természetesen bármilyen adatokkal dolgozhatnánk.
Készítsünk néhány vizsgáló szubrutint!

1, Válasszuk ki a legkisebb és a legnagyobb értéket! Tároljuk ezeket a min és max nevű változókban! Az egyszerűség kedvéért a min-be az előforduló legkisebb, míg a max-ba a legnagyobb értékét tehetjük.
Mi lesz a módszer? Nézzük a max értékét! Elővesszük az első számot, g(1), és betesszük a max-ba, majd egy ciklussal végigmegyünk a többin, s ha olyat találunk, amely nagyobb az eddigi max-nál, akkor az így megtalált érték kép elő maximálissá.
A min megkeresése szinte ugyanilyen, azzal a kivétellel, hogy itt összehasonlításkor a kisebbet kell figyelni.

300 LET max=g(1)
310 LET min=g(1)
320 FOR i=2 to 256 STEP 1
330 IF g(i)>max THEN LET max=g(i)
340 IF g(i)<min THEN LET min=g(1)
350 NEXT i
360 PRINT "a legkisebb ";min
370 PRINT "a legnagyobb ";max
380 RETURN

A meghívás

150 GO SUB 300
290 STOP

Ez utóbbi arra szolgál, nehogy "belecsorogjunk" a szubrutinba GO SUB nélkül.
Az indítás most

GO TO 150

Ugyanis jelenleg a g tömb fel van töltve számunkra értékes adatokkal, s a RUN hatására minden változó törlődik.

2. Keressük meg, hányszor fordul elő egy adott szám!

400 REM egy szam keresese
410 INPUT "melyik szamot keresed?";x
420 LET sz=0
430 FOR i=1 TO 256 STEP 1
440 IF g(i)=x THEN LET sz=sz+1
450 NEXT i
460 PRINT x;" ";sz;" alkalommal fordult elo"
470 RETURN

A meghívás:

160 GO SUB 400

Indítás:

GO TO 160

3. Keressük meg, hány szám esik egy adott sávba!

500 REM sav vizsgalat
510 INPUT "a sav also hatara ? ";sa
520 INPUT "a sav felso hatara ? ";sf
530 LET sz=0
540 FOR i=0 TO 255 STEP 1
550 IF g(i)>=sa AND g(i)<=sf THEN LET sz=sz+1
560 NEXT i
570 PRINT TAB 2;"hatarok";TAB 16;"elofordulas"
580 PRINT TAB 3;sa;"-";sf;TAB 20;sz
590 RETURN

Az 550-es sorban AND-del kapcsoltuk össze a feltételeket, hiszen mindkettőnek teljesülnie kell, ahhoz hogy az adott szám a két határ közé essen.

A három vizsgáló szubrutinhoz már illik egy tisztességes kezelőprogramot írni, ahol egy billentyűlenyomásával kiválasztható a megfelelő szubrutin.

145 CLS
150 PRINT AT 3,0;"minimum es maximum kereses";TAB 30; FLASH 1;"m"
160 PRINT AT 6,0;"szam kereses";TAB 30; FLASH 1;"k"
170 PRINT AT 9,0;sav vizsgalat";TAB 30;FLASH 1;"s"
190 IF INKEY$="m" THEN CLS: GO SUB 300: GO TO 240
200 IF INKEY$="k" THEN CLS: GO SUB 400: GO TO 240
210 IF INKEY$="s" THEN CLS: GO SUB 500: GO TO 240
230 GO TO 190
240 INPUT "folytassuk? i/n";a$
250 IF a$="i" THEN GO TO 145
290 STOP

Jó néhány vizsgálatot csinálhatnánk még, de a meglevő program is alkalmassá tehető akármilyen adatok kirajzolására, elemzésére. Most egy 256 elemű tömbünk van; legyük rugalmasak, engedjük meg a program felhasználójának, hogy maga döntsön az adatok számáról!

5 INPUT "Hany adatot tarolunk?";m
10 DIM g(m)

Ebből azonnal következik, hogy a vizsgáló rutinok ciklusában a felső határ nem 256 lesz, hanem éppen m

320 FOR i=1 TO m STEP 1
430 FOR i=1 TO m STEP 1
540 FOR i=1 TO m STEP 1

Így az m darab adat INPUT-tal kerül be a gép memóriájába.

90 FOR i=1 TO m STEP 1
100 INPUT "ird be az adatot: ";a
105 LET g(i)=a
110 PRINT i,a
120 NEXT i

A 130 és 140 sorok törölhetők.
A megjelenítés külön szubrutin lesz, amiben még arról is gondoskodunk, hogy a túl nagy, vagy túl kicsi számok esetén is jól látható ábrát kapjunk. Az egyszerűség kedvéért induljunk ki abból, hogy a legkisebb előforduló szám nulla. Ha a legnagyobb kisebb, mint 175, akkor minden értéket arányosan növelni kell. Ennek az lesz az eredménye, hogy az ábrafüggőleges irányban megnyúlik. Ha a normális érték 35, akkor a nyújtás mértéke ötszörös (175/35=5).
Mindennek a fordítottja történik, ha a legnagyobb érték 175 felett van. Ilyenkor a szorzószám 1-nél kisebb, így ha a normális érték 350, akkor minden értéket a felére kell venni, a szorzószám 175/350. Elegendő tehát az előforduló számokat 175/max törttel megszorozni, ahol a max a köztük levő legnagyobb érték. Ha a max éppen 175, akkor a szorzó 1 (175/175=1), így minden érték változatlan marad, s ez rendben is van.
Mindez akkor is igaz, ha a szorzó eredményeként nem egész számot kapunk.

ELLENŐRZÉSKÉNT azt kell megvizsgálnunk, hogy a legnagyobb érték a nyújtás vagy összenyomás után sem nagyobb, mint 175. Mivel az előforduló legnagyobb értéket 175-tel szorozzuk, majd önmagával osztjuk, az eredmény éppen 175, tehát még nem léptük túl a határt. Ilyenkor kerekítenünk kell, ezt elvégzi helyettünk maga a PLOT utasítás.
Gondolnunk kell még arra az esetre is, ha a legkisebb érték nem 0. Ilyenkor, ha a minimális érték nagyobb, mint 0, akkor minden számból le kell vonni annyit, hogy a legkisebb éppen 0 legyen.

Ha a legkisebb érték kisebb 0-nál, akkor a kivonás helyett hozzá kell adnunk éppen annyit, hogy a legkisebb szám ezzel 0 legyen.

Vegyük észre, hogy mindkét művelet ugyanazzal az utasítással elvégezhető. Minden számból ki kell vonni az előforduló legkisebb számot, így a minimális érték éppen 0 lesz. (Gondoljunk arra, hogy negatív számot kivonni annyi, mint ugyanakkora nagyságú pozitív számot hozzáadni.)

Ha 256-nál több adatunk van, akkor az összeset egyszerre nem tudjuk a képernyőre vinni. Kérdezzük meg, a felhasználótól hol kezdődjön a megjelenítés.

600 REM megjelenites
602 INPUT "Honnan kezdjuk? i=?";e

a vége az elejéhez képest 255-tel nagyobb:

603 IF e>m THEN PRINT "tul nagy szamot adtal meg": GO TO 602
605 LET v=e+255

Persze csak akkor, ha ezzel nem létük túl a felső határt, mert ha igen, akkor a v értékét le kell csökkentenünk.

608 IF v>m THEN LET v=m

Hívjuk meg a min és max értékét kiszámító szubrutint!

610 GO SUB 300
630 LET k=g(i)-min

A k változóban már olyan értékek vannak, melyek közül a legkisebb 0, ugyanakkor a 610-ben kiszámított max érték is kisebb lett, ezért a max nevű változó értékét is módosítani kell.

615 LET max=max-min

következhet a ciklusban a szorzás és a kirajzolás:

620 FOR i=e TO v STEP 1
630 LET k=g(i)-min
650 LET s=k*175/max
660 PLOT i-1,s
665 DRAW 0,-s
670 NEXT i
680 RETURN

A fentieknek megfelelően módosítani kell a vezérlőprogramot is.

180 PRINT AT 12,0;"rajzolas";TAB 30;FLASH 1;"r"
220 IF INKEY$="r" THEN CLS: GO SUB 600: GO TO 240

Legyen még egy kiíró szubrutinunk is:

700 REM kiiras
710 INPUT "honnan kezdjuk? i=? ";e
720 FOR i=e TO m STEP 1
730 PRINT i,g(i)
740 NEXT i
750 RETURN

A kezelőprogramban a módosítás:

185 PRINT AT 15,0;"kiiras";TAB 30;FLASH 1;"k"
225 IF INKEY$="k" THEN CLS: GO SUB 700: GO TO 240

Vegyük fel a programot Kc1 néven!

1 REM kc1
5 INPUT "Hany adatot tarolunk?";m
10 DIM g(m)
90 FOR i=1 TO m STEP 1
100 INPUT "ird be az adatot: ";a
105 LET g(i)=a
110 PRINT i,a
120 NEXT i
145 CLS
150 PRINT AT 3,0;"minimum es maximum kereses";TAB 30; FLASH 1;"m"
160 PRINT AT 6,0;"szam kereses";TAB 30; FLASH 1;"k"
170 PRINT AT 9,0;"sav vizsgalat";TAB 30;FLASH 1;"s"
180 PRINT AT 12,0;"rajzolas";TAB 30;FLASH 1;"r"
185 PRINT AT 15,0;"kiiras";TAB 30;FLASH 1;"k"
190 IF INKEY$="m" THEN CLS: GO SUB 300: GO TO 240
200 IF INKEY$="k" THEN CLS: GO SUB 400: GO TO 240
210 IF INKEY$="s" THEN CLS: GO SUB 500: GO TO 240
220 IF INKEY$="r" THEN CLS: GO SUB 600: GO TO 240
225 IF INKEY$="k" THEN CLS: GO SUB 700: GO TO 240
230 GO TO 190
240 INPUT "folytassuk? i/n";a$
250 IF a$="i" THEN GO TO 145
290 STOP
300 REM maximum es minimum kereses
302 LET max=g(1)
310 LET min=g(1)
320 FOR i=2 to m STEP 1
330 IF g(i)>max THEN LET max=g(i)
340 IF g(i)<min THEN LET min=g(i)
350 NEXT i
360 PRINT AT 0,0;"min: ";min;"   max: ";max
380 RETURN
400 REM egy szam keresese
410 INPUT "melyik szamot keresed?";x
420 LET sz=0
430 FOR i=1 TO m STEP 1
440 IF g(i)=x THEN LET sz=sz+1
450 NEXT i
460 PRINT x;" ";sz;" alkalommal fordult elo"
470 RETURN
500 REM sav vizsgalat
510 INPUT "a sav also hatara ? ";sa
520 INPUT "a sav felso hatara ? ";sf
530 LET sz=0
540 FOR i=1 TO m STEP 1
550 IF g(i)>=sa AND g(i)<=sf THEN LET sz=sz+1
560 NEXT i
570 PRINT TAB 2;"hatarok";TAB 16;"elofordulas"
580 PRINT TAB 3;sa;"-";sf;TAB 20;sz
590 RETURN
600 REM megjelenites
602 INPUT "Honnan kezdjuk? i=?";e
603 IF e>m THEN PRINT "tul nagy szamot adtal meg": GO TO 602
605 LET v=e+255
608 IF v>m THEN LET v=m
610 GO SUB 300
611 INPUT "kersz nyujtast? i/n";v$
615 LET max=max-min
620 FOR i=e TO v STEP 1
625 IF v$<>"i" THEN LET s=g(i): GO TO 660
630 LET k=g(i)-min
650 LET s=k*167/max
660 PLOT i-e,s
665 DRAW 0,-s
670 NEXT i
680 RETURN
700 REM kiiras
710 INPUT "honnan kezdjuk? i=? ";e
720 FOR i=e TO m STEP 1
730 PRINT i,g(i)
740 NEXT i
750 RETURN

FELADATOK:

  1. Módosítsuk a Kc1 programot, hogy a diagram "szélesebb lépcsőkből" álljon!

  2. Írjuk át a Kc1-et úgy, hogy a kijelzés vízszintes egyenesekkel történjen!

2. nap - Nagyon nagy és nagyon kicsi számok

Az előző napi feladatok megoldásai:

1. Nyilván meg kell adni a lépcső szélességét:

601 INPUT "Milyen szeles legyen egy lepcso? ";w

A 660 és 665 sorok eddig egy egyenest rajzoltak, most ehelyett w darabra van szükség, s természetesen ezt is egy ciklusban rajzoljuk meg. Rajzoljuk fel, hogy fognak kinézni a w szélességű lépcsők!

Láthatóan a ciklus kezdete mindig (i-1)*w, a befejezése (i-1)*w+w-1. Mindez csak akkor érvényes, ha a megjelentetés az első adattal kezdődik (e=1), de ha az i=1 helyére i-e kerül, akkor minden esetben a kép bal szélén kezdődik a rajz.

660 FOR j=(i-e)*w TO (i-e)*w+w-1 STEP 1
663 PLOT j,s
665 DRAW 0,-s
668 NEXT j

Ha a 660-ban a STEP 1-et átírjuk 2-re vagy 3-ra, akkor becsíkozott oszlopokat kapunk.

2. A megoldás pofonegyszerű: meg kell cserélnünk a rajzoló utasítások koordinátáit.

663 PLOT s,j
665 DRAW -s,0

Valamint a rajzoláshoz szükséges számításoknál átcseréljük a két képméretet: 225 és 167 (a felső sort továbbra is meghagyjuk a minimum és maximum érték kiírására).

605 LET v=e+INT(167/w)-1
650 LET s=k*255/max

Már biztosan mindenki gondolt arra, hogy milyen jó lenne NYERNI EGY ÖTÖST A LOTTÓN! De ez eddig csak nagyon kevés embernek sikerült. Vajon mennyi esélyünk van arra, hogy egy szelvénnyel telitalálatot érjünk el?
Az esélyeket aránnyal szoktuk megadni: például mi az esélye annak, hogy ha feldobunk egy forintost, akkor a számjegyek kerüljenek felülre? A válasz 1.2 (úgy mondjuk egy a kettőhöz), mert az összes lehetséges eset 2, mivel az érmének két oldala van (bár nagyon ritkán előfordul, hogy a harmadik oldalára, azaz az élére esik, de ettől most tekintsünk el - azt se vegyük figyelembe, hogy esetleg valaki elkapja a levegőben a pénzt, és elszalad vele).
Az általunk kiválasztott, számunkra kedvező esetek száma 1, tehát az esélyt úgy kapjuk meg, ha a kiválasztott (kedvező) esetek számát elosztjuk az összes lehetséges eset számával. Ez mind nagyon szép, de mennyi a lottóhúzás esetében a lehetséges értékek száma, azaz hányféle módon tudunk 90 különböző számból 5-öt kivenni? Azt sejtjük, hogy nagyon sok. Érdemes elkezdeni rendezve leírni őket. Például így:

1 2 3 4 5
1 2 3 4 6
...
1 2 3 4 90
1 2 3 5 6
...
1 2 3 5 90
...

Ennyi elég is lesz. Vettük ez első 4 helyre a 4 legkisebb számot, majd hozzátettük egyenként az összes többit ötödiknek (5-től 90-ig). Így minden olyan, kombinációt megcsináltunk, amelyik 1,2,3,4-gyel kezdődik. Ezután az 1,2,3,4 sor végéről a 4-et átcseréljük 5-re és ismét hozzáraktuk az összes lehetséges többit (most már csak 6-90). Ha eljutnánk az 1,2,3,89,90 sorozathoz, ekkor a harmadik helyen álló számot növelnénk eggyel, s folytatnánk a negyedikés ötödik helyen levők pörgetését.
Ugye észrevehető, hogy öt darab egymásba ágyazott ciklust kellene készítenünk, a legbelsőhöz tartozik az ötödik szám, a következőé a negyedik, és így tovább, a legkülső ciklus az első szám értékeit tartja nyilván. Az egészet egy kicsit bonyolultabbá teszi az a tény, hogy az egyes ciklusok amellett, hogy egymásba vannak skatulyázva, még nem is azonos kezdő és végértékűek. De hát ilyen az élet - vagyis a lottózás. Ha mindegyiket 1-től 90-ig futtatnánk, akkor lenne olyan kombináció is, mint

1, 1, 1, 1, 1

vagy

23, 23, 24, 86, 86

Szóval azonos számok is előfordulhatnának, márpedig a lottóhúzásnál ilyen nem lehetséges.
Ha az első négy szám

1, 2, 8, 39

akkor a legbelső ciklust 40-től 90-ig futtatjuk.
Ha az első három szám

1, 8, 52

Akkor a negyedik szám ciklusát 53-tól 89-ig, az ötödikét 54-től 90-ig futtatjuk. A negyedik szám maximum 89 lehet, mert különben az ötödiknek nem maradna már érvényes érték. Ugyanígy a harmadik szám legföljebb 88, a második 87, az első 86 lehet. A ciklusok kezdőértéke a fentiekből következően mindig eggyel nagyobb, mint az az érték, ahol az őt megelőző ciklus éppen tart.

20 FOR i=1 TO 86 STEP 1
30 FOR j=i+1 TO 87 STEP 1
40 FOR k=j+1 TO 88 STEP 1
50 FOR l=k+1 TO 89 STEP 1
60 FOR m=l+1 TO 90 STEP 1
100 NEXT m
110 NEXT l
120 NEXT k
130 NEXT j
140 NEXT i

Ezzel a ciklusszervezés kész, írjunk még bele egy számlálót, amelyben a már lefutott kombinációk darabszámát tartjuk nyilván. Ez a számolás a legbelső cikluson belülre kerül.

70 LET sz=sz+1

A változónak kezdeti értéket is kell adnunk

10 LET sz=0

Ha végig lefutott a program, akkor az sz változóban levő érték megadja az általunk keresett számot.
Jó lenne, ha futás közben látnánk, hogy hol tart a program, ezért írassuk ki az i, j, k, l, m és az sz értékét. Nem lenne célszerű az összes változót egy utasításba bezsúfolva kiíratni, ugyanis nem mindig változik mindegyik. Ezért csak azt írjuk ki, amelyik éppen módosult.

25 PRINT AT 0,0;i
35 PRINT AT 0,4;j
45 PRINT AT 0,8;k
55 PRINT AT 0,12;l
85 PRINT AT 0,16;m; AT 0,20;sz

Figyeljük meg például az 1. ciklust.

50 FOR l=k+1 TO 89 STEP 1
55 PRINT AT 0,12;l
...
110 NEXT l

A ciklus megkezdése után azonnal a képre kerül az l értéke, de ezt követően csak akkor, ha a NEXT l-et végrehajtva visszatér a gép a FOR után a következő utasításhoz, jelen esetben az 55-höz. Ha egy ciklusváltozó értékét óhajtjuk a képernyőre írni, célszerű a PRINT-et mindig közvetlenül a FOR után tenni.
Egy perc alatt (nem stopperrel mérve) mintegy 1620 változaton ment végig, de még midíg csak

1, 2, 3, 25, 49-nél

tart, bizony még nagyon messze van a vége, a

86, 87, 88, 89, 90

számsorozat.
Föl kellene gyorsítanunk a programot. Nagyjából több mint négyszeresére nő a sebesség, ha kivesszük a PRINT utasításokat, de még ez is kevés, most körülbelül 3 órányi futás után is csak

1, 15, 27, 50, 90-nél

Tartunk, ez eddig összesen 1185645 féle kombinációt jelent. Kapaszkodjunk meg: A TELJES FUTÁSI IDŐ 5 NAP lenne. Ez rettenetesen sok, próbáljuk meg más módszert keresni.
Képzeljünk magunk elé egy lottószelvényt! A kitöltése úgy történik, hogy 5 számot beikszelünk rajta. Kezdjük el, legalábbis gondolatban. Először a 90 szám közül bármelyiket választhatjuk, másodszorra már csak 89 lehetőségünk van, mert az elsőként választott számot már nem jelölhetjük meg. Ez eddig összesen 90*89 lehetőség. Az ábra rögtön elárulja, hogy jött ki ez a sorozat.

A harmadik szám bejelölésekor már csak 88 üres hely közül választhatunk, a negyediknél 87, az ötödiknél 86 áll rendelkezésünkre. Ez összesen 90*89*88*87*86 különböző lehetőséget jelent. Ilyen egyszerű lenne? Talán igen, talán nem. Mindenesetre számoljuk ki, persze a számítógéppel!

PRINT 90*89*88*87*86

Semmi pánik! Nem romlott el semmi!
A képernyőn

5.2739122E+9

látható. Ez nem más, mint az 5273912200 úgynevezett exponenciális alakja (erre utal az E betű). Az exponens szó kitevőt jelent; akik ismerik a hatványozás műveletét, azok tudják, hogy miről van szó; akik nem, azoknak eláruljuk, hogy nem nagy dolog. A hatványozás nem más, mint a szorzás ismétlése:

10^3= 10*10*10

Úgy kell kimondani, hogy tíz a harmadikon, jelentése a fenti sorból kiolvasható: a 10-et háromszor kell szorzónak venni. Példánkban

a 10 a hatványalap
a 3 a hatványkitevő.

Papíron a hatványkitevőt a hatványalap jobb felső sarka fölé írjuk.
A szorzás eredménye egyébként 1000.
Mire jó ez, kérdezhetnénk. Olyan számokat, amelyekben sok a nulla, kényelmesebb így leírni.

  hatvány alak
10
10^1
100
10^2
1000
10^3
10000
10^4
100000
10^5
1000000
10^6
10000000
10^7
...
 

Vegyük észre, hogy a 10 hatványozáskor a kitevő értéke megegyezik az egyes után írandó nullák számával. Mindez nemcsak egyessel kezdődő számokra érvényes.

7*10^6 = 7000000 (hétmillió)

vagy például

123*10^6 = 123000000

A számítógép a hatványozás jeleként a felfelé mutató nyilat (^) használja. Elérése: SMYBOL SHIFT + H.
Próbáljuk ki!

PRINT 123*10^6

A hatványozás nagyobb prioritású (elsőbbséget élvező művelet a szorzásnál ezért a gép először ezt végzi el, s csak utána a szorzást. Az eredmény:

1.23E+8

A +8 most nem ezt jelenti, hogy az 1.23 után 8 nullát kell írni, hiszen ha egy tizedes tört végére nullákat írunk, attól az értéke változatlan marad. A fenti számszörnyeteget tehát úgy lehet emberi nyelvre átírni, hogy a tizedespontot annyival visszük jobbra, amilyen szám áll az E után; ha nincs elegendő számjegy, akkor az üres helyeket nullákkal pótoljuk.

Mielőtt visszatérnénk a lottószámokhoz, még valami: aki arra gondolt, hogy a gép az E betű után kiírt egy + jelet, akkor az nyilván azért tette, mert ott - is állhat, az nem tévedett (ismét kijár a vállveregetés), A - jel negatív hatványkitevőt jelöl: ilyenkor a tizedespontot balra kell vinni.
Mindezekből következik, hogy a 10 negatív kitevőjű hatvánnyal egyszerűen leírhatók a nagyon kicsi számok is. Például:

1/10^6 = 0.000001

egy milliomod.

PRINT 1/1000000
1E-6

Megfigyelhetjük, hogy a 0 egészt is beszámítva éppen 6 darab nulla van a tizedestörtünkben.

Ideje visszatérnünk a lottószámokhoz: ha már ennyit beszéltünk róluk, legalább nyerjünk valamit a dolgon. Ott tartottunk, hogy az összes lehetséges változat darabszámát a

PRINT 90*89*88*87*86

szorzat adja.

5.2739122E+9

ami visszaírva a szokásos alakra

5273912200

ez több, mint 5 milliárd.
Próbáljuk meg ezt valahogy ellenőrizni! Persze 90 számra - mint tapasztaltuk - rendkívül hosszú időbe telne, de 6-ra könnyen megtehetjük. Módszerünk szerint először 6 közül választhatunk, aztán 5, 4, 3, 2 áll rendelkezésre. Így az összes lehetőség:

PRINT 6*5*4*3*2

720-at kapunk, ez kicsit soknak tűnik.
Írjuk csak le, ha csupán 6 számból (az egyszerűség kedvéért legyen ez 1, 2, 3, 4, 5, 6) választhatnánk ki öt darabot, milyen lehetőségeink lennének!

1, 2, 3, 4, 5
1, 2, 3, 4, 6
1, 2, 3, 5, 6
1, 2, 4, 5, 6
1, 3, 4, 5, 6
2, 3, 4, 5, 6

Ez összesen csak 6 eset, akárhogy is nézzük is, nem tudunk újabbat írni. Ezek szerint el kell vetnünk ezt a nagyon egyszerűnek látszó megoldást? Nem eszik olyan forrón a kását! Gondoljuk újra végig, hogyan is csináltuk! Először 6 szám állt rendelkezésünkre. Tegyük fel, hogy kiválasztottuk a 2-t. A maradék 5-ből az 1-et, aztán sorrendben a 3, 4, 5-öt.
Pillantsunk rá az így kitöltött lottószelvényre!

Innen bizony már nem derül ki, hogy az ikszelés sorrendje 2,1,3,4,5 volt. A végeredmény ugyanaz, mintha a kiválasztás sorrendje

1, 2, 3, 4, 5
3, 1, 2, 4, 5
5, 3, 4, 2, 1 stb.

lett volna.
S ez így van a valódi lottóhúzásnál is. A kihúzott számokat az egyszerűség kedvéért mindig nagyság szerint mondja be a rádió, írja meg az újság; a kihúzási sorrend nem fontos.
Ha valahogy kiszámoljuk, hogy 5 különböző számot hányféle módon lehet sorba rakni, máris sínen vagyunk. Kezdjük itt is a legegyszerűbb esettel: 2 szám esetében kétféle sorrend lehetséges:

1, 2
2, 1

Ha jön egy harmadik szám is, az 3 helyre kerülhet: az első szám elé, a két szám közé és a második szám után.

1, 2

3, 1, 2

1, 3, 2

1, 2, 3

s ugyanígy:

2, 1

3, 2, 1

2, 3, 1

2, 1, 3

Ez összesen 2*3=6 lehetséges sorrend. A negyedik szám 4 helyre kerülhet: az első elé, az első és a második közé, a második és a harmadik közé és a harmadik után.

3, 2, 1

4, 3, 1, 2

3, 4, 1, 2

3, 1, 4, 2

3, 1, 2, 4

A többi is ehhez hasonlóan alakul. Ezzel összesen már 2*3*4=24 sorrend lehetséges. Ha 5 számunk van, akkor az nyilvánvalóan 2*3*4*5=120 különböző sorrendben helyezkedhet el. Természetesen ugyanez a helyzet, ha bármilyen más 5 különböző számmal dolgozunk. Ha a fent kapott eredményt, a 720-at elosztjuk az összes lehetséges sorrend darabszámával (120-al), akkor 6-ot kapunk, s éppen annyi módon tudtunk 6 számból 5-öt kiválasztani. Így a 90 számra kiszámolt sorozatot is el kell osztani 120-al.

PRINT 90*89*88*87*86/120

s ez immár a végleges eredmény:

43949268

A teljesség kedvéért megjegyezzük, hogy nem precíz matematikai bizonyítást végeztünk, hiszen egyszerűen azt mondtuk, hogy ha 6 számnál jó a számítás, akkor 90-re is igaz. Akit a téma részletesebben érdekel, az a matematikakönyvekben a kombinatorikáról és a valószínűségszámításról szóló fejezeteket keresse meg.
Ha emlékszünk, ezt a sok számítást azért végeztük, hogy megállapítsuk, mennyi az esélyünk az ötös találatra, ha egy szelvénnyel játszunk. A válaszunk:

1:43949268

Hát igen: ez nem valami sok.
Ha 2 szelvénnyel játszanánk, akkor már kétszer ennyi, azaz:

2:43949268

A fentiekhez hasonlómódszerrel kiszámítható, hogy mennyi az esélyünk egy négyes, hármas vagy kettes találatra, de a számítások helyett izgalmasabb, ha JÁTSZUNK A SZÁMÍTÓGÉPPEL, azaz szimuláljuk a lottóhúzást!
Öt darab 1 és 90 közé eső számot kell előállítanunk.

10 DIM l(5)
100 FOR i=1 TO 5
110 LET r=INT (RND*90)+1
130 LET l(i)=r
140 NEXT i

Ebben idáig nincs semmi újdonság, csakhogy előfordulhat olyan eset, hogy az 5 szám között akad 2 egyforma, ezt pedig el kell kerülnünk. A 110-130-as sorok közé tegyünk be egy ellenőrző programocskát, amely kiszűri az esetleges azonosságot. Elegendő, ha a 110-benelőállított véletlen számot összehasonlítjuk a korábban kihúzottakkal, melyek már az l nevű tömbben vannak.

115 FOR j=1 TO i
118 IF r=l(j) THEN GO TO 110
120 NEXT j

Nézzük meg, hogy mi a helyzet az első szám húzásakor (i=1)! Ekkor a ciklus kezdeti és végértéke ugyanaz a szám, a FOR és a NEXT közötti utasításokat egyszer hajtja végre a gép. Az l tömb ilyenkor még üres, minden eleme 0, ezért a 118-ban elvégzett vizsgálat fölösleges. Ebben nincs semmi különös, hiszen az elsőként kihúzott szám nem lehet azonos a korábbiak valamelyikével, mivel még nincs korábbi. Ha ezt el akarjuk kerülni, akkor szúrjuk be a

112 IF i=1 THEN GO TO 130

sort, ezzel az első kihúzott szám automatikusan bekerül a tömb első elemébe.

Kövessük tovább a program futását!
i=3 esetében 2 számunk már biztosan benne van a tömbben. A harmadik helyen viszont még 0 van, tehát ezzel már fölösleges összehasonlítani a kihúzott véletlen számot. Így a 115-ös sor is módosul:

115 FOR j=1 TO i-1

Ezzel a sorral éppen az i=1 értéknél lenne a baj, de ezt már kiszűrtük.
A kiíratás már egyzserű.

200 FOR i=1 TO 5
210 PRINT l(i)
220 NEXT i

Minden rendben, csak egy kis szépséghibája van a programnak, a kihúzott számokat nem szedi nagyság szerint sorba. (Az előrelátóbbak sejtik, hogy ez lesz az egyik feladat.)
Vegyük fel a programot Kc22 néven!

10 DIM l(5)
100 FOR i=1 TO 5
110 LET r=INT (RND*90)+1
112 IF i=1 THEN GO TO 130
115 FOR j=1 TO i-1
118 IF r=l(j) THEN GO TO 110
120 NEXT j
130 LET l(i)=r
140 NEXT i

200 FOR i=1 TO 5
210 PRINT l(i)
220 NEXT i

FELADATOK:

  1. Vannak országok, ahol a lottózás eltérő a mienktől: 49 számból húznak ki 6-ot. Készítsünk programot, amely tetszőleges lottószisztémában kiszámítja és ellenőrzi a telitalálat elérésének esélyét egy szelvénnyel!
    A kiszámítás az eddig használt szorzattal történhet, az ellenőrzés pedig az összes lehetséges változat egyenkénti számba vételével.

  2. Építsük be a Kc22-be a sorbarendező programrészt!

3. nap - Lottózás a számítógép segítségével

A megoldások:

1. Reméljük, hogy sok gondot nem okozott, csupán a 90-es szám helyére kellett egy változót tenni (legyen ez most n).

5 FOR n=6 TO 20
10 LET sz=0
20 FOR i=1 TO n-4 STEP 1
30 FOR j=i+1 TO n-3 STEP 1
40 FOR k=j+1 TO n-2 STEP 1
50 FOR l=k+1 TO n-1 STEP 1
60 FOR m=l+1 TO n STEP 1
70 LET sz=sz+1
100 NEXT m
110 NEXT l
120 NEXT k
130 NEXT j
140 NEXT i
150 LET q=n*(n-1)*(n-2)*(n-3)*(n-4)/120
160 IF q=sz THEN PRINT n,q:GO TO 180
170 PRINT "rossz a szamitas"
180 NEXT n

Most a 6-tól 20-ig terjedő számokra kapjuk meg az összes lehetséges változat darabszámát.
A 160-ban ellenőrizzük, hogy a kétféle számítási mód azonos-e; eltérő eredmény estén a "rossz a szamitas" szöveget látnánk a képernyőn.

A 2. feladat már nehezebb volt. Akinek ez sikerült önállóan megoldania, az igazán elégedett lehet magával, de aki most nem járt sikerrel, de dobja sutba a számítógépet azzal, hogy neki semmi tehetsége nincs az egészhez.
A sorbarendezés látszólag nem bonyolult feladat.

21, 86, 17, 14, 52

Rápillantunk, s máris mondjuk, hogy

14, 17, 21, 52, 86

A nagyság szerinti sorrend. Persze a rápillantás után az agyunk szélsebesen kezd dolgozni. Szinte észre sem vesszük a folyamatot, ahogy szemünk megkeresi a legnagyobb számot, a sor végére teszi, majd mindezt folytatja a maradék számokkal, amíg elő nem áll a helyes sorrend. Képzeljük el, hogy ha 1000 vagy még több számmal kellene dolgoznunk, mennyivel nehezebben menne a dolog. Ezzel szemben A SZÁMÍTÓGÉP NEM FÁRAD BELE A MUNKÁBA! Akármennyi számot is kell sorbarendeznie, legfeljebb hosszú ideig tart neki. Nincs más dolgunk, mint pontosan megfogalmaznunk a gép számára, hogyan kell a sorbaállítást csinálnia.
Követetnénk azt a módszert, amit az előbb használtunk, eszerint:

1. Keresd meg a legnagyobb számot, azt vidd a sor végére, úgy, hogy a kiválasztott számtól jobbra levőket egy hellyel balra tolod, valahogy így:

21, 86, 17, 14, 52
21, 17, 14, 52, 86

Ezzel a legnagyobb szám a helyére került. Ezután tekintsd rövidebbnek rövidebbnek a számsorodat, és ismételd a műveletet, amíg 1 szabad marad, ez már biztosan a legkisebb szám.
A módszer nem rossz, csak gondoljunk arra, hogy a gép nem képes egyszerűen rápillantani az összes számra, csupán kettőt tud megvizsgálni. Hasonlítsuk össze páronként a számokat, ha a bal oldali nagyobb a jobb oldalinál, akkor megcseréljük őket, különben mindkettő marad a helyén. Ezután eggyel tovább (azaz jobbra) lépünk és folytatjuk az összehasonlítást:

21, 86, 17, 14, 52

nincs csere

21, 86, 17, 14, 52

van csere

21, 17, 86, 14, 52

van csere

21, 17, 14, 86, 52

van csere

21, 17, 14, 52, 86

Ezzel egyszer a sor végére értünk, a legnagyobb szám a helyére került. Most már az eggyel csökkentett számsorral kezdjük elölről a vizsgálódást:

21, 17, 14, 52

van csere

17, 21, 14, 52

van csere

17, 14, 21, 52

nincs csere.

Ezzel másodszor is a sor végére jutottunk, már a két legnagyobb szám a helyén van, a maradék hármat kell még elrendeznünk.

17, 14, 21

van csere

14, 17, 21

nincs csere

Csak két számunk maradt, de őket is meg kell vizsgálnunk:

14, 17

nincs csere

Készen is vagyunk:

14, 17, 21, 52, 86

Már csak a programot kell megírnunk, ami mindezt elvégzi. Ha még nem töltöttük volna be a kc22-t, most tegyük meg!
Az első menetben az utolsó (5.) számot is belevettük a vizsgálatokba,a végén már csak az első kettőt, ezért egy ciklus azt fogja számontartani, hogy milyen hosszú számsoron kell végigmenni.

150 FOR k=5 TO 2 STEP -1
195 NEXT k

Ennek belsejében egy másik ciklus gondoskodik az egymás utáni összehasonlításokról.

160 FOR i=2 TO k STEP 1
170 IF l(i)>k(i-1) THEN GO TO 190
175 LET t=l(i)
180 LET l(i)=l(i-1)
185 LET l(i-1)=t
190 NEXT i

Az összehasonlításnál eddig jobb oldalnak nevezett szám az l tömb i-edik eleme, a bal oldali pedig az (i-1)-edik. Ezért kell az i ciklust 2-től indítani, mert így az első ráfutáskor a másodikat veti össze az elsővel (2-1=1), majd a harmadikat a másodikkal, és így tovább, a végén az ötödiket a negyedikkel.
A 170-es sorban megvizsgáljuk, szükség van-e cserére. Ha a vizsgált szám (i-edik) nagyobb, mint az őt megelőző, akkor nincs mit tennünk, vehetjük a következő párt. Ellenkező esetben az l tömb i-edik és (i-1)-edik elemét fel kell cserélnünk. Sajnos a SPECTRUM nem ismer olyan utasítást, ami két változóértékét felcserélné, ezért kénytelenek vagyunk mi megtanítani őt erre az apróságra. A cseréhez kell egy ideiglenes tároló, legyen ez a t. A csere folyamata jól követhető kis rajzunkon is:

A próbához véletlen számok helyett használjuk a korábban vizsgált öt számot (21, 86, 17, 14, 52). A 110-et tegyük félre egy REM beszúrásával, s helyette INPUT vagy READ DATA páros szerepeljen.

110 READ r
500 DATA 21,86,17,14,52

S a végeredmény egészen jónak tűnik, mondhatni hibátlannak, no de azért kövessük végig a folyamatot! Írassuk ki az 5 számot minden menet végén! Csináljunk szubrutint a kiíró programrészből!

230 RETURN

és hívjuk meg az i ciklus befejezése után

192 GO SUB 200

Csakhogy így a számok egymás alá kerülnek. Ezen könnyű változtatni:

210 PRINT l(i);" ";

De így meg az új számsorozat kiírása nem kezdődik új sorban. Persze ez is megoldható:

225 PRINT

Ennek az utasításnak csupán annyi a szerepe, hogy feloldja a 210-es sor végén levő pontosvessző hatását. Csak 4 számsor kiírását várnánk, hiszen a k ciklus miatt 4-szer kerül sor a kiírás meghívására, mégis 5 sornyit láthatunk a képen. A képernyő alján a hibaüzenet útbaigazít:

7 RETURN without GO SUB 230:1

Igaz, a kiírás nemcsak akkor került sorra, amikor meghívtuk, mivel a program vége belefolyik a szubrutinba. Ezt egyszerűen megakadályozhatjuk:

199 STOP

Még inkább láthatóvá tehetjük a folyamatot, ha minden összehasonlítás után kiírjuk az 5 számot. Ehhez az i ciklus belsejébe kell tennünk a GO SUB 200-at, írjuk közvetlenül a NEXT elé.

190 GO SUB 200:NEXT i

és a 192-t töröljük.
Az eredmény

21, 86, 17, 14, 52

Négyszer szerepel egymás alá írva, mintha egetlen sorbarendező lépés sem történt volna. De hiszen az imént még minden rendben működött, s nem tettünk mást, mint áthelyeztük a kiírás meghívását. Ez így igaz, tehát a hiba is innen kell hogy származzák. A furcsa csak az, hogy a sorbaállítás működött, a kiírás is, ha csak minden menet végén hívtuk meg.
Mivel mist is csak 4 számsor láthatóa képen, 4-szer került sor a GO SUB 200-ra, pedig most a belső ciklusban van. Ez azt jelenti, hogy a belső ciklus (i) alkalmanként csak egyszer fut le, más szóval csak egy összehasonlítás történik, holott először 4, aztán 3, majd 2, végül egynek kellene lennie. Kövessük a program futását lépésről lépésre! A külső ciklus k=5 értékkel indul, a belső i=2-vel, itt az i-nek 5-ig kellene mennie. A 170-ben kiderül, hogy l(2)>l(1) (mert 86>21), ugrás 190-re, ahol a kiírás meghívása történik. Bizony, bizony! Itt van a rejtély nyitja, a kiíró szubrutin átírja az i értékét. A visszatéréskor az i=6, így a NEXT i-hez érve a gép úgy látja, hogy az i értéke túllépte a felső határt, ezzel a ciklus lefutott és a

195 NEXT k

végrehajtásával kezdődik az új menet. Emiatt a kiíró szubrutinban nem használhatjuk az i-t ciklusváltozónak.

200 FOR j=1 TO 5
210 PRINT l(j); ";
220 NEXT j

Így már mindjárt más.

21 86 17 14 52
21 17 86 14 52
21 17 14 86 52
21 17 14 52 86
17 21 14 52 86
17 14 21 52 86
17 14 21 52 86
14 17 21 52 86
14 17 21 52 86
14 17 21 52 86

Kár, hogy összefolynak az egyes menetek. Válasszuk el őket valahogy egymástól!

155 PRINT

Ez az üres PRINT minden menet elején egy üres sort csinál, olyan ez, mint az írógépeknél a soremelés billentyű. Most már menetenként tagolva látjuk a folyamatot.

21 86 17 14 52
21 17 86 14 52
21 17 14 86 52
21 17 14 52 86

17 21 14 52 86
17 14 21 52 86
17 14 21 52 86

14 17 21 52 86
14 17 21 52 86
14 17 21 52 86

Némi ügyeskedéssel a menet számát is kiírathatjuk.

k
menet száma

5
4
3
2

1
2
3
4

155 PRINT 6-k; menet"

Minden pontosan úgy történik, ahogy ezt az előzetes elképzeléseink alapján vártunk, így próbálkozhatunk más számsorral is.

21, 20, 46, 76, 89

Az első menet után kialakul a végső sorrend, a további 3 menet felesleges. No itt még nem nagy tragédia, de 1000 szám esetén 500 felesleges menet már jelentős időveszteség.
SOSE DOLGOZTASSUK A GÉPET FELESLEGESEN! Vegye észre a program, ha korábban létrejön a helyes sorrend. Megtehetnénk, hogy minden menet után megnézzük, készen vagyunk-e, de ez rengeteg felesleges vizsgálatot jelentene. Különösen akkor, amikor az összes menetnek végig kell futnia. Mikor is dolgozik feleslegesen a program? Ha egy menet során egyetlen egyszer sincs szükség cserére, mivel minden szám már a helyén van. Ellenőrizzük minden menet után, hogy a program "betette-e a lábát" a változócserélő részbe (175-185). Az indiánok ilyen esetben lábnyomokat keresnének, a nyomozókutyák szimatolnának, nekünk nem marad más, mint egy változó értékének a figyelése.
Ezt a változót (legyen ez f) minden menet előtt 0-ra állítjuk.

153 LET f=0

A cserélő részben f értékét átírjuk:

178 LET f=1

Ha a menet befejeztével az f értéke még mindig 0, az azt jelenti, hogy nem volt csere az egész menet folyamán, tehát a sorbarendezés befejeződött.

193 IF f=0 THEN GO TO 199

Ha most kipróbáljuk a

21 20 46 76 99

Számsort, akkor láthatjuk, hogy 2 menet futott végig;már az első után minden szám a helyén volt, de ennek megállapításához kellett még a következő menet. Egy menet még így is fölösleges, de ha a fentebb említett példánál maradunk, ahol 1000 szám 500 menettel volt elrendezhető, a plusz egy menettel együtt is megúsztunk 499-et. Igazán megéri.
Ezek után a READ helyére tegyük vissza a véletlenszám előállítást, azaz töröljük a 111-et, és a DATA-t, valamint vegyük ki a REM-et a 110-es elejéről.

Tegyünk néhány próbát!
Mit láthatjuk, nincs szükség mindig mind a négy menetre. Ezekben az esetekben az a menet az utolsó, ahol már nem történt egyetlen csere sem. Ezek után a sorbaállítást már nem kell lépésről lépésre követnünk. Töröljük a 155-ös sort, a 190-ből vegyük ki a kiíró szubrutin meghívását!

190 NEXT i

S hogy a későbbiekben könnyebb legyen módosítanunk, írjuk át szubrutinosra a meglevő részeket!

145 RETURN
199 RETURN

Ez utóbbival a

199 STOP

is eltűnt.
100-145 5 különböző 1-90 közé eső véletlenszám előállítása
200-230 kiírás

Az ehhez tartozó vezérlőprogram:

20 GO SUB 100
30 GO SUB 150
40 GO SUB 200
99 STOP

Így a gép vidáman húzogatja a lottószámokat, már csak a szelvényeket kell kitöltenünk. Kezdjük az egyszerűség kedvéért 1 szelvénnyel!

300 REM lottoszelveny kitoltese

A könnyebb kezelhetőség kedvéért az 5 számot tároljuk egy tömbben!

310 DIM f(5)
320 FOR i=1 TO 5
330 INPUT f(i)
340 PRINT f(i);" ";
350 NEXT i
360 RETURN

Még hátra van a szelvények kiétékelése:

400 REM kiertekeles
410 LET t=0

A t változóba kerül az elért találat.
Az értékelés abból áll, hogy a szelvény számait (f tömb) egyenként összehasonlítjuk a kihúzott számokkal (l tömb). Ehhez két egymásba ágyazott ciklusra van szükség.

420 FOR i=1 TO 5
430 FOR j=1 TO 5
440 IF f(i)=l(j) THEN LET t=t+1
450 NEXT j
460 NEXT i
470 RETURN

Végezetül a vezérlőprogram:

15 GO SUB 300
20 GO SUB 100
30 GO SUB 150
35 GO SUB 200
40 GO SUB 400
50 PRINT TAB 2;"a kihuzott szamok:"
55 GO SUB 200
60 PRINT TAB 10;t;" talalat"

Mentsük ki a programot kc32 néven!

1 REM kc32
10 DIM l(5)
15 GO SUB 300
20 GO SUB 100
30 GO SUB 150
35 GO SUB 200
40 GO SUB 400
50 PRINT TAB 2;"a kihuzott szamok:"
55 GO SUB 200
60 PRINT TAB 10;t;" talalat"
99 STOP
100 FOR i=1 TO 5
110 LET r=INT (RND*90)+1
112 IF i=1 THEN GO TO 130
115 FOR j=1 TO i-1
118 IF r=l(j) THEN GO TO 110
120 NEXT j
130 LET l(i)=r
140 NEXT i
145 RETURN
150 FOR k=5 TO 2 STEP -1
153 LET f=0
160 FOR i=2 TO k STEP 1
170 IF l(i)>l(i-1) THEN GO TO 190
175 LET t=l(i)
178 LET f=1
180 LET l(i)=l(i-1)
185 LET l(i-1)=t
190 NEXT i
193 IF f=0 THEN GO TO 199
195 NEXT k
199 RETURN
200 FOR j=1 TO 5 STEP 1
210 PRINT l(j);" ";
220 NEXT j
225 PRINT
230 RETURN
300 REM lottoszelveny kitoltese
310 DIM f(5)
320 FOR i=1 TO 5
330 INPUT f(i)
340 PRINT f(i);" ";
350 NEXT i
360 RETURN
400 REM kiertekeles
410 LET t=0
420 FOR i=1 TO 5 STEP 1
430 FOR j=1 TO 5 STEP 1
440 IF f(i)=l(j) THEN LET t=t+1
450 NEXT j
460 NEXT i
470 RETURN

FELADATOK:

Tegyük intelligensé a szelvénykitöltő programrészt.

  1. Zárjuk ki
    a. az 1-nél kisebb,
    b. a 90-nél nagyobb,
    c. a nem egész
    számok beadását!

  2. a. Akadályozzuk meg egy szám többszöri beírását!
    b. Állítsuk nagyság szerinti sorrendbe a felhasználó által beírt számokat!

4. nap - Több ember, több szelvénnyel, több hétig

Az 1. feladat a. részének megoldása mindössze egy sor, amit a

330 INPUT f(i)

sor után kell elhelyeznünk. 3 esetet kell kizárnunk:

Az első kettő önmagáért beszél, talán a harmadik igényel egy pici magyarázatot. Mint emlékszünk, az INT lefelé kerekíti a számokat, más szóval a törtből egész számot csinál, úgy, hogy a törtrészt elhagyja. Minden egész szám egész része megegyezik önmagával, tört számok esetében az egész rész nyilván kisebb, mint maga a tört.
Ha a fenti feltételek közül bármelyik teljesül (VAGY az egyik, VAGY a másik), akkor új számot kell kérni.

332 IF f(i)<1 OR f(i)>90 OR f(i)<>INT f(i) THEN GO TO 330

Eddig csak két feltételt kapcsoltunk össze AND-del vagy OR-ral, de mint látjuk, ez többel is megtehető.

2/a. Az azonosság kizárása hasonlóan történik, mint a 112-130 sorokban.

333 IF i=1 THEN GO TO 340
334 FOR j=1 TO i-1 STEP 1
335 IF f(i)=f(j) THEN GO TO 330
336 NEXT j

A 2/b. eset talán még egyszerűbb. Sorbarendező szubrutinunk már van (150), csakhogy az az l tömb elemeivel dolgozik. Nincs más dolgunk, az f tömböt át kell másolnunk az l tömbbe, meghívni a 150-es szubrutint, majd a már rendberakott l tömböt visszarakni az f-be. Mindezt megtehetjük, hiszen az l tömböt csak később, a lottószámok kihúzásánál használjuk.

354 FOR j=1 TO 5 STEP 1
357 LET l(j)=f(j)
360 NEXT j
370 GO SUB 150
375 FOR j=1 TO 5 STEP 1
378 LET f(j)=l(j)
380 NEXT j
390 RETURN

A próbához beiktathatjuk a

385 GO SUB 200-at,

amit utólag - ha látjuk, hogy minden rendben - ki is törölhetünk. S végül a 315-ben ne kérjük sorrendben a számok beírását.

315 PRINT "ird be a szamokat!"

LEGYÜNK MERÉSZEBBEK! Játszunk több szelvénnyel!
Ehhez a szelvénykitöltő programot és a kiértékelő programrészt kell módosítanunk. Ha papírra írnánk a lottószámainkat, akkor a könnyebb áttekinthetőség kedvéért ötösével csoportosíthatnánk őket, pl.

13, 27, 39, 57, 88
 4,  8, 52, 53, 90
 1, 19, 22, 28, 67

Jó lenne, ha a gép is tudná ilyenformán tárolni őket. Az eddig alkalmazott tömbökben "egymás után" voltak elhelyezve a számok, nem így táblázatosan. Persze az sem lenne nagy gond, hiszen mondjuk a 11. elemről rövid számolás után kideríthető lenne, hogy a táblázatunk harmadik sorának első számát tárolja. De felesleges a számolgatás, mert léteznek 2 dimenziós tömbök is. Mi az, hogy 2 dimenziós?
Az eddig használtak 1 dimenziósak voltak. Az egész nem nagy ördöngősség. Vegyük a fenti 15 számot!

13, 27, 39, 57, 88, 4, 8, 52, 53, 90, 1, 19, 22, 28, 67

Ezt a számot egy 15 elemű tömb képes tárolni, amit a

DIM l(15)

utasítással hozhatunk létre. Itt mindig egy szám elegendő egy adott tömbelem kiválasztásához. Ha ezt a 15 számot három sorban óhajtjuk elrendezni, akkor ezt a

DIM f(3,5)

utasítással tehetjük meg. Jelen esetben az f tömb két dimenziós (3 sorból és 5 oszlopból áll), ami csupán annyit jelent, hogy az adott eleme előhívásához két számot kell megadnunk. Ez a kis többletmunka megtérül azzal, hogy a programunk áttekinthetőbb lesz.
Az azonosítás a következők szerint történik:

 
1. oszlop
2. oszlop
3. oszlop
4. oszlop
5. oszlop
1. sor
1,1
1,2
1,3
1,4
1,5
2. sor
2,1
2,2
2,3
2,4
2,5
3. sor
3,1
3,2
3,3
3,4
3,5

A LET, INPUT és PRINT utasításokat ugyanúgy használhatjuk, mint eddig, pl.:

LET f(1,1)=13

INPUT f(1,2)

PRINT f(3,2)

stb.

A zárójelbe írt első számot sorindexnek, a másodikat oszlopindexnek nevezzük.
Ne gondoljuk, hogy csak 1 és 2 dimenziós tömbök léteznek, van 3 is (sőt több). A 3 dimenzióst így szemléltethetjük:

Itt az azonosításhoz 3 szám kell (las, sor, oszlop).
A4 dimenziósnál az ilyen lapkötegekből képzeljünk el többet. S nincs megállás, mert létezhetnek további dimenziók is, a maximális számuk 255. Ezt már nehéz lenne szemléletesen lerajzolni, 255 indexszám beírása is igen kényelmetlen, de hozzátesszük, hogy a sokdimenziós (3-nál több) tömbök nagyon jól használhatók bizonyos fizikai, illetve gazdasági számításnál. Az igazsághoz az is hozzátartozik, hogy a gép minden esetben ugyanúgy tárolja a számokat, a különbség csak az azonosítás módszerében van, a tömb dimenziószáma megadja, hogy hány darab indexszám kell az azonosításhoz. Különböző feladatokban más és más dimenziószámot érdemes használni, attól függően, hogyan célszerű csoportosítani az adatainkat.
Ott tartottunk, hogy egy helyett három lottószelvénnyel óhajtunk játszani. Az f tömb ezért 3x5 méretű lesz.

310 DIM f(3,5)

A 315-380 részt, amely egy szelvény kitöltéséről gondoskodik, háromszor kell lefuttatnunk, így ezt a programrészt beágyazzuk egy újabb ciklusba.

313 FOR b=1 TO 3 STEP 1
385 NEXT b

A b lesz a sorindex, más szóval a b értéke mutatja, hogy hányadik szelvénynél tartunk. Ezt célszerű lenne a képernyőn is megjeleníteni, írjuk a 315-öt így:

315 PRINT TAB 1;b;". szelveny"

S minden olyan utasítást át kell írnunk, ahol az f tömb szerepel.

330 INPUT f(b,i)
332 IF f(b,i)<1 OR f(b,i)>90 OR f(b,i)<>INT f(b,i) THEN GO TO 330
335 IF f(b,i)=f(b,j) THEN GO TO 330
340 PRINT f(b,i)
357 LET l(j)=f(b,j)
378 LET f(b,j)=l(j)

Az értékeléshez most már a t változó egyedül nem elegendő, hiszen külön kell jegeznünk a 0, 1, ..., 5 találatosnak előfordulását. Ehhez egy 6 elemű 1 dimenziós tömb szükséges.

5 DIM s(6)

A kitöltéshez hasonlóan a kiértékelő részt (410-460) is be kell ágyaznunk egy újabb ciklusba. Itt is használhatjuk a b-t ciklusváltozóként, hiszen a kitöltés elkülönül a kiértékeléstől.

405 FOR b=1 TO 3 STEP 1
468 NEXT b

Ugyanígy módosításra szorul a 440 is.

440 IF f(b,i)=l(j) THEN t=t+1

Az i ciklus lefutása után a t változóban van az adott szelvényen elért találat értéke. 0 találat esetén az s tömb első elemének értékét növeljük eggyel (azért az elsőt, mert nulladik elem nincs); hasonlóan 1 találatnál a másodikat, és így tovább. Természetesen, ha ötösünk van, akkor az s(6)-ot növeljük.

462 LET s(t+1)=s(t+1)+1

A főprogramban a kiírást is meg kell változtatnunk:

50 PRINT "talalat","darabszam"
55 FOR i=0 TO 5 STEP 1
60 PRINT TAB 4;i;TAB 20;s(i+1)
70 NEXT i

Játszhatunk több szelvénnyel is. Legyünk nagyvonalúak, adjunk lehetőséget minden futtatásnál más szelvénymennyiség kitöltéséhez.

305 INPUT "Hany szelvennyel jatszol?";sz

Ennek megfelelően kell az f tömböt létrehozni:

310 DIM f(sz,5)

Az oszlopszám marad 5, mert mindig ennyi számot húznak, legalábbis nálunk.
A kitöltés ciklusa is módosul:

313 FOR b=1 TO sz STEP 1

csakúgy, mint az értékelésé

405 FOR b=1 TO sz STEP 1

Ha ugyanazokkal a szelvényekkel több hétig akarunk játszani, akkor a programot nem RUN-nal, hanem GO TO 20-szal indítjuk, ezzel a kitöltést elkerültük.
A jó programozó egyik legfőbb erénye a lustaság, ezért amit csak lehet, azt A SZÁMÍTÓGÉPPEL VÉGEZTESSÜK EL!

16 INPUT "Hany hetig jatszol?";h
18 FOR n=1 TO h STEP 1
45 NEXT n

Itt ne írassuk ki külön-külön minden húzás eredményét, ezért töröljük a 35-ös sort.
Ha sok szelvénnyel több hétig játszunk, bizony elég hosszú ideig fut a program. De nézzük meg alaposabban a kiértékelő szubrutint. Vegyük egy példát:

szelvény: 11, 17, 52, 67, 81
kihúzott számok: 16, 22, 46, 52, 69

Mivel a belső ciklus a kihúzott számokat futtatja, így a program egymás után összehasonlítja a tippeket a kihúzott számokkal. Csakhogy mindkét számsorozat nagyság szerint van elrendezve, jónéhány fölösleges összehasonlítás is történik. Az első tipp a 11-es, miután összehasonlítottuk az első kihúzott számmal, a 16-ossall, nyugodtan vehetjük a következő tippet, hiszen ezután a 16-nál csak nagyobb számokkal kellene a 11-et összevetnünk. Így ha a kihúzott szám nagyobb, mint az éppen vizsgált tipp, akkor vehetjük a következőt.

435 IF l(j)>f(b,i) THEN GO TO 460

Hasonló a helyzet, ha azonos fordul elő, ilyenkor is vehetjük a következő tippet, hiszen egy adott tipp csak egy kihúzott számmal egyezhet meg. Ezt a módosítást a 440 végére tehetjük be.

440 IF f(b,i)=l(j) THEN LET t=t+1: GO TO 460

Ezzel valamivel rövidül a futási idő.
Mentsük ki a programot kc43 néven!

1 REM kc43
5 DIM s(6)
10 DIM l(5)
15 GO SUB 300
16 INPUT "Hany hetig jatszol?";h
17 CLS
18 FOR n=1 TO h STEP 1
19 PRINT AT 0,26;n
20 GO SUB 100
30 GO SUB 150
40 GO SUB 400
45 NEXT n
50 PRINT TAB 2;"talalat","darabszam"
55 FOR i=0 TO 5 STEP 1
60 PRINT TAB 4;i;TAB 20;s(i+1)
70 NEXT i
99 STOP
100 FOR i=1 TO 5 STEP 1
110 LET r=INT (RND*90)+1
112 IF i=1 THEN GO TO 130
115 FOR j=1 TO i-1 STEP 1
118 IF r=l(j) THEN GO TO 110
120 NEXT j
130 LET l(i)=r
140 NEXT i
145 RETURN
150 FOR k=5 TO 2 STEP -1
153 LET f=0
160 FOR i=2 TO k STEP 1
170 IF l(i)>l(i-1) THEN GO TO 190
175 LET t=l(i)
178 LET f=1
180 LET l(i)=l(i-1)
185 LET l(i-1)=t
190 NEXT i
193 IF f=0 THEN GO TO 199
195 NEXT k
199 RETURN
200 FOR j=1 TO 5 STEP 1
210 PRINT l(j);" ";
220 NEXT j
225 PRINT
230 RETURN
300 REM lottoszelveny kitoltese
305 INPUT "Hany szelvennyel jatszol?";sz
310 DIM f(sz,5)
313 FOR b=1 TO sz STEP 1
315 PRINT TAB 1;b;. szelveny"
320 FOR i=1 TO 5 STEP 1
330 INPUT f(b,i)
332 IF f(b,i)<1 OR f(b,i)>90 OR f(b,i)<>INT f(b,i) THEN GO TO 330
333 IF i=1 THEN GO TO 340
334 FOR j=1 TO i-1 STEP 1
335 IF f(b,i)=f(b,j) THEN GO TO 330
336 NEXT j
340 PRINT f(b,i);" ";
350 NEXT i
354 FOR j=1 TO 5 STEP 1
357 LET l(j)=f(b,j)
360 NEXT j
370 GO SUB 150
375 FOR j=1 TO 5 STEP 1
378 LET f(b,j)=l(j)
380 NEXT j
385 NEXT b
390 RETURN
400 REM kiertekeles
405 FOR b=1 TO sz STEP 1
410 LET t=0
420 FOR i=1 TO 5 STEP 1
430 FOR j=1 TO 5 STEP 1
435 IF l(j)>f(b,i) THEN GO TO 460
440 IF f(b,i)=l(j) THEN LET t=t+1: GO TO 460
450 NEXT j
460 NEXT i
461 IF t>=4 THEN GO SUB 475
462 LET s(t+1)=s(t+1)+1
468 NEXT b
470 RETURN
475 PRINT TAB 8;t;" talalat!"
480 PRINT "a kihuzott szamok: ": GO SUB 200
482 PRINT "a nyertes szelveny:"
484 FOR j=1 TO 5 STEP 1
486 PRINT f(b,j);" ";
487 NEXT j
488 PRINT #1;"Nyomd meg akarmelyik gombot a folytatashoz!"
489 IF INKEY$="" THEN GO TO 489
490 CLS
495 RETURN

A játék úgy az igazi, ha többen játszhatják. Adjon lehetőséget a program, hogy "névvel ellátott" szelvényekkel játszhassunk. Az eddigiekből sejthetjük, hogy módosítani kell a

  • szelvénykitöltő
  • értékelő
  • eredménykiíró

Programrészeket. Lássunk hozzá! A 313-385 programrész kitölti a kívánt számú szelvényt, természetesen csak egy személyét. Ezért építenünk kell köré egy ciklust, amit annyiszor futtatunk le, amennyi a játszani kívánó személyek száma.

301 INPUT "Hany szemely jatszik?";p
311 FOR u=1 TO p STEP 1
387 NEXT u

A neveket is tárolnunk kell, ehhez egy úgynevezett karakter, más néven string tömböt használunk, amely betűk, jelek és természetesen számok tárolására is alkalmas. A tömb létrehozásakor azt is meg kell adnunk, hogy hány karakterből áll a leghosszabb név. Válasszuk ezt az értéket most 6-nak!

302 DIM n$(p,6)

A $ jel - ugyanúgy, mint az egyszerű string változóknál - azt mutatja, hogy tetszőleges karakterek tárolhatók a tömbben, jelen esetben a p változóban megadott darabszámú (ezt adtuk meg a 301-ben), maximum 6 betűből álló név rakható el. Ha már van hol tárolni a neveket, akkor kell egy sor a beírásukhoz is. Ez a sor az u cikluson belülre, illetve a b-n kívülre kell, hogy kerüljön, mert a nevet elég egyszer megadnunk.

312 INPUT "Kerem a nevet";n$(u)

Ha a 314-be tettük volna, akkor az összes szelvénynél ki kellene írni a nevet.
Most jön a leglényegesebb: 3 dimenzióssá kell tennünk az f tömböt.

310 DIM f(p,sz,5)

Ha maradunk a múltkori hasonlatnál:

Kis rajzunk egy 3 lapból (p=3), laponként 4 sorból (sz=4) és 5 oszlopból álló tömböt ábrázol. Emiatt az összes f tömbre vonatkozó utasítást módosítani kell, mivel így 3 számmal (lap, sor, oszlop) adható meg egyértelműen a tömb egy eleme, mintha azt mondanánk: vedd elő a 2. lap 3. sorának 1. helyén álló számot (ez most 21).

330 INPUT f(u,b,i)

Az u mondja meg, hogy hányadik lapnál, azaz személynél tartunk.

332 IF f(u,b,i)<1 OR f(u,b,i)>90 OR f(u,b,i)<>INT f(u,b,i) THEN GO TO 330
335 IF f(u,b,i)=f(u,b,j) THEN GO TO 330
340 PRINT f(u,b,i);" ";
357 LET l(j)=f(u,b,j)
378 LET f(u,b,j)=l(j)

A kitöltéssel készen vagyunk, nézzük meg az értékelő részt.
Az összesített eredményt eddig egy 1 dimenziós, 6 elemű tömbben tároltuk. Ez kevés lesz, hiszen személyenként el kell különítenünk a találatokat. Így az s tömbnek 2 dimenziósnak kell lennie, a sorok száma megegyezik a személyek számával, az oszlopszám pedig 6 (0-5 találatok száma). Eddig az 5-ös sorban hoztuk létre az s tömböt, most máshová kell tennünk, mert csak a 300-as szubrutinban derül ki a személyek száma. Tegyük hát közvetlenül a GO SUB 300 után.

15 GO SUB 300:DIM s(p,6)

Most már nézhetjük magát a kiértékelő szubrutint. Ide is be kell tennünk az u ciklust.

402 FOR u=1 TO p STEP 1
469 NEXT u

Az f tömbre vonatkozó utasításokat a fentiekhez hasonlóan kell átírni.

435 IF l(j)>f(u,b,i) THEN GO TO 460
440 IF f(u,b,i)=l(j) THEN LET t=t+1: GO TO 460

Mivel az s tömb 2 dimenziós lett, a 462 is változik.

462 LET s(u,t+1)=s(u,t+1)+1

Így az s tömb egy sora tartozik egy személyhez, a 0 találatok darabszámát az 1., az egyesekét a 2., stb. oszlopszámú elem tartalmazza. No már csak a végeredmény kiírását kell egy kicsit átalakítanunk. Ezt többféle módon is megtehetnénk.

50 PRINT TAB 2;"nev";TAB 10;talalat";TAB 20;"darabszam"

Ide kell az u ciklus

52 FOR u=1 TO p STEP 1
54 PRINT TAB 1;n$(u)
60 PRINT TAB 10;i;TAB 20;s(u,i+1)
80 NEXT u

Szerencsés lottózást, de mielőtt nagyon belemelegednénk, mentsük ki a programot kc44 néven!

1 REM kc44
10 DIM l(5)
15 GO SUB 300: DIM s(p,6)
16 INPUT "Hany hetig jatszunk?";h
18 FOR n=1 TO h STEP 1
20 GO SUB 100
30 GO SUB 150
40 GO SUB 400
42 GO SUB 200
45 NEXT n
50 PRINT TAB 2;"nev";TAB 10;"talalat";TAB 20;"darabszam"
52 FOR u=1 TO p STEP 1
54 PRINT TAB 1;n$(u);
55 FOR i=0 TO 5 STEP 1
60 PRINT TAB 10;i;TAB 20;s(u,i+1)
70 NEXT i
80 NEXT u
99 STOP
100 FOR i=1 TO 5 STEP 1
110 LET r=INT (RND*90)+1
112 IF i=1 THEN GO TO 130
115 FOR j=1 TO i-1 STEP 1
118 IF r=l(j) THEN GO TO 110
120 NEXT j
130 LET l(i)=r
140 NEXT i
145 RETURN
150 FOR k=5 TO 2 STEP -1
153 LET f=0
160 FOR i=2 TO k STEP 1
170 IF l(i)>l(i-1) THEN GO TO 190
175 LET t=l(i)
178 LET f=1
180 LET l(i)=l(i-1)
185 LET l(i-1)=t
190 NEXT i
193 IF f=0 THEN GO TO 199
195 NEXT k
199 RETURN
200 FOR j=1 TO 5 STEP 1
210 PRINT l(j);" ";
220 NEXT j
225 PRINT
230 RETURN
300 REM lottoszelveny kitoltese
301 INPUT "Hany szemely jatszik?";p
302 DIM n$(p,6)
305 INPUT "Hany szelvennyel jatszol?";sz
310 DIM f(p,sz,5)
311 FOR u=1 TO p STEP 1
312 INPUT "Kerem a nevet";n$(u)
313 FOR b=1 TO sz STEP 1
315 PRINT TAB 1;n$(u);" ";b;". szelvenye"
320 FOR i=1 TO 5 STEP 1
330 INPUT f(u,b,i)
332 IF f(u,b,i)<1 OR f(u,b,i)>90 OR f(u,b,i)<>INT f(u,b,i) THEN GO TO 330
333 IF i=1 THEN GO TO 340
334 FOR j=1 TO i-1 STEP 1
335 IF f(u,b,i)=f(u,b,j) THEN GO TO 330
336 NEXT j
340 PRINT f(u,b,i);" ";
350 NEXT i
354 FOR j=1 TO 5 STEP 1
357 LET l(j)=f(u,b,j)
360 NEXT j
370 GO SUB 150
375 FOR j=1 TO 5 STEP 1
378 LET f(u,b,j)=l(j)
380 NEXT j
385 NEXT b
387 NEXT u
388 PRINT:PRINT
390 RETURN
400 REM kiertekeles
402 FOR u=1 TO p STEP 1
405 FOR b=1 TO sz STEP 1
410 LET t=0
420 FOR i=1 TO 5 STEP 1
430 FOR j=1 TO 5 STEP 1
435 IF l(j)>f(u,b,i) THEN GO TO 460
440 IF f(u,b,i)=l(j) THEN LET t=t+1: GO TO 460
450 NEXT j
460 NEXT i
462 LET s(u,t+1)=s(u,t+1)+1
468 NEXT b
469 NEXT u
470 RETURN

FELADATOK:

  1. Módosítsuk a kc43-at, hogy mindaddig húzzon újabb számokat, amíg egy négyes vagy ötös találatot el nem érünk.

  2. Tegyük általánossá a kc43 programot azzal, hogy ne csak 90/5-ös rendszerben (90 számból ötöt húznak ki hetente) legyen használható.

5. nap - Adatok elraktározása

A megoldások:
1. A kiértékelő részbe kell belenyúlnunk. Ha 4 vagy 5 találatunk van, akkor írjunk ki néhány adatot!

461 IF t>=4 THEN GO SUB 475
...
475 PIRNT TAB 8;t;" talalat"
480 PRINT " a kihuzott szamok:":GO SUB 200
482 PRINT "a nyertes szelveny"
484 FOR j=1 TO 5 STEP 1
486 PRINT f(b,j);" ";
487 NEXT j
488 PRINT #1;"Nyomd meg akarmelyik gombot a folytatashoz!"
489 IF INKEY$="" THEN GO TO 489
490 CLS
495 RETURN

Már egyszer találkoztunk a

PRINT #1

Utasítással. Segítségével a képernyő alsó két sorába írhatunk. A 489 sorból mindaddig nem jön ki a program, amíg meg nem nyomunk egy billentyűt.
Írjuk ki, hogy hányadik héten tart a húzás!

19 PRINT AT 0,26;n

A második feladattal viszonylag egyszerű dolgunk van.

2 INPUT "Hany szambol all a lottoszelveny?";d
3 INPUT "Hany szamot huznak hetebte?";e

Ezután már csak a megfelelő számokat kell a d, illetve e változóra cserélni.

5 DIM s(e+1)
10 DIM l(e)
55 FOR i=0 TO e STEP 1
100 FOR i=1 TO e STEP 1
110 LET r=INT (RND*d)+1
150 FOR k=e TO 2 STEP 1
200 FOR j=0 TO e STEP 1
310 DIM f(sz,e)
320 FOR i=1 TO e STEP 1
332 IF f(u,b,i)<1 OR f(u,b,i)>d OR f(u,b,i)<>INT f(u,b,i) THEN GO TO 330
354
FOR j=1 TO e STEP 1
375 FOR j=1 TO e STEP 1
420 FOR j=1 TO e STEP 1
430 FOR j=1 TO e STEP 1

Programunkat több módon fejleszthetnénk tovább. Készíthetnénk teljes nyilvántartást: több ember játszik különböző számú szelvénnyel, a kihúzott számok maguk a valódi lottószámok lennének, s szerepelhetne még a személyenkénti nyereség, illetve veszteség is. Ezen felül a program képes lehetne különböző kimutatásokat készítni. Például névsor szerint kiírná a neveket és a név mellé azt, hogy hány szelvénnyel játszik hetente és mennyi az eddigi nyereménye. Ugyanezt a listát kiadná a szelvényszám vagy a nyereség szerint sorbarendezve. S természetesen még sok minden más értelmes funkciót is beépíthetnénk, ám most nem ezt tesszük. Mégpedig azért, mert érdemes egy kicsit elgondolkozni a most felmerült problémákon és azok megoldási lehetőségén.
A számítógép egyik leggyakoribb felhasználási területe éppen az adatok tárolása, feldolgozása. Feldolgozás alatt nagyjából bizonyos számítások, műveletek elvégzését, és különböző szempontok szerinti listák elkészítését értjük. A szaknyelv ezeket a programokat adatbázis-kezelőknek nevezi. A kifejezés angol DATA-BASE szó fordításából ered. Minden számítógépre készítettek már több ilyen programot, az intelligensebbek nagyon rugalmasan alkalmazhatóak. Mégis, nem árt, ha magunk is írunk egy kisebb adatkezelő programocskát, mert ezt pontosan olyanra készíthetjük, amilyenre gondoljuk, illetve ahogy az igényeink ezt diktálják. Ilyen-olyan számításokból már csináltunk néhányat, de mit is kell értenünk a különböző szempontok szerinti listák készítésén?
A lottószámok előállításánál már találkoztunk a számok sorbarendezésével. Meg lehet ugyanezt csinálni betűkkel, illetve szavakkal is? Természetesen igen, hiszen minden betűnek, írásjelnek, számjegynek van egy azonosító számkódja (erről már esett szó); ráadásul ezek a kódok szabványosak. A szabvány neve American Standard Code for Information Interchange (amerikai információcsere-szabványkód), rövidítése ASCII (magyarul "aszki"-nak mondják). A függelékben megtaláljuk ezeket a kódszámokat. A táblázat nemcsak az úgynevezett ASCII karaktereket (32-127), hanem grafikus jeleket (128-164), kulcsszavakat (165-255) és úgynevezett vezérlő karaktereket is tartalmaz, ezek közül az ENTER (13) mint sorlezáró karakter szintén a szabványhoz tartozik.
Ha megfigyeljük, a betűk kódjai szépen, sorban követik egymást, így ennek alapján könnyen lehet ABC-sorrendet csinálni. Ezért a SPECTRUM BASIC-je nemcsak számokra, hanem betűkre is érti az összehasonlító műveleteket.
Máris tehetünk egy-két próbát.

10 LET a$="doboz"
20 LET b$="asztal"
100 IF a$>b$ THEN PRINT a$;"nagyobb, mint ";b$:STOP
110 IF a$<b$ THEN PRINT a$;"kisebb, mint ";b$:STOP
120 PRINT "egyformak"

A "nagyobb, mint" kifejezés itt azt jelenti, hogy a névsorban hátrébb áll. Lefuttatva természetesen azt kapjuk, hogy a doboz nagyobb, mint az asztal. Ez nem volt meglepő. Nézzük, mi a helyzet, ha

10 LET a$="asztal    "

A két szó látszólag azonos, az "egyformak" szöveg helyett mégis az

asztal nagyobb mint asztal

Jelenik meg. Ugyanis az első asztal szóhoz hozzátartozik az utána álló 4 darab üres betűhely (SPACE), aminek ugyanúgy létezik kódja (32), mint bármelyik betűnek. Így már könnyedén elkészíthetjük az ABC-be rendező programot. Először hozzuk létre a szavak tárolásához szükséges tömböt!

5 INPUT "Hany szot tarolunk?";e
7 INPUT "Hany betus a leghosszabb szo?";h
10 DIM a$(e,h)
20 GO SUB 100
99 STOP
100 REM adatok beirasa
110 FOR i=1 TO e STEP 1
120 INPUT a$(i)
130 NEXT i
140 RETURN

A lottóprogramnál használt sorbarendező szubrutin némi módosítással itt is alkalmazható, csupán az l tömb helyére az a$, a t helyére t$ kerül.

150 REM sorbarendezes
151 FOR k=e TO 2 STEP -1
153 LET f=0
160 FOR i=2 TO k STEP 1
170 IF a$(i)>a$(i-1) THEN GO TO 190
175 LET t$=a$(i)
178 LET f=1
180 LET a$(i)=a$(i-1)
185 LET a$(i-1)=t$
190 NEXT i
193 IF f=0 THEN GO TO 199
195 NEXT k
199 RETURN

Ha már megvan a sorbarendező szubrutin, meg is kell hívni azt a főprogramban.

30 GO SUB 150

Az sem baj, ha látjuk a végeredményt.

200 REM kiiras
210 FOR c=1 TO e STEP 1
220 PRINT a$(c);" ";
230 NEXT c
235 PRINT
240 RETURN

S a meghívás:

40 GO SUB 200

Ott tartunk, hogy képes a program szavakat tárolni, és azokat ABC-re rendezve kiírni a képernyőre. Ez még nem túl sok. Tegyük fel, hogy az otthon levő könyvek adatait szeretnénk gépünk segítségével tárolni. Egyenlőre csak a szerzőt és a címet vegyük figyelembe, később majd kibővítjük egyéb adatokkal is.
Ehhez két dimenziós tömb kell.

10 DIM a$(e,2,h)

Így az e a könyvek darabszáma lesz (azaz a tömb sorainak száma), soronként 2 elem található és minden elem maximum h hosszúságú.
Az adatbeíró ciklusba 2 INPUT kerül.

115 INPUT "szerzo?";a$(i,1)
120 INPUT "cim?";a$(i,2)

Az adatok bekérése után el kell dönteni, hogy milyen szempont szerint történjen a sorbarendezés (jelenleg szerző vagy cím szerint lehetséges).

30 PRINT AT 0,0;"Milyen szempont szerint rakjuk sorba?"
31 PRINT AT 3,0;FLASH 1;"1";FLASH 0;" szerzo"
32 PRINT AT 6,0;FLASH 1;"2";FLASH 0;" cim"
33 PRINT AT 9,0;FLASH 1;"3";FLASH 0;" tema"
36 PRINT AT 18,0;" Nyomd meg a megfelelo gombot!"
38 LET s=CODE INKEY$
39 IF s<49 OR s>53 THEN GO TO 38
40 LET s=s-48
45 IF s<1 AND s>2 THEN GO TO 38
47 CLS
50 GO SUB 200
99 STOP

A 38-ban megnyomott billentyű kódja bekerül az s változóba. Ha éppen nem nyomtunk le semmit, akkor s=0. Jelen helyzetben csak az 1-es, vagy 2-es billentyűt fogadjuk el érvényesnek. A függelékben található táblázatból kinézhetjük, hogy a számok ASCII kódja 48 és 57 között van, így az 1-é 49, a 2-é 50.
A program mindaddig visszatér a 38-ba, míg a fenti két billentyű valamelyikét le nem nyomtuk. Ezután még magát a sorbarendező szubrutint kell átírni. Az s változóban levő szám mutatja, hogy az a$ tömb melyik oszlopában levő adatok szerint történjen a sorbaállítás. A csere most a tömb két sorának teljes felcserélését jelenti, ezt is ciklussal érdemes csinálni.

170 IF a$(i,s)>a$(i-1,s) THEN GO TO 190
173 LET f=1
175 FOR r=1 TO 2 STEP 1
178 LET t$=a$(i,r)
180 LET a$(i,r)=a$(i-1,r)
185 LET a$(i-1,r)=t$
188 NEXT r
190 NEXT i

Végül a kiírás módosításáról se feledkezzünk el.

210 FOR c=1 TO e STEP 1
215 FOR r=1 TO 2 STEP 1
220 PRINT a$(c,r);" ";
225 NEXT r
230 NEXT c
240 RETURN

Bővítsük tovább a rendszerezés szempontjait! A szerző és a cím mellett tároljuk a mű témakörét (pl. regény, vers, matematika, stb.), valamint a kiadási évet és a könyv árát. Az első ötletünk az lehetne, hogy az eddigi 2 oszlopos tömböt bővítsük ki újabb hárommal!

10 DIM a$(e,5,h)

Igen ám, de gondoljunk arra, hogy az elem hossza (h) egyforma a tömb minden elemére, ez azonban elég nagy pazarlás, hiszen egy könyvcím esetén is legalább 10-15 betű kell, ugyanakkor az árat, illetve az évszámot 3-4 számjeggyel le tudjuk írni. Ráadásul a témakörök esetében nem lenne célszerű minden regénynél tárolni magát a regény szót, jobban járunk, ha az összes témakört egy-egy számmal azonosítjuk. Ezért a három új szempont tárolásához használjunk egy külön numerikus (számok tárolására alkalmas) tömböt, a sorok száma ugyanannyi, mint az a$ tömbé, azaz megegyezik a tárolni kívánt könyvek darabszámával, az oszlopszám pedig 3.
Az előforduló témakörök neveit a könnyebb módosítási lehetőség kedvéért tároljuk egy DATA utasításban

600 DATA "biologia","regeny","vers","xxx"

A legvégén levő xxx jelzi a DATA sorozat végét, így ha újabb témát akarunk beiktatni, azt egyszerűen beszúrhatjuk a megfelelő helyre, az xxx mindenképpen jelzi a témanevek végét. Megtehettük volna, hogy egy külön változóban tároljuk a DATA-ban levő adatok darabszámát, de ebben az esetben újabb téma beírása esetén ezt a változót is módosítani kellene.

Szinte minden programrész módosításra szorul. A 600-as DATA-ban levő neveket természetesen ugyanúgy egy tömbben célszerű tárolni, mintha INPUT-tal adná be őket a program felhasználója. Csupán az a kérdés, mekkora tömbnek foglaljunk helyet a memóriában, másszóval milyen tömböt definiáljunk. Két dolgot kell megállapítanunk: hány névből áll a DATA, és hány betűből áll a leghosszabb név. Az első nem okozhat gondot, hiszen addig kell egyesével számolnunk, míg elérjük az xxx-et. A leghosszabb szó megállapításában segítségünkre siet egy BASIC utasítás, a LEN - amely az angol LENGTH (ejtsd: lengsz), magyarul hosszúság szóból ered. Próbáljuk ki a következő 3 soros programocskát!

1000 LET x$="abcd"
1010 LET h=LEN x$
1020 PRINT h

A csodák csodája, ha lefuttatjuk a programot, ott díszeleg a képernyőn: 4.

5 INPUT "Hany szot tarolunk";e
7 INPUT "Hany betus a leghosszabb szo?";h
10 DIM a$(e,2,h)
12 DIM b(e,3)
13 RESTORE 600:LET n=1:LET pmax=1
14 READ x$
15 IF x$="xxx" THEN GO TO 19
16 LET p=LEN x$
17 IF p>pmax THEN LET pmax=p
18 LET n=n+1: GO TO 14
19 DIM m$(n,pmax)

Így három tömbünk van, az a$-ban az e darab könyv szerzőjét és címét, a b-ben az összes könyv három további adatát (téma, évszám, ár), az m$-ban pedig a témák neveit tároljuk.
Nézzük az adatok beírását!

100 REM adatok beirasa
101 CLS
102 RESTORE 600
103 FOR j=1 TO n STEP 1
104 READ d$:PRINT j;TAB 4;d$:LET m$(j)=d$
106 NEXT j

Ezzel feltöltöttük az m$ tömböt a témanevekkel.

110 FOR i=1 TO e STEP 1
115 INPUT "szerzo?";a$(i,1)
120 INPUT "cim?";a$(i,2)
128 INPUT "temaszam?";b(i,1)
130 INPUT "evszam? (2 szamjegy)";b(i,2)
132 INPUT "ar?";b(i,3)
138 NEXT i
140 RETURN

Az évszámnak elegendő 2 számjegy is.
A kiválasztást kiíró rész két újabb sorral bővül:

34 PRINT AT 12,0;FLASH 1;"4";FLASH 0;" ev"
35 PRINT AT 15,0;FLASH 1;"5";FLASH 0;"ar"

Ennek megfelelően módosul a billentyű-beolvasás.

45 IF s>0 AND s<3 THEN GO TO 150
46 IF s>2 AND s<6 THEN GO TO 300

Mint láttuk, külön szubrutin gondoskodik a nevek (150), illetve a számok (300) alapján történő sorbarendezéséről. Lényegében mindkettő ugyanazt a cserélő szubrutint hívja meg (172), ha az éppen vizsgált elem kisebb, mint az előző, tehát cserére van szükség. Akármilyen szempont szerint is történik a sorbaállítás, az 5 darab összetartozó értéknek (szerző, cím, téma, év, ár) együtt kell elmozdulnia, valójában egész tömbsorokat cserélünk fel.

150 REM sorbarendezes
151 FOR k=e TO 2 STEP -1
153 LET f=0
160 FOR i=2 TO k STEP 1
162 IF a$(i,s)<a$(i-1,s) THEN GO SUB 172
164 NEXT i
166 IF f=0 THEN GO TO 170
168 NEXT k
170 RETURN
172 REM cserelo
173 LET f=1
175 FOR r=1 TO 2 STEP 1
178 LET t$=a$(i,r)
180 LET a$(i,r)=a$(i-1,r)
185 LET a$(i-1,r)=t$
188 NEXT r
190 FOR r=1 TO 3 STEP 1
192 LET t=b(i,r)
194 LET b(i,r)=b(i-1,r)
196 LET b(i-1,r)=t
198 NEXT r
199 RETURN

300 REM sorbarendezes (szamok)
310 LET q=s-2
315 FOR k=e TO 2 STEP 1
320 LET f=0
325 FOR i=2 TO k STEP 1
330 IF b(i,q)<b(i-1,q) THEN GO SUB 172
335 NEXT i
340 IF f=0 THEN GO TO 350
345 NEXT k
350 RETURN

Némi magyarázatra talán csak a 310-es sor szorul. Ha s=3 - mert a harmadik szempontot, a témát választottuk -, akkor a b tömb 1. oszlopában levő számok alapján kell a sorrendet megállapítanunk; s=4 esetén ugyanez a 2. illetve s=5-nél a 3. oszlop elemével történik.

No már csak a kiírás van hátra. Ha azt akarjuk, hogy az összetartozó 5 adat egy sorban legyen a képernyőn, akkor egyikből-másikból le kell vágnunk néhány betűt. Ez is könnyedén megoldható. Tegyük egy-két próbát!

1000 LET x$="abcd"
1010 LET y$=x$(1 TO 3)
1020 PRINT y$

Az 1010-ben az y$ változóba az x$ 1-től 3-ig elemei kerülnek át. Ugyanezt az y$ kihagyásával is megtehetjük.

1010 PRINT x$1 TO 3)

Ezekből következően a kiíró rész így alakul:

200 REM kiiras
203 CLS
205 PRINT "szerzo   cim      tema  ev  ar""
207 PRINT
210 FOR c=1 TO e STEP 1
212 PRINT TAB 0;a$(c,1)(1 TO 8);
215 PRINT TAB 9;a$(c,2)(1 TO 9);
218 PRINT TAB 19;m$(b,(c,1))(1 TO 5);
220 PRINT TAB 25;b(c,2);
225 PRINT TAB 28;b(c,3);
230 NEXT c
240 RETURN

Első pillantásra a 218 kicsit bonyolultnak tűnik, de nincs másról szó, mint hogy a b tömb c-edik sorának 1.oszlopszámú eleme mondja meg, hogy az m$ tömb hányadik elemét kell kiírni.

Végre kipróbálhatjuk a művünket, de előbb vegyük fel kc55 néven! Programunk máris tekintélyes hosszúságú, pedig még ráfér jónéhány kiegészítés.
Ne zsúfoljuk egy sorba az összetartozó adatokat, ehelyett egyszerre csak egy könyvre vonatkozó információk legyenek a képen, s mint a valódi katalóguscédulák között , legyen lehetőség az előre-hátra lapozásra! Ezenfelül adjunk lehetőséget arra, hogy csak bizonyos könyvek adatai kerüljenek a képre; pl. csak biológiai tárgyúak, vagy az összes Verne regény, stb.

1 REM kc55
5 INPUT "Hany szot tarolunk?";e
7 INPUT "Hany betus a leghosszabb szo?";h
10 DIM a$(e,2,h)
12 DIM b(e,3)
13 RESTORE 600:LET n=1:LET pmax=1
14 READ x$
15 IF x$="xxx" THEN GO TO 19
16 LET p=LEN x$
17 IF p>pmax THEN LET pmax=p
18 LET n=n+1: GO TO 14
19 DIM m$(n,pmax)
20 GO SUB 100
28 CLS
30 PRINT AT 0,0;"Milyen szempont szerint rakjuk sorba?"
31 PRINT AT 3,0;FLASH 1;"1";FLASH 0;" szerzo"
32 PRINT AT 6,0;FLASH 1;"2";FLASH 0;" cim"
33 PRINT AT 9,0;FLASH 1;"3";FLASH 0;" tema"
34 PRINT AT 12,0;FLASH 1;"4";FLASH 0;" ev"
35 PRINT AT 15,0;FLASH 1;"5";FLASH 0;" ar"
36 PRINT AT 18,0;" Nyomd meg a megfelelo gombot!"
38 LET s=CODE INKEY$
39 IF s<49 OR s>53 THEN GO TO 38
40 LET s=s-48
45 IF s>0 AND s<3 THEN GO SUB 150
46 IF s>2 AND s<6 THEN GO SUB 300
47 CLS
50 GO SUB 200
99 STOP
100 REM adatok beirasa
101 CLS
102 RESTORE 600
103 FOR j=1 TO n STEP 1
104 READ d$:PRINT j;TAB 4;d$:LET m$(j)=d$
106 NEXT j
110 FOR i=1 TO e STEP 1
115 INPUT "szerzo?";a$(i,1)
120 INPUT "cim?";a$(i,2)
128 INPUT "tema? Ird be a megfelelo szamot!";b(i,1)
130 INPUT "evszam? (2 szamjegy)";b(i,2)
132 INPUT "ar?";b(i,3)
138 NEXT i
140 RETURN
150 REM sorbarendezes
151 FOR k=e TO 2 STEP -1
153 LET f=0
160 FOR i=2 TO k STEP 1
162 IF a$(i,s)<a$(i-1,s) THEN GO SUB 172
164 NEXT i
166 IF f=0 THEN GO TO 170
168 NEXT k
170 RETURN
172 REM cserelo
173 LET f=1
175 FOR r=1 TO 2 STEP 1
178 LET t$=a$(i,r)
180 LET a$(i,r)=a$(i-1,r)
185 LET a$(i-1,r)=t$
188 NEXT r
190 FOR r=1 TO 3 STEP 1
192 LET t=b(i,r)
194 LET b(i,r)=b(i-1,r)
196 LET b(i-1,r)=t
198 NEXT r
199 RETURN
200 REM kiiras
203 CLS
205 PRINT "szerzo   cim      tema  ev  ar"
207 PRINT
210 FOR c=1 TO e STEP 1
212 PRINT TAB 0;a$(c,1) (1 TO 8);
215 PRINT TAB 9;a$(c,2) (1 TO 9);
218 PRINT TAB 19;m$(b,(c,1)) (1 TO 5);
220 PRINT TAB 25;b(c,2);
225 PRINT TAB 28;b(c,3);
230 NEXT c
240 RETURN
300 REM sorbarendezes (szamok)
310 LET q=s-2
315 FOR k=e TO 2 STEP 1
320 LET f=0
325 FOR i=2 TO k STEP 1
330 IF b(i,q)<b(i-1,q) THEN GO SUB 172
335 NEXT i
340 IF f=0 THEN GO TO 350
345 NEXT k
350 RETURN
600 DATA "biologia","csillagaszat","drama","egyeb","film","fizika","kemia","matematika","mese", "nyelv","proza","szamitastechnika","szinhaz","tortenelem","utleiras","vers","zene","xxx"

6. nap - Még mindig a könyvtár

A tegnapi -a program bővítésére tett - ötletek megoldásához egy kicsit fel kell forgatnunk az eddig meglévő dolgokat. Mindenesetre töltsük be a kc55 programot! Szükségünk van egy új kiíró szubrutinra, egy billentyű-figyelőre, amely a lapozást kezeli, s meg kell teremtenünk a választás lehetőségét is (teljes vagy válogatott lista).

250 REM kiiras nem egy sorba
252 CLS
255 PRINT AT 8,10;a$(c,1)
260 PRINT AT 11,1;a$(c,2)
265 PRINT AT 1,31-pmax;m$(b,(c,1))
270 PRINT AT 1,1;b(c,2)
275 PRINT AT 16,24;b(c,3)
280 RETURN

580 REM billentyu figyeles
582 PRINT AT 20,0;"6 - elore, 7 - hatra, SPACE - vissza a valasztashoz"
583 IF INKEY$="" THEN GO TO 583
584 IF INKEY$=" " THEN LET b=0:RETURN
585 IF INKEY$="6" THEN LET b=1:RETURN
586 IN INKEY$="7" THEN LET b=-1:RETURN
588 GO TO 583

A lenyomott billentyűknek megfelelően a b értéke -1,0,1. A szempontkiválasztó rész most a 430-as szubrutinba került, mert - majd látni fogjuk - máshol is szükség lesz rá.

430 PRINT AT 0,0;"Milyen szempont szerint rakjuk sorba?"
431 PRINT AT 3,0;FLASH 1;"1";FLASH 0;" szerzo"
432 PRINT AT 6,0;FLASH 1;"2";FLASH 0;"cim"
433 PRINT AT 9,0;FLASH 1;"3";FLASH 0;"tema"
434 PRINT AT 12,0;FLASH 1;"4";FLASH 0;"ev"
435 PRINT AT 15,0;FLASH 1;"5";FLASH 0;"ar"
436 PRINT AT 18,2;"Nyomd meg a megfelelo gombot"!
438 LET s= CODE INKEY$
439 IF s<49 OR s>53 THEN GO TO 438
440 LET s=s-48
442 RETURN

Nézzük meg a választó programrészt, amelynek szokásos angol elnevezése az angol menu szóból eredően: ÉTLAP vagy MENÜ.

22 CLS
23 INPUT "listazas/valogatas/stop (l/v/s)";e$
25 IF e$="s" THEN STOP
26 IF e$="v" THEN GO TO 500
27 IF e$<>"l" THEN GO TO 23

Ha a feltett kérdésre "v"-vel válaszoltunk, akkor az 500-ra ugrik a program, itt van a válogatás. Ha az "l"-lel feleltünk, akkor jön a sorbarendezés, ahogy ez eddig is történt, majd ezt követi a listázás.

30 GO SUB 430
45 IF s>0 AND s<3 THEN GO SUB 150
46 IF s>2 AND s<6 THEN GO SUB 300
47 CLS
55 LET c=1
57 GO SUB 250
60 GO SUB 580
65 IF b=0 THEN GO TO 22
67 LET c=c+b
68 IF c>e THEN LET c=e
70 IF c<1 THEN LET c=1
74 GO TO 57

Ugye a c változó mondja meg, hogy a tömb hányadik sorát (azaz melyik könyv adatait) akarjuk kitenni a képre. Ezt meg is teszi a 250-es szubrutin. Az utána meghívott 580-as a fent leírt értékek (-1, 0, 1) valamelyikét teszi a b változóba, Ha b=0, azaz a SPACE-t nyomtuk le, jelezve ezzel, hogy elég volt a listázásból, akkor a program visszatér az "étlaphoz" (65). A másik két esetben módosítjuk a c-t a b értékével, vagyis csökkentjük vagy növeljük eggyel. Ez nem más, mint a lapozás (67). A 68 és 70 sorok gondoskodnak arról, hogy ne tudjunk túlmenni az elején vagy a végén (összesen e darab könyv adatait tároljuk). Így a lista elején és végén megáll a lapozás. Ha átírnánk a 68-ast és a 70-est

68 IF c>e THEN LET c=1
70 IF c<1 THEN LET c=e

akkor az utolsó könyv után újra az első jönne, illetve visszafelé lépéskor az első után az utolsó. Ízlés dolga, hogy kinek melyik megoldás a szimpatikusabb.
Nézzük a válogatást!

500 GO SUB 430
505 IF s>3 THEN GO TO 550
507 IF s=3 THEN INPUT "tema?";n$:GO TO 535
508 IF s=2 THEN INPUT "cim?";n$:GO TO 510
509 INPUT "szerzo?";n$
510 LET x=LEN n$
512 LET c=1:LET b=1:LET je=0
514 IF a$(c,s)(1 TO x)=n$ THEN GO SUB 250:GO SUB 580:LET je=1
515 IF b=0 THEN GO TO 22
516 LET c=c+b
517 IF c>=1 AND c<=e THEN GO TO 514
518 IF c>e AND je=0 THEN CLS:PRINT AT 0,10;"Nincs ilyen":GO TO 23
520 GO TO 512
535 LET x=LEN n$
537 LET c=1:LET b=1:LET je=0
540 IF m$(b(c,1))(1 TO x)=n$ THEN GO SUB 250:GO SUB 580:LET je=1
542 IF b=0 THEN GO TO 22
544 LET c=c+b
546 IF c>=1 AND c<=e THEN GO TO 540
547 IF c>e AND je=0 THEN CLS:PRINT AT 0,10;"Nincs ilen":GO TO 23
548 GO TO 537
550 INPUT "also hatar?";ah
552 INPUT "felso hatar?";fh
555 LET c=1:LET b=1:LET je=0
560 IF b(c,s-2)>ah AND b(c,s-2)<fh THEN GO SUB 250: GO SUB 580:LET je=1
562 IF b=0 THEN GO TO 22
564 LET c=c+b
566 IF c>=1 AND c<=e THEN GO TO 560
567 IF c>e AND je=0 THEN CLS:PRINT AT 0,10;"Nincs ilyen":GO TO 23
568 GO TO 555

Az 500-ban meghívott szubrutin kiírja a lehetséges válogatási szempontokat. Az s változóba a lenyomott billentyűtől függően 1-t közötti érték kerül. Tegyük fel, hogy s=1, ekkor szerző alapján válogatunk, az 509 bekéri a nevet, az 510 megállapítja ennek hosszát, s beteszi az x változóba. Az 512-ben beállítjuk a kezdeti értékeket a kiíráshoz, c=1: kezdjük az elején, b=1: majd lapozunk előre. A je változóról külön kell szólnunk. Tegyük fel, hogy olyan nevet adunk meg, az 509-ben, ami nem szerepel a tömbünkben. Ilyenkor a program nyilván nem talál semmi kiírandót, akár előre, akár hátra lapozgatunk; s mindaddig üres a képernyő, amíg vissza nem térünk a SPACE-szel az étlaphoz. Ezért a program figyeli, hogy az összes nevet végignézve sem talált azonosat, akkor kiírja a "nincs ilyen" üzenetet, és automatikusan visszatér a menühöz. Ezt a figyelést szolgálja a je változó.
Az 514 levágja az éppen aktuális szerzőnevet x hosszúságúra és összehasonlítja a beadott névvel. Ha azonosnak találja, akkor meghívja a kiíró és a billentyűzet-figyelő szubrutint, valamint átírja a je-t 1-re. Ha a b=0 (tehát a SPACE-t nyomtuk le a kiírás után), akkor visszatérünk az étlaphoz, ellenkező esetben a c értékét növeljük vagy csökkentjük, azaz lapozunk. Ha az 514-ben nem teljesül az egyenlőség, akkor automatikusan történik az előrelapozás (mivel b kezdeti értékét 1-re állítottuk) az első azonos név megtalálásáig, vagy ha nincs ilyen, akkor a névlista végéig.
518-ba érve ha már túl vagyunk az utolsó szerzőn is (c>e), s még mindig nem találtunk azonosat (a je még mindig 0), akkor jöhet a "nincs ilyen" üzenet. Itt egyébként a lista végétől az elejére ugrunk vissza a változatosság kedvéért. Ha jól megnézzük az 510 és 514 sorokat, akkor kiderül, hogy a levágás miatt nemcsak teljes neveket, hanem akár csupán egy kezdőbetűt is megadhatunk, s így egymás után kiírhatjuk mondjuk az R betűs szerzőket.
A fentiekkel teljesen egyezően történik a címek alapján történő válogatás (s=2).
Az s=3 esetében (téma szerint) sem sok az eltérés. AZ 535-548 sorok az 540 kivételével megegyeznek az 510-520 közöttiekkel. Az 540-ben az azonosság eldöntése történik. Még emlékszünk, hogy a b tömb első oszlopában tároljuk a témák azonosító számát, maguk a témanevek pedig az m$ tömbben vannak.
Az évszám (s=4) és az ár (s=5) szerinti keresésnél is hasonló a helyzet, annyi eltéréssel, hogy itt egy alsó és egy felső határt adhatunk meg (ah, fh). Ezzel kiválaszthatjuk mondjuk a '82 és '84 között vásárolt könyveinket, vagy éppen azokat, amelyeknek ára 30 és 70 Ft közé esett. Ha csupán egy adott évbeszerzése érdekel, akkor ugyanazt a számot kell beadnunk mindkét határértékre.

Ez idáig szép és jó, de hiába mentjük ki a programot, az INPUT-tal beadott adatok elvesznek. Ha még emlékszünk, a rajzoló programnál is volt ilyen gondunk, s a megoldást az adattömb kimentése jelentette. Ezt most is megtehetnénk, mindössze a

SAVE "konyv1" DATA a$
SAVE "konyv2" DATA b()

utasításokat kellene begépelnünk, s természetesen a főétlapot kibővítenünk a betöltés és kimentés lehetőségével.
De adódik egy másik megoldás is. Ha az adatokat nem INPUT-tal adjuk meg, hanem DATA-kba írjuk, akkor a program kimentésével az adataink is a szalagra kerülnek. Csak ezzel sokkal nagyobb memóriaterületet foglalnak le az adatok, hiszen ott vannak a DATA-kban, de ugyanakkor az a$ és a b tömbben is. Ha 10 betűs neveket és címeket használunk, akkor körülbelül 4-500 könyv adatai így is elférnek.

700 DATA "Arany","Toldi",16,83,35
710 DATA "Obadovics","Matematika",8,82,67
720 DATA "Goldman","Elvis",17,85,95

5 LET e=3:REM konyvek szama
7 LET h=10:REM legnagyobb szohossz

115 READ a$(i,1)
120 READ a$(i,2)
128 READ b(i,1)
130 READ b(i,2)
132 READ b(i,3)

A 600-as DATA-hoz hasonlóan itt is megtehettük volna, hogy az adatok számát a program maga határozza meg. Persze akkor a DATA-k végén ismét xxx-nek kellene állnia. Sőt némi ügyeskedéssel az a$ és b tömböt is elhagyhatnánk, hiszen a DATA-kban is megvan minden; ehhez nyilván az a$ és b tömbbel kapcsolatos sorokat kell megfelelően módosítani és a megfelelő RESTORE utasításokról gondoskodni. Jelen példánkban a GOLDMAN könyv kiírásához a

RESTORE 720

utasítással állhatunk a megfelelő DATA sor elejére.
Akinek kedve van hozzá, próbálja megcsinálni.

7. nap - Néhány adósságunk törlesztése

Többször említettük már a felhasználó által definiált, úgynevezett udg karaktereket. A rövidítés az angol user defined graphics (ejtése: júzer difájnd grefiksz) szavakból ered. Minden karakter - így az udg is - 8x8 képpontból áll.

Míg a normál karakterek mintáit leíró a számítógép nem-felejtő memóriájában (ezt nevezzük ROM-nak) találhatók, addig az udg karaktereké a törölhető, átírható memóriarészbe kerülnek (ezt RAM-nak hívjuk). Ez utóbbi terület alapesetben 65368-65535közötti memóriacímeken van. Ez összesen 168 byte-nyi hely. (Emlékszünk még? A SPECTRUM teljes memóriakészlete 65536 byte-ból áll.)
Már az is szóba került, hogy 21 darab udg karakterrel dolgozhatunk, így némi számolással kiderül (168/21 = 8), hogy egy karakterre 8 byte jut. Csupán az a kérdés, hogyan lehet a mintázatot számokkal leírni.) Nézzük újra az előző ábrát. Ez nem áll másból, mint pontok és üres helyek sorozatából. Ha számokkal akarjuk kifejezni, ehhez elegendő két számjegy, legyenek ezek az egyszerűség kedvéért a 0 és az 1.

1: a pont,
0: az üres hely

Rajzoljuk le az ábrát számokkal!

0
0
0
0
0
1
0
0
0
0
0
0
1
0
0
0
0
0
1
1
1
0
0
0
0
0
0
0
0
1
0
0
0
0
1
1
1
1
0
0
0
1
0
0
0
1
0
0
0
0
1
1
1
1
0
0
0
0
0
0
0
0
0
0

Az egy sorban levő számjegyeket egy számnak tekintve éppen 8 számot kapunk.

101 DATA 00000100
102 DATA 00001000
103 DATA 00111000
104 DATA 00000100
105 DATA 00111100
106 DATA 01000100
107 DATA 00111100
108 DATA 00000000

Igen ám, de ha még emlékszünk, egy byte-ban csak 0 és 255 közötti számokat tárolhatunk. Itt látszólag ennék sokkal nagyobbak is előfordulnak Próbáljuk ki!

10 READ x
20 PRINT x: POKE 65368,x
30 DATA 11111111

Szúrjuk be a DATA szó után a BIN-t (elérése: E módban B), Újra futtatva a programot láthatjuk, hogy az 11111111 átalakult 255-té. Nem történt más, mint hogy a 8 darab 1-es számjegyet az eléírt BIN szó miatt BINÁRIS, azaz kettes számrendszerben írottnak tekintette a számítógép (a bináris szó jelentése kettős, kettes). Semmi pánik, nem fogunk elmerülni a különböző SZÁMRENDSZEREK rejtelmeiben, de annyit érdemes megfigyelnünk, hogy a tízes számrendszer 10 különböző számjeggyel (0, 1, ..., 9)dolgozik, míg a kettes csupán kettővel (0, 1).
Hasonlítsuk össze a helyiértékeket is!

100
10
1
9 5 7
 
128
64
32
16
8
4
2
1
1 0 1 1 0 1 1 1

Így az 10110111 kettes számrendszerű szám értéke tízes számrendszerben:

128+32+16+4+2+1 = 183

Töröljük ki a 30-as sort, és tegyük be a 101-108 sorokba a számsor elé a BIN-t. S írjunk egy ciklust, amely a DATA-kban megadott számokat lerakja a memória megfelelő helyére.

10 LET k=65368
40 FOR i=k TO k+7 STEP 1
50 READ x
60 POKE i,x
70 NEXT i

Az így létrehozott grafikus karaktert is a PRINT utasítással vihetjük a képernyőre, úgy, hogy a PRINT szó beírása után áttérünk grafikus üzemmódba (CAPS SHIFT + 9) és ezután nyomjuk le az A billentyűt! Ha az A helyett a B betűvel szeretnénk előhívni ugyanezt a mintázatot, csak egy sort kell módosítanunk.

10 LET k=65376

Könnyen kikövetkeztethetjük, hogy az egyes betűkhöz tartozó minták 8 byte-os számcsoportjai szépen egymás után helyezkednek el a memóriában. Ám számítógépünk még attól is megkímél, hogy kiszámítsuk, hogy például a P-nek megfelelő terület hol kezdődik. Elegendő ennyit írni:

10 LET k=USR "p"

Az USR az angol user szó betűiből származik (az user szóval az udg-nél már találkoztunk).
A grafikus karaktereket kiírhatjuk a kódszámuk segítségével is. Így a grafikus A-t a

PRINT CHR$ 144

Utasítás jeleníti meg. A következő programunk 3 udg karaktert definiál és jelenít meg.

1 REM kc71
10 LET k=USR "a"
15 LET d=3
40 FOR i=k TO k+d*8-1 STEP 1
50 READ x
60 POKE i,x
70 NEXT i
80 FOR i=1 TO d STEP 1
85 PRINT CHR$ (i+143)
90 NEXT i

101 DATA BIN 00000100
102 DATA BIN 00001000

103 DATA BIN 00111000
104 DATA BIN 00000100
105 DATA BIN 00111100
106 DATA BIN 01000100
107 DATA BIN 00111100
108 DATA BIN 00000000
110 REM
111 DATA BIN 00001000
112 DATA BIN 00010000
113 DATA BIN 00111000
114 DATA BIN 01001100
115 DATA BIN 01111000
116 DATA BIN 01000000
117 DATA BIN 00111100
118 DATA BIN 00000000
120 REM
121 DATA BIN 00001000
122 DATA BIN 00010000
123 DATA BIN 00000000
124 DATA BIN 00110000
125 DATA BIN 00010000
126 DATA BIN 00010000
127 DATA BIN 00111000
128 DATA BIN 00000000

A d változóban a definiálandó karakterek darabszámát tároljuk.

Az imént azt mondtuk, hogy az udg terület alapesetben 65368-65535 részen van. Mi az, hogy alapeset, illetve mit kell tennünk, hogy ne az alapeset legyen? Ehhez annyit kell tudnunk, hogy az udg terület kezdetét a SPECTRUM a 23675-ös és a 23676-os címeken talált értékekből számítja ki.

5 LET r=PEEK 23675+256*PEEK 23676

Ha beiktatjuk a

12 PRINT k

Sort, akkor láthatjuk, hogy tényleg 65368 a k értéke. Ez úgy jön ki, hogy 88 és 255 van a fenti két memóriacímen. Meg is nézhetjük PRINT PEEK-kel.
Írjuk át az utóbbit 254-re!

POKE 23676,254

újra futtatva a programot 65112-t kapunk az udg terület kezdeti értékeként.
Miért hasznos ez? Gondoljunk arra, hogy egyszerre 21 udg karakter számára van hely, ha azonban időlegesen átírjuk a 23675 és a 23676 memóriacímeken levő értékeket, akkor megsokszorozhatjuk udg karaktereink számát. Így például a

PRINT CHR$ 144

Utasításhoz annyi különböző fajta karaktermemória tartozhat, ahány ilyen készletet hoztunk létre. Csupán arról kell gondoskodnunk, hogy az adott PRINT utasítás előtt a 23675 illetve 23676 helyekre a megfelelő értéket írjuk be (POKE).
Térjünk vissza alappéldánkhoz! Töröljük ki az 5 és 12 sorokat, és mentsük ki a programot kc71 néven, majd töröljük ki a memóriát egy NEW paranccsal! Ezután próbáljuk ki a

PRINT CHR$ 144

parancsot! S újra a kis á betű jelent meg a képen. Ebből azt a következtetést vonhatjuk le, hogy a NEW parancs az udg területet nem törli.

Eddig a SAVE, LOAD és VERIFY parancsokkal csak BASIC programot és adattömböt tudtunk kimenteni, betölteni. De megtehetjük ezt a memóriaterület bármely részével, így az udg területtel is. A módszer a következő:

SAVE "név" CODE 65368,168

A CODE (kód) szó utal arra, hogy nem BASIC programot, hanem csupán a memória egy részében találhatószámokat mentjük ki, az utána álló számok az adott memóriarész kezdetét, illetve hosszát jelentik (elérése: E módban I).
Az ellenőrzés ehhez hasonlóan:

VERIFY "név" CODE

Ilyenkor a kimentett memóriaterület az eredeti helyére kerül vissza. Ám megtehetjük azt is, hogy más helyre töltjük. Például így:

LOAD "név" CODE 50000

Természetesen itt is írhattuk volna a 65368 helyett az USR "a""-t is.
Ha már itt tartunk, elmondjuk, hogy a képernyő tartalmát is kimenthetjük:

SAVE "név" SCREEN$

A SCREEN$ elérése: E módban SYMBOL SHIFT + K. A SCREEN szóval egyébként már találkoztunk a CLS utasításnál (annak kedvéért, aki nem emlékezne: képernyőt jelent). A VERIFY itt nem működik, hiszen az ellenőrzés kezdetén rákerül a képre a megtalált név.

Eddig a képernyőt a PAPER, INK, BRIGHT és FLASH utasításokkal tudtuk színezni (ezek, mint tudjuk, akár önállóan, akár PRINT vagy PLOT utasításba ágyazva is működnek). Ezentúl színezhetjük a képernyőt akár úgy is, hogy közvetlenül írunk a színmemóriába.

Mint láthatjuk, a képernyő bal felső sarkát a 22528-as memória helyére történő POKE-olással színezhetjük. A színmemória egy byte-ja a kép egy karakterének (8x8 képpont) papír- és tintaszínét illetve fényességét és villogását adja meg a következők szerint:

  tintaszín
+
papírszín * 8
+
64 (ha a fenti színeket fényes változatban akarjuk - BRIGHT 1)
+
128 (ha a fenti színeket villogtatjuk - FLASH 1)

Pl. sárga papíron fekete tinta fényes változatban villogás nélkül:

0 + 6*8 + 64 = 112

Ha ilyen színűre akarjuk festeni a képernyő 3. sorának 16. karakterhelyét, akkor ezt a

POKE 22528+3*32+16,112

utasítással tehetjük meg. Játszunk egy kicsit!

10 LET r=INT (RND*768)
20 LET s=INT (RND*256)
30 POKE 22528+r,s
40 GO TO 10

Ha ügyesen választjuk meg az s-t, egészen érdekes képeket kaphatunk.

Eddig csak írogattunk a kép- és színmemóriába, de olvasni is lehet belőle. Persze mondhatná bárki, hogy ahová POKE-kal bevittünk egy számot, onnan PEEK-kel ki is tudjuk másolni. Ez igaz, de ezeken kívül létezik néhány ügyes kép- és színmemória olvasó utasítás.

LET x=ATTR(0,0)

Az ATTR az attributum (magyarul talán tulajdonságnak fordíthatnánk) szó rövidítése. Elérése: E módban SYMBOL SHIFT+L. Végrehajtása után 0,0 koordinátájú karakter színének (papír, tinta, fényesség, villogás) értéke kerül az x változóba. A koordináta ugyanúgy értendő, mint a PRINT AT utasításnál.

LET x$= SCREEN(0,0)

A koordináták itt is a PRINT AT-nek megfelelőek. Ezután az x$ változóba az adott koordinátájú helyen található karakter kerül, feltéve, ha karaktermintázata benne van a gép ROM-jában. Lényegében a 32-127 kódú karaktereket ismeri fel az utasítás. Ellenkező esetben

x$="" (nem SPACE, üres karakter)

LET x=POINT(0,0)

A POINT elérése: E módban SYMBOL SHIFT+8. Jelentése, bármilyen meglepő is: pont. Végrehajtás után a 0,0koordinátájú képpont (itt most a PLOT-ban értelmezett koordinátákról van szó) "állapota" kerül az x változóba. Ha a képpont üres (a papírszín látszik), akkor x=0, ellenkező esetben x=1 (ilyenkor tintaszín a pont).
Ezek az utasítások különösen a játékprogramokban bizonyulnak igen hasznosnak.

Nem került még szóba, hogyan lehet a SPECTRUMBÓL HANGOT ELŐCSALOGATNI. Nem tagadjuk, ez a gépnek nem erőssége, de egy kis ügyeskedéssel azért ki lehet hozni belőle egészen tisztességes dolgokat is.

BEEP 1,0

A BEEP (ejtése bíp) szó szerinti fordítása helyett inkább emlékeztetnénk arra, hogy valami ehhez hasonló hangot hallatott a kengyelfutó gyalogkakukk is. Elérése: E módban SYMBOL SHIFT+Z. Az utasítást követő első szám a hang időtartamát adja meg másodpercben, a második a hangmagassággal (a hang frekvenciájával) arányos. A 0 éppen megfelel a normál c hangnak. A legmélyebb hanghoz -60, a legmagasabb +69.8 tartozik.

Ezzel végére értünk a SPECTRUM titkainak világában tett kalandozásunknak. Időnként talán túl mélyre merültünk egy téma elemzésében, de reméljük nem volt mindez hiábavaló. A függelékben található táblázatok, illetve a hibakeresés módszerét taglaló külön fejezet tanulmányozásával tovább mélyíthetjük tudásunkat, hiszen bármennyire is igyekeztünk sok mindenről szót ejteni, rengeteg felfedeznivaló maradt még, különösen azok számára, akik előbb-utóbb a gépi kódú programozással is szeretnének megismerkedni.


Függelék

Hibakeresés

Kicsit leegyszerűsítve a dolgokat azt mondhatnánk, hogy a programozás nem áll másból, mint a programsorok beírásából, valamint a hibák megkereséséből, s azok kijavításából. A jó programozó egyik fő ismérve, hogy képes gyorsan behatárolni a hibákat, még akár más által elkészített programban is. Ehhez feltétlenül logikus gondolkodásra és erre épülő módszeres hibafeltárásra van szükség. Ezért most megpróbálunk némi segítséget nyújtani eme területen is. A könyvvel együtt
megvásárolható kazetta számos hibás programot tartalmaz, néhányat vizsgáljunk meg együtt, a többit az olvasóra bízzuk, ugyanis - mint azt már említettük - az önálló munka mindennél hasznosabb.
Az első hét első napján már tettünk említést a hibák típusairól. A formai, vagy ha úgy tetszik helyesírási (idegen szóval szintaktikai) hibákkal nem foglalkozunk, ugyanis a SPECTRUM nem fogadja el a formai hibát tartalmazó sort, és egy villogó ? mutatja, hogy hol kell javítanunk. A tartalmi hibák két csoportba sorolhatók:

  1. Amikor egy formailag ugyan helyes utasítással arra akarjuk rávenni a gépet, hogy írjon a képernyő 33. sorába, akkor egy hibaüzenet figyelmeztet a tévedésünkre: és ez a szerencsésebbik eset, mert így a hiba viszonylag könnyen behatárolható.
  2. A gép bármennyire is ügyes, de nem gondolatolvasó, így nem fogja kitalálni helyettünk, hogy mit akarunk tőle. Például, ha a képernyő legfelső sorába akarunk írni, akkor erre a PRINT AT 1,1 utasítás nem alkalmas. Sajnos ilyenkor magunknak kell rájönnünk a tévedésünkre. Sokszor a hibajelenség csak ritkán, esetleg véletlenszerűen jön elő, ilyenkor már nehezebb a dolgunk.

Töltsük be a kazettáról az 1h nevű programot. Lefuttatva a

2 Variable not found, 20:1

hibaüzenetet kapjuk. Azaz a 20-as sorban olyan változóból szerettünk volna egy számot elővenni, amilyennel eddig a gép még nem találkozott. Vajon melyik lehet ez a változó? Két név lehetséges: az I és az X. Az ellenőrzés egyszerű, próbáljuk ki:

PRINT I

Az eredmény: 1. De a

PRINT X

beírására újra megkapjuk a fenti hibaüzenetet, tehát az X változónak nincs értéke, holott mi azt szeretnénk, hogy a gép az X régi értékéhez adja hozzá az I-t. Nincs más teendőnk, mint kezdeti értéket adni az X-nek.

7 LET K=0

S máris minden rendben.

Töltsük be a kazettáról a 2h nevű programot! Lefuttatva a

3 Subscript wrong, 60:1

hibaüzenetet kapjuk, ami annyit jelent, hogy nem létező tömbelemre hivatkoztunk. A 60-as PRINT eleső részét végrehajtotta a gép, az I értéke: 11. A tömbünk 10 elemből áll, tehát 11 valóban túl nagy szám. A hiba onnan adódott, hogy a kiíratás ciklusváltozója a J és nem az I.

60 PRINT j,a(j)

Ezt a módosítást elvégezve a program lefut, de a tömb összes eleme 0, pedig az olvasási ciklusban megtörténik a 10 adat kiolvasása. Ez már olyan elvi hiba ahol
semmilyen hibaüzenet nem áll rendelkezésünkre. Így marad a logikus gondolkodás. A beolvasás megtörténik, de a tömbelemek a kiíratáskor mégsem egyenlőek a DATA-ban letett értékekkel. Ez Két módon lehetséges:

  1. A beolvasott értékek nem kerülnek be a tömbbe.
  2. A beolvasás után a tömb elemei valamilyen módon lenullázódnak.

Most az 1. eset játszódott le, hiszen a beolvasott érték nem az A tömbbe, hanem egy ugyanilyen nevű változóba kerül.

30 READ a(i)

S ezzel minden tökéletesen működik.

Töltsük be a kazettáról a 3h nevű programot! Elindítva a program futását, egy ideig szépen rajzolódnak egymásra a körök. Ne feledjük azonban, hogy amikor véletlen jelenségekkel dolgozunk, hosszú tesztelésre van szükség, hogy biztosan előkerüljenek az esetleges hibák. Ha elég türelmesek vagyunk előbb-utóbb

B Integer out of range. 40:1

hibaüzenettel leáll a futás. Ellenőrizzük az X,Y,R értékeket.

PRINT x;" ";y;" ";r

Mint az látható, az Y=155 és az R=21. Ha a két értéket összeadjuk (176), megkapjuk a kör felső pontjának Y Koordinátáját. Ez a szám túl nagy, hiszen ennek a koordinátának a maximális értéke 175. A javítás csupán ennyi:

30 LET r=INT (RND*21)

Nézzünk egy kicsit bonyolultabb esetet! Töltsük be a 4h nevű programot! Helyesen megadva a válaszokat, a képernyőn a következők láthatók:

ANGLIA
   ROSSZ
SVAJC

NDK
   ROSSZ
NSZK
LONDON   HELYES

BERN  ROSSZ

BERLIN  HELYES

BONN  ROSSZ

PONTSTAM: 2

A gép csak két választ fogadott el helyesnek (mert a pontszám 2), ráadásul helyes válasz esetén a következő sorban megjelenik a ROSSZ felirat.
Nyilvánvaló, hogy a válasz ellenőrzése körül lehet hiba. Egy program futásának követését megkönnyítheti, ha a kritikus elágazási pontokra beiktatunk egy-egy BEEP utasítást (célszerű eltérő hosszúságú és magasságú hangokat választani a könnyebb megkülönböztetés végett).

50 IF a$(i,2)=b$ THEN BEEP 1,0:PRINT "  HELYES":LET p=p+1
55 BEEP 2,10:PRINT "  ROSSZ"

Így futtatva a programot helyes válasz esetén mindkét hang hallható, ami nem túlzottan nagy meglepetés, hiszen éppen emiatt került a képre ilyenkor is a ROSSZ felirat. Vagyis a válasz minőségétől függetlenül a vizsgálat után mindenképpen az 55-ös sorban folytatódik a program végrehajtása, holott helyes válasz esetén ezt a sort át kell ugranunk, ezért az IF sor THEN ágának a végére be kell tennünk a GO TO 60-at

50 IF a$(i,2)=b$ THEN BEEP 1,0:PRINT "  HELYES":LET p=p+1: GO TO 60

Ezzel az egyik hiba eltűnt, de vajon miért nem fogadja el a gép a BERN és BONN válaszokat? Írassuk ki a képernyőre a helyes választ is!

45 PRINT AT 2*i+2,8;a$(i,2);"  ";b$

Így egymás mellett látható a helyes és a felhasználó által megadott válasz. Ha alaposan megfigyeljük a kiírást, észrevesszük, hogy a rossz válaszok esetében a helyes és a megadott válasz között 4 üres karakterhely van, holott a 45-ös sorban csak kettőt írtunk az idézőjelek közé. Ez annyit jelent, hogy a helyes válaszok kiírásakor a gép a BERN és BONN szavakat is hatbetűsnek tekinti. A DIM utasításban szöveges tömb esetén, mint tudjuk, meg kell adnunk egy elem méretét, jelen példánkban ez a szám 6. A gép minden tömbelem számára ennyi helyet tart fenn, ha egy szó rövidebb ennél, akkor a maradékot üres karakterrel (SPACE) tölti fel. Emiatt csak akkor kapjuk meg a maximális 4 pontot, ha a négybetűs szavakat két üres karakterrel kiegészítve írjuk be. Elegánsabb, ha a feltöltésről maga a program gondoskodik.

41 LET k=6-LEN b$
42 FOR l=1 TO k
43 LET b$=b$+" "
44 NEXT l

Ez a módosítás bármilyen, hatbetűsnél rövidebb szót automatikusan kiegészít.

A kazettán található még jónéhány elrontott program, egyikük-másikuk nehezebb is, mint a fentiek, de reméljük, egyik sem bizonyul majd megoldhatatlannak.

Hibakódok és értelmezésük

A hibaüzenetek a következő részekből tevődnek össze: a sor elején áll a hiba kódszáma, ezt követi a hiba rövid leírása, természetesen angol nyelven, majd annak az utasításnak a száma, ahol a program végrehajtása megszakadt. Ez utóbbi nem is egy szám, hanem kettő, melyeket kettőspont választ el egymástól, az első a sorszám, a második a soron belüli pozíció.

0 OK Rendben

Minden rendben, a program lefutott.

1 NEXT without FOR NEXT FOR nélkül

A program olyan NEXT utasításhoz érkezett, melyet nem előzött meg a hozzátartozó FOR, vagyis beleugrottunk egy ciklus közepébe, vagy egyszerűen hiányzik a FOR utasítás.

2 Variable not found Nincs meg a változó

Olyan változóra hivatkozunk, amelynek korábban még nem adtunk értéket. Minden változót is tartalmazó utasításnál előfordulhat.

3 Subscript wrong Rossz az index

Nem létező tömbelemre hivatkoztunk (az index nagyobb, mint a tömb létrehozásakor megadott elemszám, vagy nem annyi indexszámot használtunk, mint amennyi a tömb dimenziószáma.

4 Out of memory Elfogyott a memória

Nincs elég munkaterület a program végrehajtásához. Ez akkor is előfordulhat, ha CLEAR utasítással alacsonyra tettük le a BASIC memóriaterület tetejét.

5 Out of screen Nem fér rá a képre

A képernyő 22. sorába akartunk írni.

6 Number too big Túl nagy szám

Matematikai kifejezésekben a gép által elfogadott legnagyobb szám 10^38-on.

7 RETURN without GO SUB GOSUB nélküli RETURN

A program a végrehajtás során úgy érkezett egy RETURN-höz, hogy szubrutinhívás nem történt. Ez akkor fordulhat elő, ha GO SUB helyett GO TO-val ugrunk rá a szubrutinra, vagy egyszerűen belecsorgunk. Ez utóbbit megakadályozhatjuk, ha a szubrutin első sora elé egy STOP-ot teszünk.

8 End of file Csak microdrive használata esetén fordul elő.

 

9 STOP statement Vége

A STOP utasítás hatására ezzel az üzenettel áll le a program.

A Invalid argument Helytelen argumentum

Egy függvény argumentumába olyan értéket írtunk be, amelyet az értelmezni nem tud.

B Integer out of range Tartományon kívül eső szám

Minden olyan utasításnál előfordulhat, amelybe csak bizonyos határok közé eső egész számot írhatunk he.

C Nonsense in BASIC A BASIC-ben nem értelmezhető

A VAL és VAL$ utasítások argumentuma nem megfelelő, vagy a program sérülése következtében (például hibás betöltés) értelmetlen sor keletkezik.

D BREAK-CONT repeats Megszakított állapot

Valamilyen külső eszközzel (magnó, nyomtató) történő adatközlés megszakításakor kapjuk. CONT parancs hatására az adott utasítás ismét végrehajtódik. Érdemes összevetni az L hibaüzenettel.

E Out of data Elfogyott az adat

A READ utasításokkal az utolsó DATA-t is kiolvastuk. Vagy bővítenünk kell az adatokat, vagy egy RESTORE-ral vissza kell állítanunk a DATA mutatót egy korábbi DATA sorhoz.

F Invalid file name Hibás név

A SAVE parancs argumentumában üres, vagy 10 karakternél hosszabb string áll.

G No room for line Nincs hely újabb sor számára

A gép memóriájában már nincs hely egy újabb sor befogadására.

H STOP in INPUT STOP az INPUT sorban

Akkor fordul elő ha az INPUT első karaktere a STOP kulcsszó. Ezzel lehetőségünk van a program futásának megszakítására akkor is, amikor a program INPUT-ban várakozik.

I FOR without NEXT Nincs lezárva a ciklus

Egy üres ciklus (pl. FOR i=3 TO 1 STEP 1) végrehajtásakor hiányzik a FOR-t lezáró NEXT, ugyanis ilyen esetben a gép azonnal a NEXT utáni sornál folytatná a program végrehajtását.

J Invalid I/O device Csak microdrive használata esetén fordul elő.

 

K Invalid colour Hibás színkód

A színezéssel kapcsolatos valamely utasítás (ideértve a FLASH, BRIGHT, INVERSE, OVER utasításokat is) argumentumában álló érték nem megengedett.

L BREAK into program Megszakított állapot

A program futása a BREAK parancs kiadásával bármikor megszakítható. CONT parancs hatására a soron következő utasítással folytatódik a program végrehajtása. Érdemes összevetni a D hibaüzenettel.

M RAMTOP no good Rosszul van beállítva a RAMTOP

A RAMTOP a BASIC számára elérhető memóriaterület felső határa. Elfordul, ha egy CLEAR paranccsal túl alacsony értékre próbáljuk beállítani a RAMTOP-ot.

N Statement lost Elveszett utasítás

Egy utasítás, vagy annak egy része elveszett.

O Invalid stream Csak microdrive használata esetén fordul elő.

 

P FN without DEF Nem definiált függvény hívása

Olyan felhasználói függvényt hívtunk, amelyet korábban nem definiáltunk.

Q Parameter error Paraméter hiba

A felhasználói függvény hívásakor rosszul adtuk meg a paramétereket.

R Tape loading error Töltési hiba

A program betöltése, vagy a kimentett program ellenőrzése (VERIFY) szalaghiba miatt ezzel az üzenettel áll le.

 

BASIC kulcsszavak

A magyarázatok jelentős részéhez egy értékelemző táblázat tartozik, melyben, megtalálhatjuk az adott utasítás által elfogadott értékeket, illetve a különböző hibaüzeneteket. Ahol ez a táblázat hiányzik ott minden értéket elfogad a gép. Azokban az esetekben, amikor csak az egész számok a helyesek, s törtet adunk meg, a gép kerekíti az értéket a táblázatunkban ezt a "csak egész" szöveggel jelezzük. Az utasítások argumentumában sok esetben egy változónév áll (ez rendszerint az x), de ezt csak az egyszerűbb jelelés miatt használtuk, vajban ezekre a helyekre számot, vagy különböző műveleteket tartalmazó kifejezést is írhatunk.

ABS (Abszolútérték-függvény)
Példa:

LET y=ABS x

Az y változóba az x értéke kerül előjel nélkül. (Az előjel nélküli szám mindig pozitívnak számít.) Ha x pozitív szám vagy 0, akkor y=x, ellenkező esetben y=-x.

ACS (Arkusz koszinusz függvény)
Példa:

LET y=ACS x

Az y változóba az x arkusz koszinusza kerül radiánban.
Értelmezés:

helyes
hibás
hibaüzenet
-1 <= x <= 1
x > 1
A
 
x < 1
A
AND (Logikai 'ÉS' művelet)
Példák:

IF x>0 AND y>2 THEN GO TO 100

A feltétel csak abban az esetben teljesül, ha az AND-del összekapcsolt állítások mindegyike igaz.

LET y=x>0 AND s>2

Az y változóba 1 kerül, ha mindkét állítás teljesül, ellenkező esetbe az a értéke 0 lesz.

ASN (Arkusz szinusz függvény)
Példa:

LET y=ASN x

Az y változóba az x arkusz szinusza kerül radiánban.
Értelmezés:

helyes
hibás
hibaüzenet
-1 <= x <= 1
x > 1
A
 
x < 1
A

 

ATN (Arkusz tangens függvény)
Példa:

LET y=ATN x

Az y változóba az x arkusz tangense kerül radiánban.

ATTR (Attribútum: egy karakterre vonatkozó színnel kapcsolatos adat)
Példa:

LET f=ATTR(x,y)

Hatása ugyanaz, mint a

LET f=PEEK(22528+x*32+y)

utasításnak. Az x,y értékek a PRINT AT-ben alkalmazott sor- és oszlopkoordináták (az értékelemzést lásd ott). Az f értékre a következő módon adódik:

f=FLASH*128 + BRIGHT*64 + PAPER*8 + INK

BEEP (hangkeltés)
Példa:

BEEP X,Y

X: a hang hossza másodpercben
Y: a hangmagasság
y=0 a közepes c hangnak felel meg. A pozitív értékekhez ennél magasabb, a negatívokhoz pedig mélyebb hangok tartoznak. Értelmezés:

helyes
hibás
hibaüzenet
-60 <= y <= 69.8
minden egyéb
B
0 <= x < 10.5
minden egyéb
B
BIN (Bináris)
Példa:

LET y=BIN 1011

átalakítja a kettes számrendszerben írt maximum 16 jegyű számot decimálissá (tízes számrendszerűvé).

BORDER (A keretszín megadása)
Példa:

BORDER x

A színkódok megtalálhatók az INK kulcsszónál. Értelmezés:

helyes
hibás
hibaüzenet
0 <= x <= 7
-256 < x < 0
K
(csak egész)
7 < x < 256
K
 
x <= -256
B
 
x >= 256
B
BRIGHT (Fényesség ki- bekapcsolása)
Példa:

BRIGHT x

Értelmezés:

helyes
hibás
hibaüzenet
0, 1, 8
-256 < x < 0
K
(csak egész)
1< x < 8
K
 
8 < x < 256
K
 
x <= -256
B
 
x >= 256
B

0: kikapcsolja a fényességet
1: bekapcsolja a fényességet
8: változatlanul hagyja a fényességi állapotot A ki- és bekapcsolás lehet ideiglenes, vagy tartós, erre vonatkozóan az INK utasításnál található magyarázat.

CAT Csak microdrive használata esetén értelmezi a gép.
CHR$ (Karakter string)
Példa:

LET a$=CHR$x

Az a$ stringváltozóba x számnak megfelelő kódú (lásd CODE !) karakter kerül.
Értelmezés:

helyes
hibás
hibaüzenet
32 <= x <= 255
x < 0
B
(csak egész)
x > 255
B

A 0 és 31 közé eső úgynevezett vezérlő karakterek értelmezését egy külön táblázat tartalmazza.

CIRCLE (Kör)
Példa:

CIRCLE x,y,r

x ,y a kör középpontjának koordinátái (ugyanaz, mint a PLOT utasításban, r: a kör sugara.
Értelmezés: Az x, y értékeire ugyanaz vonatkozik, mint a PLOT esetében, a sugár természetesen nem lehet negatív szám, a rajzolás pontonként történik, ha a kirajzolandó pont koordinátája a képernyőn kívülre mutat, akkor a futás a B Integer out of range hibaüzenettel leáll.

helyes
hibás
hibaüzenet
0 <= x-r
x-r < 0
B
x+r <= 255
x+r > 255
B
0 < y-r
y-r < 0
B
y+r <= 175
y+r >175
B
(csak egész)
   
CLEAR (Törlés)
Példa:

CLEAR x
CLEAR

Az utasítás funkciói(mindkét változatra érvényes):
- törli a képernyőt,
- törli a változókat,
- visszaállítja a PLOT pozíciót a bal alsó sarokba.
- kiüríti az úgynevezett GO SUB stacket
(az a memóriaterület, ahol a szubrutinok visszatérési sorszámai találhatók)
Mindezek mellett a CLEAR x legfontosabb funkciója az x-nek megfelelő értékre állítja át a BASIC memóriaterület felső határát. Ezt akkor célszerű tennünk, ha a BASIC program úgynevezett gépi kódi, szubrutinokat hív meg.
Értelmezés: Átállítás csak akkor történik, ha a gépben már benn levő BASIC program nem nyúlik túl az x-ben megadott memóriacímen. Ellenkező esetben az M hibaüzenetet olvashatjuk. Ha x>65535, akkor a már annyiszor látott hibaüzenetet kapjuk.

CLOSE# Csak microdrive használata esetén értelmezi a gép.
CLS (CLEAR SCREEN - képernyőtörlés)
Letörli a képernyőt.
CODE (Kód)
Példa:

LET y=CODE x$

Az y változóba az x$ string első karakterének kódszáma kerül (hasonlítsuk össze a CHR$ utasítással!).

CONTINUE
(Folytatás)
Csak parancsként használatos, ha BREAK-kel megállítjuk egy program futását, vagy automatikusan leáll valamilyen hibaüzenettel, akkor a CONT paranccsal a program folytatható. Természetesen az utóbbi esetben az újraindítás előtt a hiba okát meg kell szüntetnünk.
COPY (Kopírozás, azaz másolás)
A képernyő felső 22 sorát kimásolja a ZX-printerre.
COS (Koszinusz függvény)
Példa:

LET a=COS x

Az a változóba az x (radiánban megadott) szög koszinusza kerül.

DATA (Adat)
Példa:

  1. DATA 5,10,2,-7,-3,14
  2. DATA "jozsi","pista,zoli"

A DATA sorokból READ-del lehet kiolvasni a tárolt adatokat.

DEF FN (Felhasználói függvény)
Példa:

DEF FN K(x,y)=3*x+2y
DEF FN q$(a$,n)=a$(n TO n)

A gyakran alkalmazott összefüggéseket érdemes saját függvényként megadni. 26 numerikus és 26 stringfüggvényt tudunk definiálni, a függvények argumentumában összesen 52 betű állhat. Előhívásul FN utasítással lehetséges. Próbáljuk ki a következő kis programot!

20 DEF FN q$(a$,n,m)=a$(n TO m)
30 LET c$=FN q$("abcde",2,4)
40 PRINT c$

A 20-as sorban a DEF FN argumentumában található a$ ill. n változóknak csak formai szerepük van, azt jelölik, hogy amikor a g$ nevű felhasználó függvényre hivatkozunk: akkor a zárójelben először egy stringet, azután két számot kell megadnunk vesszővel elválasztva. A 20-ban megadott művelet szerint,a stringből kivágjuk az n-edik és m-edik elem közé eső részt, s ez kerül a c$ változóba. Az a$, n és m változókat ettől függetlenül használhatjuk a programban.

DIM (Adattömb létrehozása)
Adattömb részére helyet foglal a memóriában.
Példa:

DIM n(x,y)

Ezzel létrehoztuk az n nevű, 2 dimenziós, x sorból és y oszlopból álló numerikus (számok tárolására alkalmas) tömböt.

DIM b$(x,y,z)

A b$ nevű 2 dimenziós string tömb (tetszőleges karakter tárolására alkalmas) x sorból és y oszlopból áll. Minden elem maximum z karakterből állhat.
Mindkét esetben maximum 255 dimenziós tömböt hozhatunk létre. Egyébként a tömb méreteit csak a szabad memóriaterület korlátozza. Ha nincs elegendő hely, a 4 Out of memory error hibaüzenetet kapjuk. Karakteres tömb esetében minden egyes elem tárolásához annyi byte szükséges, ahány karakterből áll egy elem, a numerikus tömböknél ez mindig 5 byte.

DRAW (Rajzol)
Példa:

DRAW a,b

Az utasítás egy egyenest húz. A kezdőpont a legutóbbi rajzolás (PLOT, DRAW, CIRCLE) végpontja. A végpontot úgy számítja ki, hogy a kezdőpont x koordinátájához hozzáad a-t, az y koordinátájához pedig b-t. Értelmezés:

helyes
hibás
hibaüzenet
-255 < a < 255
a < -255
B
 
a > 255
B
-175 <= b <= 175
b < -175
B
(csak egész)
b > 175
B

Amennyiben az a és b fenti helytelen értékek valamely csoportjához tartozik, akkor a rajzolás el sem kezdődik. Egyébként az egyenes meghúzása pontonként történik, s csak akkor áll le a futás (ismét csak a B hibaüzenettel), amikor az éppen kirajzolandó pont a képernyőn kívülre kerülne.

DRAW a,b,c

Hasonló az előzőhöz. Kivéve, hogy a kezdő- és végpontot most nem egyenes, hanem körív köti ősze. A c a körív középponti szöge radiánban, ha c=PI akkor félkört, c=2*PI esetén pedig egyenest kapunk.

ERASE Csak microdrive használata esetén értelmezi a gép.
EXP (Exponenciális függvény)
Példa:

LET y=EXP x

Az y változóba az "e" x-edik hatványa (e=2.71828183)

FLASH (Villogás ki- bekapcsolása)
Példa:

FLASH x

Értelmezés:

helyes
hibás
hibaüzenet
0, 1, 8
-256 < x < 0
K
(csak egész)
1 < x < 8
K
 
8 < x <256
K
 
minden egyéb
B

0: kikapcsolja a villogást,
1: bekapcsolja a villogást,
8: változatlanul hagyja a villogás állapotot
A ki- és bekapcsolás lehet ideiglenes, vagy tartós, erre vonatkozóan az INK utasításnál található magyarázat.

FOR (Ciklusutasítás)
Példa

FOR i=x TO y STEP z

x: a ciklus kezdete,
y: a felső határ,
z: a lépésköz.
Értelmezés: x, y és z bármilyen értékű lehet, de gyorsabban fut a programunk, ha 65536-nál kisebb egész számokat adunk meg.
A ciklust lezáró utasítás a

NEXT i

FORMAT Csak microdrive használata esetén értelmezi a gép.
GO SUB (Szubrutinhívás)
Példa:

GO SUB x

Hatására a program futása az x számú sorban folytatódik mindaddig, amíg egy RETURN utasítással nem találkozik, akkor a gép visszatér a GO SUB-ot követő utasításhoz. Értelmezés:

helyes
hibás
hibaüzenet
0 < x < 65536
x < 0
B
(csak egész)
x > 65535
B
 
x = 0
4

Ha x olyan érték, amilyen számú sor nincs a programban, akkor a számítógép megkeresi az x-nél nagyobb sorszámok közül az x-hez legközelebb esőt, és itt folytatja a program végrehajtását. Ha az x nagyobb, mint a legnagyobb sorszám a programban.(ez egyébként maximum 9999 lehet) akkor a futás a 0 OK hibaüzenettel leáll.

GO TO (Ugrás)
Példa:

GO TO x

Hatására a program futása az x számú sorban folytatódik.
Értelmezés: ugyanaz, mint a GOSUB esetében.

IN (Adatbehozás külső eszközről)
Példa:

LET a=IN x

A számítógép úgynevezett INPUT/OUTPUT portokon (bemeneti/kimeneti kapukon) keresztül 'beszélget' a hozzá csatlakozó kiegészítő egységekkel (pl. billentyűzet, printer). Az IN utasítás hatására a számítógép beolvassa az a változóba az x számú I/O porton levő értéket. (érdemes összehasonlítani a PEEK utasítással.)

INK (Tintaszín, azaz a minta színe)
Példa:

  1. INK x
  2. PRINT INK 4;"CSAK EZ LESZ ZOLD"

Tartósan (1) vagy ideiglenesen (2) átírja a tintaszínt. A tartósan kifejezés annyit jelent, hogy mindaddig ezzel a tinta színnel történik minden kiírás és rajzolás, amíg egy újabb INK utasítással meg nem változtatjuk. Ha az INK nem önálló utasításként áll, hanem be van építve egy kiíró vagy rajzoló utasításba (2), akkor csak arra az utasításra vonatkozik a szín megadása,(azaz ideiglenes) s a továbbiakban a régi tinta szín érvényes.
Értelmezés:

helyes
hibás
hibaüzenet
0 < x <= 9
x < 0
B
(csak egész)
9 < x < 256
K
 
x > 256
B

Színkódok:

0 - fekete,
1 - sötétkék,
2 - vörös,
3 - lila,
4 - zöld,
5 - világoskék (cián),
6 - sárga,
7 - fehér,
8 - átlátszó (az adott karaktert az éppen érvényes tintaszínnel rajzolja)
9 - kontraszt (az adott papírszíntől leginkább elütő szín).

INKEY$ (Billentyűnyomás figyelése)
Példa:

20 LET a$=INKEY$

Ha a 20-as sor végrehajtásakor egy billentyűt lenyomva tartunk, akkor a billentyű kódja bekerül az a$ változóba. Próbáljuk ki!

10 PRINT AT 0,0;INKEY$
20 GO TO 10

INPUT (Adatbevitel a billentyűzetről)
Segítségével a felhasználónak lehetősége van a program futása közben értéket adni egy változónak.
Példa:

10 INPUT y
20 INPUT x$

A felhasználó tájékoztatására szolgál a beépített szöveg

30 INPUT "Ird be a neved!";a$

Ez azért is hasznos mert így elkerülhető, hogy betűkkel válaszoljunk, amikor a gép csak egy számot vár. Például, ha a 10-es sor végrehajtásakor a Zoli szót gépeljük be az y értéke a Zoli nevű változó értékével lesz egyenlő, feltéve, hogy van ilyen változónk, ellenkező esetben a 2 Variable not found hibaüzenetet olvashatjuk.

INT (Ineger - egészrész)
Példa

LET y=INT x

Az y változóba az x értékének egész része kerül, ami lényegében lefelé kerekítést jelent. Az alábbi kis program bemutatja a különböző eseteket.

10 FOR x=-2 TO 2 STEP 0.2
30 LET y=INT x
30 PRINT x,y
40 NEXT i

INVERSE (Inverz, azaz fordított)
INVERSE 1 - bekapcsolja az inverz videó üzemmódot.
INVERSE 0 - visszakapcsolja a normál videó üzemmódot.
A ki- és a visszakapcsolás lehet tartós és ideiglenes, ennek részletezése az INK magyarázatánál található meg.
Példa:

2 PRINT INVERSE 1; "CSAK EZ LATSZIK INVERZBEN"

Értelmezés: Csak a 0 és az 1 a helyes érték, a hibaüzenetek ugyanazok, mint a BRIGHT utasításnál.

LEN (LENGTH azaz hosszúság)
Példa:

LET y=LEN x$

Az y változóba az x$ string karaktereinek száma, másszóval a hossza kerül.

LET (Változónak értéket adó utasítás)
Példa:

1 LET x=12
2 LET x=y*3
3 LET x=x-1
4 LET x$="igen"
5 LET x$=y$+q$
6 LET K(3)=23
7 LET n$(2)=x$

A változó lehet numerikus (1,2,3) string (4,5), vagy úgynevezett tömb típusú (6,7). Csak olyan tömbbe írhatunk, amelyet korábban egy DIM-mel definiáltunk.

LIST
(Listázás)
A program kiíratására szolgáló parancs, ha nem a legelső sortól akarjuk indítani a listázást, akkor a LIST után be kell írni a kívánt sorszámot. Ez a szám természetesen nem lehet negatív, vagy 65535-nél nagyobb szám, mivel ilyen sorszámokat nem fogad el a gép.
LLIST (Listázás a nyomtatóra)
LN (Logarithmus Naturalis, azaz a természetes alapú logaritmus)
Példa:

LET y=LN x

Az y változóba az x természetes alapú logaritmusa (az alap: e=2.7182818...) kerül. Értelmezés:

helyes
hibás
hibaüzenet
x > 0
x <= 0
A
LOAD (Betöltés)
Példa:

  1. LOAD "név"
  2. LOAD "név" CODE
  3. LOAD "név" SREEN$
  4. LOAD "név" DATA x()
  5. LOAD "név" DATA x$()

Basic program (1), gépi kódú program vagy adat (2), kép (3), numerikus tömb (4), string tömb (5) betöltése szalagról. A név maximum 10 karakterből állhat, ennek alapján keresi meg a gép a szalagon a kiválasztott programot, vagy adathalmazt. Ha a név helyén egy üres string áll ("") akkor mindig a szalagon soron következő program töltődik be. Az x és x$ a numerikus, illetve string tömb neve, ez mindig csak egy betű lehet.

MERGE (Összeolvasztás)
Példa:

MERGE "név"

Segítségével a gépben levő Basic programra rátölthető egy újabb program. Ha az eredeti és az új program azonos számú sorokat tartalmaz, akkor a régi sor törlődik s az új lép a helyére.

MOVE Csak microdrive használata esetén értelmezi a gép.
NEW
(új)
Előkészíti a gépet egy új program fogadására, kitörli a teljes Basic programot, csupán a Basic memóriaterület feletti rész marad érintetlen így az UDG karakterek nem vesznek el.
NEXT A magyarázat a FOR utasításnál megtalálható.
NOT (Logikai tagadás)
Ellenkezőjére változtatja egy logikai kifejezés értékét, azaz ha igaz volt hamissá teszi és fordítva.
Példa:

IF NOT x=0 THEN PRINT x

A THEN után álló PRINT csak akkor kerül sorra, ha nem igaz az, hogy x egyenlő 0-val azaz teljesül az x<>0 feltétel.

OPEN# Csak microdrive használata esetén értelmezi a gép.
OR (Logikai 'VAGY' művelet)
Példa:

1 IF x>0 OR y>2 THEN GO TO 100

A feltétel csak abban az esetben teljesül, ha az OR-ral összekapcsolt állítások közül legalább az egyik igaz.

2 LET y=x>0 AND s>2

Az y változóba 1 kerül, ha az egyik állítás teljesül, ellenkező esetben az értéke 0 lesz.

OUT (Adatkivitel külső eszközre)
Példa:

OUT x,y

Az IN utasítás párja, segítségével a fent említett I/O portokra lehet kiküldeni. (Érdemes összehasonlítani a POKE-kal.) Az x-szel megadott számot I/O címnek nevezzük. Az egyes címek értelmezésére nem térünk ki.

helyes
hibás
hibaüzenet
0 < x <= 65535
x < 0
B
 
x > 65535
B
-255 <= y <= 255
y > 255
B
(csak egész)
y < -255
B

Az y esetében a számítógép az előjelet nem veszi figyelembe.

OVER
(Átfedés, felülírás)
OVER 1 - bekapcsolja a felülírás üzemmódot,
OVER 0 - visszakapcsolja a normál üzemmódot
A felülírás azt jelenti, hogy a kinyomtatott minta tinta színű lesz, ha az eredeti képpontok üresek, azaz a papír színűek voltak, s fordítva a tinta színű pontok papír színűre változnak. Ha ugyanarra a helyre kétszer egymás után OVER 1-gyel írunk ki valamit, akkor a második PRINT letörli azt, amit az első írt.
Példa:

10 PRINT AT 0,0;OVER 1;"cica"
15 PAUSE 100
20 PRINT AT 0,0;OVER 1;"cica"

Mindez természetesen a rajzoló utasításokra is érvényes. A ki- és visszakapcsolás lehet tartós és ideiglenes, ennek részletezése az INK magyarázatánál található meg.
Értelmezés: Csak a 0 és az 1 a helyes érték, a hibaüzenetek ugyanazok, mint a BRIGHT utasításnál.

PAPER (A papír szín, azaz a háttér szín)
Az utasítás pontosan úgy működik, mint az INK, ezért a részletes magyarázat megegyezik az ott találhatóval.
PAUSE (Pauza, azaz szünet)
Példa:

PAUSE x

A PAUSE hatására a program futása leáll annyiszor 1/50 másodperc időre, amennyi az x értéke. A várakozás bármely billentyű lenyomásával megszakítható. Ha x=0, akkor a futás mindaddig áll, amíg egy billentyűt le nem nyomunk. Értelmezés:

helyes
hibás
hibaüzenet
0 <= x <= 65535
x < 0
B
(csak egész)
x > 65535
B
PEEK (Memória tartalom kiolvasása)
Példa:

LET y=PEEK x

Az y változóba az x-szel meghatározott memóriacím tárolt szám kerül

helyes
hibás
hibaüzenet
0 <= x <= 65535
x < 0
B
(csak egész)
x > 65535
B
PLOT (Egy pont kirajzolása)
Példa:

PLOT x,y

Az utasítás kirajzol egy pontot a képernyő x-edik sorának y-odik oszlopába. A képernyő 176x256 képpontból áll (pixel) áll, a hely kiszámítás a bal alsó sarokból kiindulva történik Értelmezés:

helyes
hibás
hibaüzenet
-255 <= x <= 255
x < -255
B
 
x > 255
B
-175 <= y <= 175
y > 175
B
(csak egész)
y < -175
B

A PLOT argumentumában álló számoknak (jelen esetben az x és az y változó tárolja őket) a gép az abszolút értékét veszi (azaz eltekint az előjeltől), majd kerekíti.

POINT

(Képpont tartalmának kiolvasása)
Példa:

LET k=POINT(x,y)

A k változóba 1 kerül, ha az x,y koordinátákkal megadott képpont tinta színű és 0 ha papír színű. A koordináták ugyanúgy értelmezendők, mint a PLOT utasításban, így az értékelemzés is ugyanaz.

POKE (Beírás egy adott memória címre)
Példa:

POKE x,y

Az utasítás az x-szel megadott memóriacímre beírja az y-t. Értelmezés.

helyes
hibás
hibaüzenet
0 <= x <= 65535
x < 0
B
 
x > 65535
B
-255 <= y <= 255
y < -255
B
(csak egész)
y > 255
B
PRINT (Kiíratás a képernyőre)
A kiíratáshoz meg kel adnunk mit, hová s milyen színnel akarunk láthatóvá tenni, de ez utóbbi kettő el is hagyható. Példa:

1 PRINT "4 hajo"
2 PRINT r,y$,a$(3)
3 PRINT "f= ";f
4 PRINT PAPER 2;INK 7;INVERSE 1; BRIGHT 1;"színes"
5 PRINT AT x,y;"barhova"
6 PRINT TAB t;"tabulala"
7 PRINT PAPER 2;INK 7;INVERSE 1;BRIGHT 1;AT 4,13;"vegyes ";INK 5;INVERSE 0;a$

Kiírathatunk tetszőeges, idézőjelek közé tett szöveget (1), változókat (2) akár keverve is (3), megadhatjuk a színeket (4), a helyet vagy az x,y koordinátákkal (5) vagy soron belüli pozícionálással (6), s mindezeket tetszőleges módon vegyíthetjük (7).

x: a sor száma felülről számítva,
y: az oszlop száma balról számítva,
t: az oszlop száma balról számítva.

Megjegyezzük, hogy a TAB-ban megadott oszlopszám kisebb, mint az éppen aktuális pozíció, akkor a következő sor megadott helyén folytatódik a kiírás. A PRINT lezárásához, illetve az egyes kiíratandó egységek elválasztásához a következő jeleket használhatjuk:

; ( pontosvessző) a legközelebbi kiíratás helye,
, (vessző) a következő 16-os mező eleje,
' (aposztróf) a következő sor eleje

Értelemzés:

helyes
hibás
hibaüzenet
0 <= x <= 21
x < 0
B
 
x = 22
5
 
x > 22
B
0 <= y <= 31
x < 0
B
 
x > 31
B
0 <= t <= 65535
t < 0
B
(csak egész)
t > 65535
B

A megadott értéket a gép elosztja 32-vel, s veszi az osztás maradékát, ami mindig kisebb, mint 32.

RANDOMIZE (Véletlenszerűsítés)
Példa:

RANDOMIZE x

Az utasítás segítségével kezdeti értéket adhatunk a véletlenszámot előállító számítási eljárásnak, így a gép által generált véletlenszámok egy adott sorrendben követik egymást. Ha az x-et elhagyjuk, a gép maga állítja be a kezdeti értéket mintegy véletlenszerűen a FRAMES nevű rendszerváltozó felhasználásával, melynek értéke 1/50 másodpercenként növekszik. Értelmezés:

helyes
hibás
hibaüzenet
0 <= x <= 65535
x < 0
B
(csak egész)
x > 65535
B
READ (Olvasás a  DATA sorból)
Példa:

1 READ y
2 READ y$

Az éppen aktuális DATA sorból a soron következő érték az y illetve az y$ változóba kerül. A kiolvasás a legelső DATA elejétől kezdődik, a sorrend a RESTORE utasítással megváltoztatható. Ha numerikus változóba stringet akarunk beolvasni (lásd DATA utasítás!), akkor a C Nonsense in BASIC hibaüzenet figyelmeztet a tévedésünkre. Amikor már az összes DATA-t kiolvastuk s egy újabb READ következik, az E Out of DATA hibaüzenettel leáll a program.

REM (REMark, azaz megjegyzés)
A gép a REM után álló betűket, számokat nem veszi figyelembe.
RESTORE (Visszaállítás)
Példa:

RESTORE x

A legközelebbi READ végrehajtásakor a gép az x-szel megadott számú sorból olvassa ki az adatot, ha ilyen nem létezik, akkor megkeresi a legközelebbi x-nél nagyobb számút. Az x-et el is hagyhatjuk, ilyenkor a legelső DATA sorra ugrik vissza.

RETURN (visszatérés)
Szubrutint lezáró utasítás, hatására a program végrehajtása a GO SUB-ot követő utasítással folytatódik.
RND (véletlenszám előállítás)
Példa:

LET y=RND

Az y változóba 0 és 1 közötti véletlenszám kerül (A 0 benne van, 1 nem.)

RUN (Programfutás elindítása)
Példa:

RUN x

A program végrehajtása az x-szel megadott sorban kezdődik, ha ilyen nem létezik, akkor a gép megkeresi a legközelebbi, x-nél nagyobbat. Ha nem írunk a RUN után sorszámot, akkor a futtatás az első sorral indul. A RUN magába foglal egy CLEAR és egy RESTORE utasítást is, ha ezek végrehajtására nem tartunk igényt, (például azért, hogy ne törlődjön a kép) akkor GO TO-val kell indítanunk a programot. Az értelmezés ugyanaz, mint a GO TO utasításnál.

SAVE
(Kimentés)
Segítségével programot, illetve különböző típusú adatokat rögzíthetünk szalagra. Az utasítás formája ugyanaz, mint a LOAD esetében, annyi eltéréssel, hogy névként itt nem adhatunk meg üres stringet (""), illetve ha a név után beírjuk a LINE 10 kiegészítést, akkor a program betöltés után (LOAD) a 10-es sor végrehajtásával automatikusan elindul.
SCREEN$ (Karakter kiolvasása a képmemóriából)
Példa:

LET k$=SCREEN$(x,y)

A k$ változóba az x,y koordinátájú pozícióban (ugyanaz, mint a PRINT AT-nél) található karakter kerül. A gép csak 32 és 127 közötti kódszámú karaktereket ismeri fel, bármilyen más ábra esetén a K$-ba üres string ("") íródik be. A koordinátákra vonatkozó értelmezés a PRINT AT utasításnál található meg.

SGN (Szignum, azaz előjel)
Példa:

LET x=SGN y

Az x értéke csak az í előjeétől függ.

y>0   x=-1
y=0   x=0
y>0   x=+1

SIN (Szinusz függvény)
Példa:

LET y = SIN x

Az y változóba az x (radiánban megadott) szög szinusza kerül.

SQR (Négyzetgyök függvény)
Példa:

LET y=SQR x

Az y változóba az x négyzetgyöke kerül. Értelmezés:

helyes
hibás
hibaüzenet
x >= 0
x < 0
A
STOP (Megállítás)
Az utasítás megállítja a BASIC program futását, folytatás a CONTINUE paranccsal lehetséges.
STR$ (Numerikus kifejezés karakteressé alakítása)
Példa:

LET y$=STR$ 3*x+2

A művelet fordítottját a VAL utasítás végzi.

TAN (Tangens függvény)
Példa:

LET y= TAN x

Az y változóba az x (radiánban megadott) szög tangense kerül.

TO (String felszeletelése)
Példa:

1 LET a$="abcdefghijk"
2 LET b$=a$(x TO y)

A b$ változóba az a$ x-edit és y-odik elemei közötti rész klerül.

Értelmezés:
Ha x>y vagy x>LEN a$, akkor b$=""
Ha 0<x<LEN a$, de az y>LEN a$, akkor a 3 Subscript wrong hibaüzenetet kapjuk.

USE x (Gépi kódú program indítása)
Példa:

1 RANDOMIZE USR x
2 PRINT USR x
3 LET a=USR x

A fenti utasítások bármelyikével az x-el megadott memóriacímen kezdődő gépi kódú program végrehajtása indítható. Értelmezés:

helyes
hibás
hibaüzenet
0 <= x <= 65535
x < 0
B
(csak egész)
x > 65535
B

Az USR argumentumában álló számot (jelen esetben az x változó tárolja) a gép kerekíti,a táblázat a kerekített értékekre vonatkozik.

USE "A" (UDG karakter helyének megkeresése)
Példa:

LET x=USR "A"

Az x változóba az idézőjelek között álló betűnek megfelelő grafikus karakter mintájának memóriacíme kerül. A megadott betű A-tól U-ig terjedhet (a kisbetűk is érvényesek), minden más esetben az A Invalid argument hibaüzenetet kapjuk.

VAL (String átalakítása számmá)
Példa:

LET x=VAL y$

Az x változóba az y$ stringben levő kifejezés numerikus értéke kerül. A string tartalmazhat számokat, változókat, melyek bármilyen matematikai műveleti jellel összeköthetők.
Értelmezés: Ha az y$ olyan betűt is tartalmaz, amilyen nevű változó nincs definiálva, akkor a 2 Variable not found hibaüzenetet olvashatjuk.

VAL$ (Idézőjelek közé tett string kiértékelése)
Példa:

10 LET x$="""hello"""
20 PRINT VAL$ x$

Lefuttatva a fenti programocskát a képernyőn a hello szöveg olvasható. Ha nincs idézőjelek közé foglalva a string, akkor a C Nonsense in BASIC hibaüzenetet kapjuk.

VERIFY (A kimentett program ellenőrzése)
A parancs hatására a gép összehasonlítja a szalagon levő adatokat, a memória tartalmával, eltérés esetén az R Tape loading error hibaüzenetet kapjuk.

A karakterkészlet

A SPECTRUM által használt karakterek közül a 0-31 kódszámúak az úgynevezett vezérlő karakterek. Ezek nem íródnak ki a képernyőre, ezzel szemben megváltoztatják a kiírás valamilyen paraméterét.

Vezérlő karakterek
0-5
-
6
,
7
EDIT
8
kurzor balra
9
kurzor jobbra
10
kurzor le
11
kurzor fel
12
DELETE
13
ENTER
14
NUMBER
15
-
16
INK
17
PAPER
18
FLASH
19
BRIGHT
20
INVERSE
21
OVER
22
AT
23
TAB
24-31
-

A6-os a PRINT utasítás részeit elválasztó vessző.
A 14-es azt jelzi, hogy az utána következő 5 byte egy számot tartalmaz.
Minden PRINT utasítás leírható vezérlő karakterek segítségével is. Például:

PRINT INK 6;PAPER 2;INVERSE 1;AT 0,10;"HELLO"

PRINT CHR$16; CHR$ 6; CHR$ 17; CHR$ 2; CHR$ 20, CHR$ 1; CHR$ 22; CHR$ 0; CHR$ 10; CHR$ 72; CHR$ 69; CHR$ 76; CHR$ 76; CHR$ 79;

Látható karakterek

Kódszámuk 32-től 255-ig terjed, kis- és nagybetűk, számok írásjelek, grafikus karakterek mellett a BASIC kulcsszavaknak is van azonosító kódszámuk. A 144-164 kódú karakterek az UDG karakterek.

Vissza