Hetedhéten túl
Tartalom
Először is néhány szót arról...
Első hét
1. nap - Képernyővarázs
2. nap - Rohan az idő
3. nap - Hetet egy csapásra
4. nap - Értékes nevekMásodik hét
1.nap - Listázás reggeltől estig
2. nap - Egy kis függvénytan
3. nap - Pontról pontra
4. nap - Alkossunk függvényeket
Harmadik hét
1. nap - Programok egymás közt
2. nap - Alakoskodó jelek
3. nap - Türelmetlen hangok
4. nap - Bit Béla a tanárok rémeNegyedik hét
1. nap - Kívül-belül változó
2. nap - Egy kis matek
3. nap - Kalandozás a csatornák útvesztőjében
4. nap - Csak röviden+1. nap - Ami mindenhonnan kimaradt
1. példaprogram - Kanyargó
2. példaprogram - Hamika
- hogy kiknek szól ez a könyv?
Mindazoknak, akik a HETEDHÉT ENTERPRISE című könyv segítségével már megismerkedtek az ENTERPRISE BASIC alapjaival, és most szeretnének még többet megtudni a gépről. Ehhez nyújtunk segítséget, de természetesen játszani és szórakozni is fogunk.
E könyv összeállításakor feltételeztük, hogy olvasói már ismerik az előző kötet tartalmát. Ezért a HETEDHÉT ENTERPRISE-ban bemutatott utasításokat nem ismertetjük, de sok esetben hivatkozunk rájuk, és minden ilyen esetben megmondjuk, hogy hol, melyik fejezetben olvashattunk már azokról.
Természetesen ez a kötet is csak azoknak a kedves olvasóknak nyújt használható, új ismereteket, akik az ENTERPRISE számítógép előtt ülve lépésről-lépésre követik az egyes napok gondolatmenetét, és minden új programot begépelnek. Ezzel a módszerrel könnyen érthetővé válnak az újonnan bemutatott utasítások.
- hogy miről szál ez a könyv?
Mivel az ENTERPRISE nagyon sok mindent tud, semmiképpen sem vállalhattuk, hogy valamennyi létező utasítását ismertetjük. Ehhez több vaskos kötet sem lenne elegendő. Azok közül a BASIC utasítások közül válogattunk, amelyek az előző könyvből helyhiány miatt kimaradtak, de ezeket is fontos megismernünk, mert sokszor lehet szükségünk rájuk.
Minden tudnivaló természetesen ebbe a kötetbe sem fért bele. A ritkán felmerülő részletekre -a Felhasználói leírás segítségével - minden érdeklődő maga kell, hogy megtalálja a választ. Mindenkit szeretnénk bátorítani, hogy kísérletezzen a még ismeretlen megoldásokkal, mert csak így sajátíthatja el az ENTERPRISE minden csínját-bínját.
- hogy miért négy naposak a hetek?
Aki átolvasta a könyv tartalomjegyzékét, az talán furcsálja, hogy ebben a könyvben minden hétnek csak négy napja van. Ez azonban csak a könyvre vonatkozik, a hét továbbra is hét napból áll. Vajon mi lehet az eltérés oka?
Nos, az előző kötetben minden fejezet végén néhány egyszerű feladatat tűztünk ki, amelyek megoldásával a fejezetben bemutatott újdonságokat lehetett gyakorolni. Most ehelyett a hét három utolsó napját szabadon hagytuk, így ezeken a napokon mindenki kedve szerint maga gyakorolhat.
- hogy mit tartalmaznak az egyes napok?
Minden hét első napján a program begépelésével és a szöveg szerkesztését megkönnyítő dolgokkal foglalkozunk. A hetek második napján új függvényekkel ismerkedünk meg. A harmadik napokon mindig valami különlegesség szerepel. Végül a negyedik napokon a legnehezebb témák következnek, az eljárásokat, azok használatát próbáljuk bemutatni.
A könyv végén két példaprogramot is közreadunk. Ezek egyszerű, szórakoztató játékprogramok, s egyúttal jó példát mutatnak arra, hogy hogyan oldhatunk meg az ENTERPRISE BASIC eszköztárával bonyolultabb feladatokat is.
- s végül, hogy mire van szükség ahhoz, hogy megtanuljunk programozni?
Elsősorban kitartásra és kísérletező kedvre. Nem vállalkozhattunk a mindenttudó lexikon szerepére, a legapróbb részletek kidolgozására. Sok olyan probléma merülhet fel, amelyekre mindenki saját maga kell, hogy megkeresse a megoldást. Minden új ötletünket próbáljuk ki, kérdéseinkre így kaphatunk feleletet.
Állandó kísérletezgetéssel megismerhetjük az ENTERPRISE minden csínját-bínját. Számítógépünk tőle telhetően megpróbál segíteni nekünk, ha hibázunk hibaüzenetet küld, de ne feledjük, hogy csak gép, a megoldást mindig nekünk kell megtalálnunk!
Jó szórakozást!
Ma a képernyővel, a rajta megjelenő betűkkel, szavakkal fogunk játszani. Ehhez azonban először írnunk kell a képernyőre. Erre a célra a következő program felel meg. Futtassuk le!
10 FOR 1=1 TO 20
20 FOR J=1 TO I
30 PRINT " ";
40 NEXT
50 PRINT "szavacska"
60 NEXT I
A kép most tele van a "szavacska"-val, a kurzor pedig baloldalt alul villog. Ha bármelyik felső sorba szeretnénk valamit írni, akkor a botkormánnyal mozgatva a kurzort szépen fellépkedhetünk abba a sorba, amelyik nekünk kell és beírhatjuk, amit akarunk. Mennyivel egyszerűbb lenne, ha egyetlen mozdulattal a kép tetejére ugorhatnánk! Igen ám, de ha a botkormánnyal mozgatjuk a kurzort, akkor az mindig csak egyet-egyet lép, a következő sorra. Hogyan lehet ugrani vele?
Erre való a SHIFT billentyű. Nyomjuk le a SHIFT-et, majd egy pillanatra toljuk előre, felfelé a botkormányt! Hopp, a kurzor maris ott van a képernyő tetején. Ismét lenyomva a SHIFT-et, és közben lefelé, magunk felé döntve a botkormányt, a villogó pont vissza kerül a kép aljára. Ha tehát a SHIFT-tel együtt használjuk a botkormányt, akkor nem egy sornyit, hanem egy egész képernyőnyit lépteti a kurzort.
Még jobban látjuk ezt, ha már több oldalt is teleírtunk. Futtassuk le néhányszor egymás után a fenti programot! A gép sorra írja ki a "szavacská"-kat, a korábbi sorok pedig rendre eltűnnek a kép felső szélénél. De nem örökre! Nyomjuk le a SHIFT-et és léptessük a kurzort felfelé, de egymás után kétszer! Az első ugrás után a villogó pont a legfelső sorba kerül. Amikor másodszor is felfelé léptetjük, észrevesszük , hogy a korábban eltűnt sorok újra előbukkannak, a gép egyet lapoz visszafelé. Ha most lefelé ugratjuk kétszer a kurzort, a SHIFT-et használva, akkor ismét a legutolsó teleírt lap tűnik fel. Tanulság: a képernyő tetején eltűnő sorokat a gép megjegyzi, azokra vissza tudunk menni a kurzorral, akár egyenként lépegetve a sorokon, akár egész lapokat átugorva. A laponkénti mozgatáshoz a botkormányon kívül a SHIFT billentyűt is le kell nyomnunk.
De vajon mi történik, ha nem előre-hátra, hanem jobbra vagy balra döntjük a botkormányt? Próbáljuk ki! Menjünk az egyik olyan sorba, ahol van egy "szavacska"! Nyomjuk le a SHIFT-et és döntsük jobbra a botkormányt! A kurzor a sor végére ugrik, pontosabban a sorban levő legutolsó szó végére. Ha balra döntjük a botkormányt, a sor elejére tudunk lépni. Menjünk néhány sorral feljebb vagy lejjebb és ott is próbáljuk ki ezeket! Mivel most máshol van a legutolsó szó vége, ezért a botkormány jobbra mozgatásával másik oszlopba ugrik a kurzor.
A SHIFT billentyűvel tehát megnöveljük a botkormánnyal mozgatott kurzor lépéseit. Más billentyűk hatását nem tudjuk megnövelni? Dehogynem! Például az ERASE és a DEL billentyűkét. Menjünk a kurzorral valamelyik "szavacska" közepére és a SHIFT-tel együtt nyomjuk le a DEL billentyűt! Minden, ami a kurzortól jobbra van egyszerre eltűnik. A sor végéig mindent kitöröltünk. Próbáljuk ki az ERASE billentyűt is! Válasszunk ki egy másik "szavacskát" és ennek is menjünk a közepére a kurzorral! Nyomjuk le a SHIFT-et és az ERASE-t, ekkor minden, ami a kurzortól balra van egy csapásra törlődik, a kurzortól jobbra levő szöveg pedig a kurzorral együtt a sor elejére kerül. Ha tehát a törlésre szolgáló billentyűk bármelyikét (DEL, ERASE) a SHIFT-tel együtt nyomjuk le, akkor nemcsak egyetlen betű tűnik el, hanem minden, ami a kurzor előtt vagy mögött van. Ha sor elején vagy végén használjuk ezeket, akkor az egész sort ki tudjuk üríteni.
Töröljük le a képernyőt (F5) és futtassuk le újra a programot! Ismét szép szabályosan sorakoznak egymás alatt a "szavacskák". Most menjünk oda az egyik "szavacska" közepére, a c-re! Nyomjuk le a SHIFT és az INS billentyűket egyszerre! A sor hirtelen kettétörik, ami a kurzortál balra volt az ugyanott marad, de ami jobbra, az átkerül a következő sor elejére.
...szavacska
szavacska
szava
cska
szavacska
szavacska
A SHIFT tehát az INS billentyű hatását is megsokszorozza, ha a kettőt együtt használjuk nem egyetlen betűnyi helyet, hanem egy fél sort teszünk szabaddá. A szabad helyre most bármit beírhatunk. írjuk be a következőt: "lo". Most már csak a sor végét kellene visszahozni, hogy kialakuljon a "szavalocska". De hogyan?
A megoldás a következő: ellenőrizzük, hogy a kurzor a "szavalo" felirat végén, az o betű utáni szabad helyen áll-e? Ha a "lo" beírása után nem mozdítottuk el a kurzort, akkor éppen já helyen van. Most nyomjuk le a DEL gombot! A kettétört sor újra összeforr!
...szavacska
szavacska
szavalocska
szavacska
szavacska
Ha tehát egy sor végén lenyomjuk a DEL-t, akkor a következő sort mintegy hozzáragasztja az elázó sor végéhez. Ezt nemcsak akkor tehetjük meg, ha egy sort előzőleg kettétörtünk, hanem bármelyik sor végén kipróbálhatjuk. Nosza! Menjünk valamelyik utolsó "szavacska" végére, pontosabban az utánna ál1ó üres helyre és nyomjuk le a DEL-t! A következő sor eltűnik, de a mi sorunkban sem jelenik meg új szöveg, csak a képernyő bal szélén egy jobbra mutató nyilacska. Vajon mi történt? Semmi vész, csak azt jelzi ezzel a gép, hogy ebbe a sorba az újonnan bevitt szöveg már a képernyőn nem fér el, de attól az még létezik, éppen erre utal a kis nyíl.
Törjük ketté a sort, nyomjuk le a SHIFT-et és az INS-t együtt! Most újra előbukkan az eltűnt sor. Ha tehát olyan hosszá sort ragasztunk az előző végére, amelyik a képernyő méretei miatt már nem fér ki, azért az nem veszik el. Létezik, a gép megjegyezte, csak nem látható. Erre a ki nem irt szövegrészre figyelmeztet a kis nyíl. Ha a hozzáragasztott rész is kifér, akkor természetesen minden gond nélkül azt is látjuk az előző sor végén. Próbáljuk ki! Menjünk az egyik első sorban levő "szavacska" végére, az utána levő szóközre, és nyomjuk le a DEL-t!
szavacska
szavacska szavacska
szavacska
szavacska...
Mivel ezek rövid sorok, így a két sor együtt is kifért a képernyőre, tehát szépen összeolvadtak. Az újonnan keletkezett sort, amiben két "szavacska" van, persze ügyesen kettétörhetjük, és akkor ismét viszaáll az eredeti rend. Oldjuk meg ezt már önállóan!
Ragasszuk össze az összes "szavacskát" egyetlen sorrá! Ha ügyesen dolgoztunk, akkor a képernyőn ezt látjuk:
szavacska szavacska szavacska sz>
Vigyázzunk, nem mindegy, hogy milyen sorrendben kezdjük el a sorok összevonását! Ha sikerült, akkor próbáljuk meg széttördelni úgy, hogy az eredeti képet kapjuk vissza! Ha valahol elrontjuk, nem kell elkeseredni! Töröljük le a képet (F5), futtassuk le a programot (F1) és próbáljuk meg újra!
Lépjünk egy kicsit tovább! Azt már tudjuk, hogyan lehet egy sort kettétörni, de vajon hogyan lehet egy teljesen új sort beszúrni a már meglevők közé? Nekünk már ez sem okozhat gondot! Tudjuk, hogy ha egy sor közepén a SHIFT és az INS billentyűket egyszerre nyomjuk le, akkor a sor kettétörik, azaz minden ami a kurzortól jobbra volt átkerül a következő sorba, miközben a kurzortól balra levő dolgok nem változnak. Mi történik, ha tőle balra semmi sincs? Ha éppen egy sor elején állunk, akkor minden jobbra van a kurzortál, tehát minden átkerül a következő sorba, itt pedig egy új üres sor keletkezik. Ugye milyen egyszerű új sort beszúrni! Próbáljuk ki! Töröljük le a képernyőt és futtassuk le a programot! A sorok elejére állva szúrjunk be néhány új sort!
De ha be tudunk szúrni sorokat, akkor törölni is tudnunk kell őket! Természetesen ennek sincs akadálya. Álljunk az üres sor végére! A végére? De hát hol van az üres sor vége? Az elején!
Hiszen nincs benne semmi. Ha most lenyomjuk a DEL-t, akkor a következő sort a gép összevonja a jelenlegivel, de mivel, ebben nincs semmi, tehát csak annyi történik, hogy az üres sor eltűnik, kitörlődik. Ilyen könnyű törölni egy üres sort.
És egy nem űreset? Nos, azt előbb ki kell üríteni! De hogyan? Erről ma már volt szó! Álljunk a sor elejére és a SHIFT-tel együtt nyomjuk le a DEL-t! Az egész sor kiürül. Most nyomjuk le újra a DEL-t, de most már a SHIFT nélkül! Az üres sor kitörlődik.
Próbáljuk ki a most tanultakat! Töröljük ki a szövegből az üres sorokat, majd néhány néhány olyan sort is, amelyik nem üres! Ha sikerült, akkor próbáljunk meg üres sorokat beszúrni és azokba beírni a hiányzó "szavacskákat" úgy, hogy visszaálljon az eredeti szólépcső!
Töröljük le a képernyőt és írjuk le a nevünket, pl.: Kiss Antal
Most tördeljük szét úgy, hogy minden betűje egy-egy új sor elejére kerüljön:
K
i
s
s
A
n
t
a
l
Ragasszuk össze újra a sorokat, rakjuk eredeti helyükre a betűket! Tördeljük szét ismét és szúrjunk be egy-egy üres sort a betűk közé! Ragasszuk megint össze a sorokat! Ha ügyesen csináljuk, összerakás közben az üres sorokat el tudjuk tűntetni!
Jó kísérletezgetést!
Ha pedig lépést akarunk tartani az idővel, akkor jó ha tudjuk, mit mutat az óra. Gépeljük be a következő programot és indítsuk el!
10 CLEAR SCREEN
20 DO
30 PRINT AT 10,10:TIME$
40 LOOP
A képernyőn feltűnik egy óra. Sőt, szépen lépeget is, másodpercenként. De hát hogy kerül ez oda? Nézzük meg a programot!
Az elején töröljük a képet, majd végtelen ciklusban kiírunk valamit a tizedik sor tizedik oszlopába. Méghozzá a TIME$ nevű szöveg típusú változó tartalmát. De vajon mit rejt ez a változó? Mi már tudjuk, hogy egy órát, hiszen láttuk a programot dolgozni, láttuk mit ír ki.
Igen ám, de hogyan lehet tartalma a TIME$ változónak, amikor mi nem írtunk bele semmit? Eddig úgy tudtuk, hogy egy változó tartalmát csak akkor olvashatjuk ki, ha előzőleg beirtunk már oda valamit. Ellenkező esetben a gép hibát jelez. Ráadásul ennek a változónak a tartalma másodpercenként változik, anélkül, hogy a program bármit is csinálna?
Nos, a TIME$ nem közönséges változó. Ezt maga az ENTERPRISE már jó előre létrehozza a mi utasításunk nélkül. Amikor bekapcsoljuk a gépet, akkor csupa nullát ír bele, majd másodpercenként eggyel növeli. Ez tehát egy olyan óra, amelyik mindig a gép bekapcsolásakor indul és az azóta eltelt időt mutatja. Hogy könnyebben lehessen leolvasni, az órák, a percek, és a másodpercek közé kettőspontot tesz.
És ezt az órát be sem lehet állítani? Dehogynem! De hogyan? Legelőször az jut az ember eszébe, hogy hasonlóan a többi változóhoz, ebbe is az értékadó utasítással lehet írni. Próbáljuk ki! Először a STOP gombbal állítsuk meg a futó programot, majd írjuk be a következő sort:
5 LET TIME$="12:34:56"
Most indítsuk el a programot! Azt várjuk, hogy az ára 12:34:56-rál indul, és szépen lépeget. De nem. Mintha elromlott volna, meg se mozdul. 12 óra 34 perc 56 másodpercen áll. Vajon miért?
Azt már tudjuk, hogy a TIME$ változó különbözik a többitől, hiszen ezt már előre létrehozza a gép és másodpercenként változtatja. Újdonság, hogy írni is másként lehet bele, mint a többi változóba. Ha egy értékadó utasítással próbálkozunk, akkor a gép azt hiszi, hogy mi magunk szeretnénk valamit egy TIME$ nevű változóba eltenni, ezért a saját, korábban létrehozott TIME$ változóját elrejti, helyette létrehoz egy újat, amit mi használhatunk. Ezt az új változót viszont már nem fogja másodpercenként változtatni, hiszen nem tudhatja, mit irtunk bele. írhatnánk bele egy nevet, valami üzenetet vagy bármi mást is.
A saját TIME$ változóját persze nem törli ki, továbbra is növelgeti, csak mi nem láthatjuk. Azért nem tudunk ennek az értékéhez hozzáférni, mert a TIME$ név számunkra most nem a belső órát, hanem egy teljesen hétköznapi változót jelöl. A programunk jó1 működött, hiszen az ötös sorban beírtunk valamit egy változóba, azután pedig újra meg újra kiolvastuk és kiírattuk a képernyőre. Ha ismét a belső órát szeretnénk kiolvasni, akkor állítsuk meg a programot a STOP billentyűvel, töröljük ki az ötös sort, és újra indítsuk el! Most már szépen fut az óra.
De hát akkor hogyan lehet tetszés szerinti időre beállítani ezt az árát? Erre egy külön utasítás szolgál. Na azért nem kell megijedni, nem olyan bonyolult ez, könnyen meg lehet jegyezni, az utasítás ugyanis a TIME. (ejtsd: tájm, magyarul: idő)
A TIME utasítás után egy szöveget kell megadnunk, ami lehet idézőjelek között beirt szöveg, de persze egy szöveg típusú változó is. Ennek tartalmát használja majd a gép. A beírt szöveg pontosan ugyanolyan formában kell hogy tartalmazza az időt, ahogy azt a gép belső órájában, a TIME$ változóban van. Tehát elöl áll az óra, két számjeggyel kiírva, utána kettősponttal elválasztva a perc, majd a másodperc. Próbáljuk ki! írjuk be a következő sort és indítsuk el a programot!
5 TIME "13:24:35"
így, most már sikerült beállítanunk az órát. A TIME utasításban természetesen változót is megadhatunk, sőt, akár a TIME$ változót is, de ez utóbbinak nyilvánvalóan nincs semmi értelme.
A gép nem csak ezt az egy ilyen különleges változót ismeri. A TIME$-hoz hasonlóan létezik egy DATE$ is. (Date, ejtsd: dét, magyarul dátumot jelent.) A DATE$ a dátumot tartalmazza, pontosabban a gép bekapcsolásakor 1980 nulladik hó nulladikáról - ami nincs is - indul, és csak naponta változik egyet. Éppen ezért csak akkor van igazán jelentősége, ha több napig folyamatosan működtetjük a gépet, ami elég ritka, meg nem is nagyon használ neki. A DATE$ kicsit más formában tartalmazza a dátumot, mint a TIME$ az időt, itt ugyanis nincsenek elválasztó kettőspontok az évet, a hónapot és a napot jelölő számok között. A DATE$ változót a DATE utasítással tudjuk beállítani, hasonlóan ahhoz, ahogy a TIMES-t a TIME-mal. A beállítandó dátum formája meg kell hogy egyezzen a DATE$ változóban használttal.
Vannak más olyan változók is, amelyeket a gép tőlünk függetlenül hoz létre és rendszeresen megváltoztatja tartalmukat. Ilyen az INKEY$. Az INKEY$ változóban mindig egyetlen betű van, méghozzá az a betű, amit éppen lenyomva tartunk. Ha nem nyomunk le egyetlen billentyűt sem, akkor az INKEY$ egy üres szöveg, amit - emlékezzünk -két egymás mellé irt idézőjellel tudunk jelölni. Ha tehát azt mondjuk, LET BETU$=INKEY$, az (majdnem) ugyanaz, mintha azt írtuk volna, GET BETU$. (A GET utasítást a HETEDHÉT ENTERPRISE második hetének 6. napján ismertük meg.)
Ha van óránk, és tudunk számolni, akkor akár világórát is készíthetünk. Hiszen az egyes földrajzi helyeken a pontos idő időzónánként változik, csak annyiban különbözik a budapestitől, hogy egy-egy órával kevesebbet (nyugatabbra fekvő helyeken) illetve többet (keletebbre) mutatnak ott az órák. Térkép segítségével bármelyik városról meg tudjuk állapítani, hogy hány időzónával (tehát hány órával) és milyen irányban (tehát + vagy -) kell számolnunk. Igen ám, de hogyan tudunk számolni az idővel, amikor a pontos idő nekünk szöveges változóban van megadva, a szövegeket pedig nem lehet összeadni vagy kivonni? Számolás előtt számokká kell alakítanunk azokat! Erre szolgál a VAL függvény, amelynek a neve az angol value (ejtsd: velju) szóból származik. A value jelentése érték, és ez a függvény valóban a megadott szövegnek megfelelő értéket szolgáltatja, de már mint számot. Gépeljük be és indítsuk el a következő programot!
10 TIME "12:04:34"
20 CLEAR SCREEN
30 PRINT :PRINT
40 PRINT" A pontos ido"
50 DO
60 PRINT AT 10,1:" Pesten";
70 PRINT TIME$(1:2);" ora, ";
80 PRINT "Londonban";
90 LET X=VAL(TIME$(1:2))
100 LET X=X-1
110 PRINT X;"ora "
120 PRINT
130 PRINT ,TIME$(4:5);" perc, ";
140 PRINT TIME$(7:8);" masodperc";
150 LOOP
A program szépen kiírja a budapesti és a londoni pontos időt. (Ha jól állítottuk be az órát a tízes sorban.) Az órát, percet, másodpercet úgy tudjuk a TIME$ szövegből külön-külön kiolvasni, hogy a szöveg mögött zárójelben megadjuk, hányadik betűtől hányadik betűig terjedő részletre van szükségünk. (pl.: az órák száma=TIME$(1:2) ) Ezt a megoldást már a HETEDHÉT ENTERPRISE-ban megismertük. Számunkra most a 90-es sor az érdekes, ahol a VAL függvényt használtuk. Ezzel a függvénnyel az órák számát szövegből számmá alakítottuk, majd - még mindig a 90-es sorban - betöltöttük az X nevű változóba. Ha nem alakítottuk volna számmá, akkor nem tudnánk számváltozóba tölteni, tehát a 100-as sorban nem tudnánk eggyel csökkenteni. (Azért kell eggyel csökkentenünk, mert London Budapesttől egy időzónával nyugatra van.)
A VAL függvény tehát szövegeket, karaktersorozatokat alakít számmá. Jó tudnunk, hogy ez a függvény csak addig olvassa el az utána beírt szöveget, amíg olyan jelet, betűt nem talál, ami már nem lehet a szám része. Így:
Figyeljük meg, hogy a budapesti és a londoni idő kiírása között formai eltérés van. A fenti programunk azokat a számokat, amelyeket egy szöveg részeként iratunk ki, mindig két számjeggyel jelzi. Így a budapesti időt 10 ára előtt egy nullával kezdődő kétjegyű számmal írja ki. Ugyanezek a 10 óra előtti időpontok a londoni idő kiírásánál már egy számjegyűek, mert azt számváltozóban adtuk meg és a számokra ez a szabály érvényes. Próbáljuk ki! Indítsuk el a programot úgy, hogy a tízes sort átjavítjuk és 05:45:40-et adunk meg benne. Figyeljük meg a pesti és a londoni idő kiírása közti különbséget! Próbáljuk meg kiküszöbölni az eltérést!
Még egy hibát rejteget a program, akinek kedve van, megpróbálhatja kijavítani. A jelenlegi program ugyanis, amikor Pesten nulla óra van, Londonban -1 órát jelez. Ez a hiba nem a VAL függvény tulajdonságaiból fakad, ezért itt nem is foglalkozunk vele, de szórakoztató feladat megkeresni az okát és kiküszöbölni.
A VAL függvény ellentettje az STR$ függvény. Ez éppen arra szolgál, hogy használatával számokat szöveggé alakítsunk. Vajon mire jó ez? A következő program például kiírja, hogy hány számjegyből áll a beolvasott szám:
10 DO
20 CLEAR SCREEN
30 PRINT "Adj meg egy szamot=";
40 INPUT SZAM
50 PRINT
60 LET SZAM$=STR$(SZAM)
70 PRINT " A ";SZAM;" ";
80 PRINT LEN(SZAM$);
90 PRINT " szamjegybol all";
100 WAIT 5
110 LOOP
Ezt a feladatot az STR$ függvény nélkül is meg tudnánk oldani, de csak sokkal bonyolultabb módon. Vállalkozó kedvnek kísérletezhetnek vele! Az itt leírt megoldás viszont olyan magától érthetődő, hogy szinte nem is kell hozzá magyarázat. A SZAM-ot az STR$ függvénnyel szöveggé alakítjuk (SZAM$), majd a LEN függvénnyel megnézzük a hosszát. Emlékezzünk, hogy a LEN függvény egy szövegben levő karakterek számát adja meg. A program majdnem tökéletes, kis szépséghibája, hogy negatív vagy törtszámokra hibás eredményt ad, mivel az előjelet és a tizedespontot is számjegyként kezeli, az STR$ függvény ugyanis ezeket is elhelyezi az általa készített szövegben.
Még két olyan függvény van, a CHR$ és az ORD, amivel érdemes most megismerkednünk. Ezekkel a függvényekkel a gép minden egyes betűjét, jelét el tudjuk érni. A számítógép minden egyes létező jeléhez tartozik egy-egy szám. A karakterkészlet minden elemének van egy sorszáma, nullától egészen 255-ig. Az "A" sorszáma például 65. A kis i betűé 105. A billentyűk között ugyan nem található a magyar abc ékezetes kis á betűje, de azért a gép ezt is ismeri, ennek a sorszáma 149.
Ha egy betűnek ismerjük a sorszámát, de a billentyűkkel nem tudjuk begépelni, akkor a CHR$ függvénnyel mégis kiírhatjuk. A CHR$(149) például az á betűt jelenti. Próbáljuk ki!
PRINT "L";CHR$(149);"da"
Láda
Az á betű helyett a CHR$ függvényt használtuk, és megadtuk neki, hogy a 149-es sorszámú betűre van szükségünk. Nyugodtan kísérletezzünk más számokkal is, a gépet nem tudjuk elrontani, de ne lepődjünk meg, ha néha furcsa dolgok történnek. A gép bizonyos karaktereket ugyanis nem szokványos betűként értelmez, hanem különleges vezérlőkarakterként, s ilyenkor bizony meglepő dolgokat tapasztalhatunk. Ha netán sikerülne olyan bonyodalmat okoznunk, hogy már mi se értjük, mi történik, csak nyomjuk meg a hátsó, piros újraindító gombot. Azért nem árt megjegyezni, melyek azok a karakterek, amelyek miatt a gép butaságot csinál, hogy ezeket lehetőleg ne használjuk.
A következő program egy írógépet utánoz, és az különlegessége, hogy képes jelezni a sor végét, ki is írja azt! A sor végét onnan ismeri fel, hogy a 13-as karaktert olvassa be, ami az ENTER billentyű sorszáma. Gépeljük be és próbáljuk ki!
10 CLEAR SCREEN
20 DO
30 FOR I=1 TO 25
40 DO
50 LET A$=INKEY$
60 LOOP UNTIL A$<>""
70 IF ORD(A$)=13 THEN EXIT FOR
80 PRINT A$;
90 NEXT I
100 PRINT "*ITT A VELE"
110 LOOP
A programban sehol sem használtuk a CHR$ függvényt, de nem is volt szükség rá. Használtuk viszont a ORD-ot. Ez a CHR$ ellentettje, azaz ha megadunk neki egy karaktert, meghatározza annak a sorszámát. Ha az ENTER billentyűt lenyomjuk, akkor a program a 13-as sorszámú karaktert olvassa be. A program ezt az IF feltételben vizsgálja, és ha ilyet talál, akkor félbehagyja a FOR ciklust, és kiírja a sor végét. A következő programmal bármelyik billentyűről megtudhatjuk, hogy mennyi a sorszáma:
10 DO
20 DO
30 LET A$=INKEY$
40 LOOP UNTIL A$<>""
50 PRINT " A ";A$;" sorszama=";ORD(A$)
60 LOOP
Indítsuk el a programot! Ha bármelyik billentyűt leütjük, a gép kiírja a megfelelő betűt és a sorszámát is. Ne felejtsük el, hogy az egyes billentyűk a SHIFT, ALT vagy a CTRL billentyűkkel együtt lenyomva mást jelentenek, mint önmagukban! A CHR$ és az ORD függvénnyel még sokszor fogunk találkozni, mint ahogy az STR$ és a VAL függvénnyel is. Sokat segítenek programjainkban, bátran kísérletezzünk velük!
A program szavait, parancsainkat eddig legtöbbször betűről betűre be kellett gépelnünk. Voltak azonban már olyan parancsaink is, amelyeket sokkal gyorsabban, egyszerűbben, egyetlen billentyű lenyomásával is ki tudtunk adni. Ilyen például a TEXT (F5), a START (F1), vagy a LIST (F2). Ezeket a parancsokat egy-egy funkcióbillentyűvel tudjuk leírni. De vajon miért pont ezeket? És más utasításokat nem lehet így kiadni?
Amikor bekapcsoljuk a gépet, akkor az minden funkcióbillentyűhöz (a felső sorban levő kék gombok) hozzárendel egy-egy meghatározott szöveget. így az F1 billentyűhöz a START-ot, az F2-höz a LIST-et, és így tovább. Ha azonban szükségünk van rá, bármikor meg is tudjuk ezeket változtatni. Ehhez a SET FKEY parancsot kell használni. Példaként rendeljük a hatos funkcióbillentyűhöz a PRINT szót, amit egyébként is gyakran használunk:
SET FKEY 6 " PRINT "
A SET FKEY után a funkcióbillentyű számát adtuk meg (6), majd a kívánt szöveget, természetesen idézőjelek között. Azért tettünk egy-egy szóközt a PRINT szó elé és mögé, hogy majd a programban el tudjuk választani az előtte és utána álló szótól. Figyeljük meg azt is, hogy a SET KEY parancsban nem vesszőkkel, hanem egyszerű szóközökkel különítettük el a billentyű számát és a kívánt szöveget. Ha most írunk egy programot, akkor a PRINT legépelése helyett elég az F6 billentyűt leütnünk. Próbáljuk ki a következő sorokkal:
10 PRINT "Ezek a funkciobillentyük"
20 PRINT "igazan nagyon hasznos"
30 PRINT "segitotarsak"
40 PRINT "a programozasban"
Most próbálkozzunk valami mással. Azt már a HETEDHÉT ENTERPRISE-ban olvashattuk, hogy a képernyő törlését a CLEAR SCREEN parancs végzi, az F5 billentyűvel kiadható TEXT parancs egy kicsit mást csinál. írjuk át az F5 billentyűt úgy, hogy a CLEAR SCREEN parancsot lehessen vele kiadni!
SET FKEY 5 "CLEAR SCREEN"
Most nyomjuk le az F5-öt! A képernyőn megjelenik ugyan a CLEAR SCREEN felirat, de a gép nem törölt le semmit. Ahhoz, hogy a parancsot végre is hajtsa a gép, elébb az ENTER-t is le kell ütnünk. Eddig, ha a TEXT parancsot használtuk az F5 billentyűvel, nem kellett még külön ezt is lenyomnunk. A TEXT parancs ebben is különbözne a CLEAR SCREEN-től? Nem, az eltérés nem a két utasítás között van, hanem abból fakad, hogy ha egy funkcióbillentyűvel kiíratott szöveg után automatikusan az ENTER gombot is le akarjuk ütni, akkor ezt külön jelezni kell, azaz a SET FKEY parancsban a szöveg végére oda kell írjuk az ENTER gombot is.
Odaírni egy billentyűt? De hogyan? No hát nem az ENTER szót kell begépelnünk, hanem az ENTER billentyű kódját kell megadnunk. Az előző fejezetből tudjuk, hogy ez a billentyű a 13-as sorszámú. A sorvégjelet tehát a CHR$(13) függvényhívással tudjuk leírni. Ha pedig egy ilyen jelet akarunk egy szöveghez hozzácsatolni, akkor a & jelet kell használnunk. (Ha nem emlékszünk, olvassuk el újra a HETEDHÉT ENTERPRISE első hetének 6. napján leírtakat!) A helyes parancs tehát a következő:
SET FKEY 5 "CLEAR SCREEN"&CHR$(13)
Próbáljuk ki ismét az F5 billentyűt! Most már tökéletesen működik. Bármelyik funkcióbillentyűt szövegét megváltoztathatjuk. Azt sem árt tudnunk, hogy ha egy funkcióbillentyűt a SHIFT gombbal együtt nyomunk le, akkor más lesz a hatása, mint nélküle. Ha ezeket a szövegeket akarjuk megváltoztatni, akkor a SET FKEY parancsban nyolccal nagyobb számot kell megadnunk, mint eredetileg. Az F1 billentyű a SHIFT-tel együtt a CONTINUE parancsot jelenti. (Lásd HETEDHÉT ENTERPRISE első hét 3. nap!) A következő parancs kiadása után azonban egészen mást. Próbáljuk ki!
SET FKEY 9 "Jajdejo!!"
Aki sok programot ír, annak célszerű is a leggyakrabban használt utasításokat olyan funkcióbillentyűhöz rendelni, amelyeket egyébként ritkán használ. Például a TEXT parancsot (F5) lecserélhetjük a PRINT utasításra, a GRAPHICS-et (F6) a DO-ra, a DISP.GRAPHICS-et (SHIFT+F6) a LOOP-ra.
Ha már teljesen összekevertük az egyes funkcióbillentyűk szövegeit és szeretnénk az eredeti állapotot visszaállítani, akkor erre több lehetőségünk is van. A legunalmasabb megoldás az, ha egyenként minden billentyűhöz hozzárendeljük az eredeti szövegét. A legdurvább, ha egy pillanatra kihúzzuk a gépet, aztán újra bekapcsoljuk. Ezzel mindent kitörlünk, de a billentyűk is visszakapják eredeti jelentésüket. Az is egy megoldás, ha a gép hátulján levő piros újraindító gombot nyomjuk meg, ezzel a programot nem töröljük ki, de a funkcióbillentyűk visszaváltoznak. Ennek a megoldásnak egyetlen apró hibája van: program közben nem lehet használni, ugyanis az újraindító gomb hatására a gép félbeszakítja a programot és megáll. Márpedig a SET FKEY parancs programon belül is használható. Hogyan lehet akkor program közben megszüntetni az általunk bevitt változtatásokat?
Erre egy külön utasítás szolgál, a CLEAR FKEYS. A következő program először megváltoztatja az F1 billentyű hatását, majd az új paranccsal visszaállítja az eredetit. Hogy erről meggyőződhessünk, arra is lehetőséget ad, hogy kipróbáljuk a billentyűt. (Ha nem emlékeznénk arra, mit csinál a DEF utasítás, olvassuk el a HETEDHÉT ENTERPRISE harmadik hetének 4. napját!) Futtassuk le!
10 SET FKEY 1 "EZ MAR MAS"&CHR$(13)
20 CALL PROBA
30 CLEAR FKEYS
40 CALL PROBA
50 DEF PROBA
60 PRINT "Nyomd le az F1 billentyut!"
70 INPUT A$
80 PRINT A$
90 END DEF
Egy- egy billentyű lenyomásakor a gép mindig rövid pittyenéssel jelzi, hogy észrevette a billentyűt. Ez kényelmesebbé teszi a gépelést, mert ha nem eléggé nyomunk le egy gombot, akkor a hang elmaradásából könnyen észrevehetjük, hogy baj történt és kijavíthatjuk a hibát. Vannak azonban olyan programok, ahol ez gondot okoz. írjuk be és indítsuk el a következőt!
10 DO
20 RESTORE
30 FOR I=1 TO 6
40 DO
50 GET A$
60 LOOP UNTIL A$<>""
70 READ HANG HOSSZ
80 SODUND PITCH HANG,DURATION HOSSZ
90 NEXT I
100 LOOP
110 DATA 37,10,41,10,44,10,49,10,44,10,41,10
A READ, SOUND és a DATA utasításról a HETEDHÉT ENTERPRISE harmadik hetének 4. napján olvashattunk. A program minden billentyű lenyomásakor egy-egy hangot játszik egy kis dallambál. Igen ám, csakhogy az egyes billentyűk lenyomását a billentyűhang is kíséri. Hogyan lehetne ezt a kattogást a dallamból eltüntetni? Nos, a billentyűhang angol neve, amit a gép is használ, KEY CLICK. Ezt ki lehet kapcsolni a SET KEY CLICK OFF utasítással. Próbáljuk ki, írjuk be a következő sort:
5 SET KEY CLICK OFF
Most indítsuk el a programot! A kattogás megszűnt. Kikapcsoltuk. Ha azonban megállítjuk a programot, akkor már újra jó lenne bekapcsolni, hiszen a gépelésnél sokat segít. Erre szolgál a következő parancs:
SET KEY CLICK ON
Gépeljük is be! A billentyűhang újra szól. Láttuk, hogy a két parancs alig különbözik egymástól. A SET szó azt jelenti, beállítani valamit. Ezután kell megadnunk, hogy mit akarunk beállítani. Oda is írtuk: KEY CLICK, azaz a billentyűhangot. Azt, hogy be vagy ki kell kapcsolni, a parancs végén álló ON (be) vagy OFF (ki) szócska határozza meg.
Arra is van lehetőség, hogy a billentyűhangot átkapcsoljuk, azaz ha be volt kapcsolva, akkor ki és fordítva. Valamit átkapcsolni a TOGGLE paranccsal lehet. A billentyűhang átkapcsolására a TOGGLE KEY CLICK utasítás vonatkozik. Ezt a parancsot az F7 billentyűvel is kiadhatjuk. Próbáljuk ki! Nyomjuk le az F7-et, majd gépeljünk néhány sort! A billentyűhang nem szól. újra lenyomva az F7-et, ismét hallhatóvá válik.
A SET és a TOGGLE parancsok nemcsak erre használhatók. Ezekkel más szolgáltatásokat is ki-, be- vagy átkapcsolhatunk. Ilyen például a beépített hangszóró, melynek angol neve SPEAKER. Kikapcsolhatjuk a SET SPEAKER OFF, be a SET SPEAKER ON utasítással. Átkapcsolhatjuk a TOGGLE SPEAKER utasítással, de ugyanezt érjük el, ha az F7 és a SHIFT billentyűket együtt nyomjuk le.
Próbaképpen nyomjuk le egyszerre a SHIFT-et és az F7-et! Ezzel, ugye, a TOGGLE SPEAKER parancsot adtuk ki, meg is jelenik a képernyőn. Most indítsuk el a programot! Hiába nyomogatjuk azonban a billentyűket, most nem szól, ugyanis a hangszóró ki van kapcsolva. Ha most a STOP gombbal megállítjuk a programot, bekapcsoljuk a hangszórót, és újraindítjuk a gépet, akkor a hangok megint hallhatóak.
Tapasztaltuk, hogy a BASIC nyelvben saját külön nevük van a változóknak, a függvényeknek, de az eljárásoknak - másnéven DEF blokkoknak - is. Ezeknek a neveknek értéket is adhatunk. A változó értéke az a szám vagy szöveg, amit a változó éppen tartalmaz.
LET SZAM=5
Egy ilyen utasítás után a SZAM értéke 5. Az egyes függvények nevéhez mindig más és más érték tartozik, aszerint, hogy milyen adatokat adunk meg nekik.
SZAM=INT(4.5)
Az INT függvény értéke most 4, mivel 4.5 egész része pont négy. Ha más számot írtam volna a zárójelek közé, más lenne az INT értéke is. De vajon hogyan adhatunk értéket az eljárások neveinek? Ha azt akarjuk, hogy az eljárás neve egy értéket jelöljön, akkor a DEF blokkon belül kell megmondanunk, mi is legyen az az érték.
10 DEF KOVKAR$
20 DO
30 GET A$
40 LOOP UNTIL A$<>""
50 LET KOVKAR$=A$
60 END DEF
Ez az eljárás mindig a következő karaktert olvassa be, ezért az eljárás neve (KOVKAR$) ennek a rövidítése: következő (KOV) és karakter (KAR). A név végén azért van dollárjel, mert a következő karakter természetesen nem szám, hanem szöveg típus. Az eljárásban először beolvassuk az A$ változóba a következő létező karaktert - ezt végzik el a 20-40. sorok -, majd onnan, mintha csak egy változó lenne, beírjuk azt az eljárás nevébe. Amikor majd később meghívjuk az eljárást, akkor ennek a névnek az értéke az a betű lesz, amit az eljárásban beolvasunk. De hogyan lehet egy ilyen eljárást meghívni? Ehhez is a CALL utasítást kell használnunk? Nem, az ilyen típust eljárást egyszerűen ügy hívjuk meg, hogy a nevét, mintha csak egy változó lenne, leírjuk egy utasításban.
70 DO
80 LET B$=KOVKAR$
90 PRINT B$;
100 LOOP
Ez a program az előző eljárást használja az éppen következő karakter beolvasására. A 80-as sorban a B$-ba töltjük a KOVKAR$ értékét. Ez az érték persze mindig más és más, aszerint, hogy mit olvas be a KOUKAR$ eljárás. A 90-es utasításban kiírjuk a korábban beolvasott betűt, aztán kezdődik elölről az egész. Ez tehát egy gépíró program, arra jó, hogy gépelni lehet vele. Indítsuk el!
Csak értékadó utasításokban (LET) lehetnek ilyen értékkel rendelkező eljárásnevek? Nem, bármilyen más utasításban is jelölhetünk velük értékeket, természetesen ezekben az esetekben is a gép meghívja az eljárást és az eljárásnév új értékét használja fel. Ezek szerint a PRINT utasításba közvetlenül is beírhattuk volna a KOVKAR$-t? Miért ne? Próbáljuk is meg! Töröljük ki a 80-as sort és írjuk át a 90-est:
90 PRINT KOVKAR$;
Ismét elindítva a programot láthatjuk, hogy az ugyanúgy működik, mint korábban. Most próbáljuk meg mégegyszer beírni a PRINT utasításba a KOVKAR$-t:
90 PRINT KOVKAR$; KOVKAR$:
Most akkor mi lesz? Talán kétszer írja majd ki ugyanazt a betűt? Dehogy! Hiszen éppen az előbb olvastuk, hogy a gép, ha megtalálja az eljárás nevét egy utasításban, akkor mindig újra meghívja az eljárást és a név új értékét használja fel. Indítsuk el a programot, és tapasztalni fogjuk, hogy az ugyanúgy dolgozik, mint korábban.
Ezek szerint a B$ változóra nem is volt szükség. Vajon nem lehet az A$-t is kihagyni a programból? Sajnos nem. Gondoljuk végig, hol kellene az A$ helyett egyből a KOVAR$ nevet írnunk. Hát legelőször is rögtön az eljárás 30-as sorában, GET A$ helyett GET KOVAR$-t írva. Igen ám, de ha ezt a gép elolvassa, akkor azt hiszi, hogy a GET utasításban meghívtuk a KOVKAR$ eljárást, és rögtön elölről kezdi a DEF blokkot, azaz újra a 10-es sorra ugrik. Eljut a 30-as sorig, de onnan megint visszalép a 10-esre. A végtelenségig járna körbe-körbe, és soha nem folytatná a programot. Vigyázzunk, hogy ilyen hibát soha ne kövessünk el! Egy DEF blokk belsejében az eljárás neve csak egy értékadó utasítás bal oldalán szerepelhet, ahogy azt az 50-es sorban látjuk is. Ha véletlenül mégis ilyen végtelen körforgást csinálnánk, akkor előfordulhat, hogy csak a hálózati csatlakozót kihúzva és újra bedugva áll vissza a rend.
Az eljár-ások nevét nemcsak az értékadó vagy a PRINT utasításban használhatjuk fel, hanem például az IF utasítás feltételrészében is. Ezt mutatja be a következő példa.
10 DEF MEHET
20 PRINT "MEHET A ";I;"-IK SZIN";
30 INPUT A$
40 IF A$="i" THEN
50 LET MEHET=1
60 ELSE
70 LET MEHET=0
80 END IF
90 END DEF
100 FOR I=1 TO 255
110 IF MEHET THEN SET BORDER I
120 NEXT I
A program a border színét állítja be sorban 1-től 255-ig, de előtte mindig megkérdi, hogy az adott színt meg akarjuk-e nézni. Ezt a kérdést a MEHET nevű eljárás teszi fel, amelyik a nevének az értékét is beállítja egyre vagy nullára aszerint, hogy mit válaszolunk. Az eljárás neve után nem áll dollárjel, mivel nem szöveget, hanem számot fogunk a névvel jelölni. Ne felejtsük el, hogy az eljárás válaszunk beolvasásához az INPUT utasítást használja, ezért a válasz betűje - az i, vagy az n - után az ENTER-t is le kell nyomnunk!
Itt is megfigyelhetjük, hogy az eljáráson belül az eljárás neve csak az értékadó utasítás bal oldalán, konkrétan az 50-es és a 70-es sorban áll. A 20-as sorban is szerepel a MEHET szó, de itt egy szöveg részeként, idézőjelek között, így tehát nem zavarja a gépet.
Még érdekesebb felfigyelnünk arra, hogy a 110-es sorban az IF utasítás feltételeként egyetlen szó, a MEHET eljárás neve áll. Ha megnézzük az eljárást, ennek a névnek az értéke vagy egy, vagy nulla. Az IF utasítás ügy működik, hogy ha a feltétel értéke nem nulla, például egy, akkor a THEN után álló utasítást, illetve utasításukat hajtja végre. Ha a feltétel nulla, akkor az ELSE utáni sorokra ugrana a gép, de mivel itt nincs ELSE utasítás, ezért ebben az esetben nem csinál semmit.
A program fő része így lényegében egyetlen sor, a 110-es, amelyik aszerint, hogy NEHET, vagy sem, beállítja a border színét. A SET BORDER utasítást a HETEDHÉT ENTERPRISE harmadik hetének 3 napján ismerhettük meg.
Felvetődik a kérdés, hogy ezeket a saját nevüknek értéket adó eljárásokat nem hívhatjuk-e meg a CALL utasítással? Természetesen meghívhatjuk, csakhogy ilyenkor nem férhetünk hozzá ahhoz az értékhez, amit az eljárás a saját nevének adott. Nézzük a következő két sort:
105 CALL MEHET
110 IF MEHET THEN SET BORDER I
Ez első pillantásra jónak tűnhet, de ha elindítjuk a programot, akkor azt tapasztaljuk, hogy minden számot kétszer kérdez meg, és csak a második válasz számit. Ez természetes is, hiszen a gép a 105-ös és a 110-es, sorban is meghívja a MEHET eljárást, de az IF utasítás csak a második alkalommal beállított értéket vizsgálja.
Az eljárások tehát nemcsak külön változókban, hanem a nevükben is hordozhatnak értéket, ami lehet szöveges, de szám jellegű is. Az ilyen felhasználásoknál nem a CALL utasítással, hanem egyszerűen az eljárás nevének leírásával célszerű meghívni az eljárást. Ha viszont nincs szükségünk az eljárás nevével jelölt értékre, akkor használjuk nyugodtan a CALL utasítást.
Az eljárás nevével, amely az eljárás által kiszámított értéket jelöli, kényelmesen tudunk egyszerű döntési feltételeket, az eljárás által beolvasott adatokat használó utasításokat leírni. A későbbiekben még sokszor fogjuk ezt az igen célszerű eszközt használni.
1.nap - Listázás reggeltől estig
Írjuk be a következő programot!
10 DEF ELSO
20 REM EZ
30 REM AZ
40 REM ELSO
50 REM ELJARAS
60 END DEF
70 DEF MASOD
80 ! EZ
90 ! PEDIG
100 ! A
110 ! MASODIK
120 END DEF
A REM utasítást a HETEDHÉT ENTERPRISE második hetének 7. napján mutattuk be. Említettük, hogy ezt az utasítást egy felkiáltójellel lehet rövidíteni. A fenti program semmi különöset nem csinál. Győződjünk meg erről, indítsuk el! Arra fogjuk felhasználni, hogy megtanuljunk listáztatni.
Eddig is ismertük már a LIST parancsot, amellyel programunk teljes egészét kiírathatjuk a képernyőre. Ezt az utasítást az F2 billentyűvel is kiadhatjuk. Igen ám, de gyakran elegendő lenne a program egyetlen sora is. Erre is van lehetőség, ha a LIST szó után beírjuk a kívánt sor sorszámát, akkor csak az a sor jelenik meg. írjuk be:
LIST 10
A képernyőn azonnal feltűnik a tízes sor. Mi történik azonban, ha olyan sorszámot adunk meg, ami nem létezik? Próbáljuk ki!
LIST 11
A gép nem ír ki semmit. Ez így van jól, hiszen tizenegyes sor nincs, tehát nem is lehet kilistázni.
Gyakran előfordul az is, hogy nem a teljes programot, de nem is egy-egy sort, hanem egy programrészletet szeretnénk megnézni. Tegyük fel, hagy meg akarjuk vizsgálni az ELSO eljárást, azaz a tizes és hatvanas sorok között részletet. Ezt a következő utasítással tehetjük meg:
LIST 10 TO 60
A TO szócskával kell. elválasztanunk a kívánt programrészlet kezdő és befejező sorát jelölő sorszámokat. Kiirathatjuk a program közepén levő sorokat is, például így:
LIST 35 TO 93
Ekkor a 40-és, 50-es, 60-as, 70-es, 8O-as és a 90-es sor bukkan fel, hiszen ezek vannak 35 és 93 között.
Ha a program elejét vagy végét szeretnénk kiíratni, de nem ismerjük az első vagy az utolsó sor sorszámát, akkor a legelső sorszám helyett használhatjuk az angol FIRST (első), a legutolsó helyett pedig a LAST (utolsó) szócskát. A következő utasítással kiírathatjuk a program első sorától az ötvenes sorszámúig tartó részletet.
LIST FIRST TO 50
Ha a 70-es sortól az utolsó sorig akarjuk kiíratni a programot, akkor a következő utasítást kell kiadnunk:
LIST 70 TO LAST
A LIST FIRST TO LAST utasítás az egész programot kiírja, de ezt egyszerűbben elérhetjük, ha csak a LIST utasítást használjuk. Az eljárások listázását azok nevei segítik elő. A LIST ELSO utasítás az ELSO nevű eljárást írja ki, ugyanígy a LIST MASOD a MASOD nevűt. Próbáljuk ki!
Gyakran kell egyes sorokat törölnünk is a programból. Eddig ezt úgy csináltuk, hogy leírtuk egy üres sor elejére a törlendő sor sorszámát, majd leütöttük az ENTER-t. Létezik azonban egy másik megoldás is, a DELETE parancs. A DELETE (ejtsd: dilit) angol szó, törlést jelent. Vigyázzunk, mert ez a parancs is, a LIST-hez hasonlóan, ha önmagában használjuk, akkor az egész programra vonatkozik, azaz a teljes programot törli a memóriából. (A képernyőről persze nem törli le a látható sorokat. A LIST paranccsal győződhetünk meg arról, hogy a memóriából valóban kitöröltük ezeket.)
Szerencsére a DELETE nemcsak ebben hasonlít a LIST-hez. A parancs neve után itt is megadhatjuk, hogy mely sorokra, programrészletekre vonatkozzon.
DELETE 10
Ez a parancs a tízes sort törli.
DELETE 10 TO 40
Ez pedig a 10-es és a 40-es közöttieket. Itt is használható a FIRST és a LAST szócska, és az eljárások nevei is.
DELETE MASOD
Ez a MASOD eljárást törli ki. Töröljünk ki sorokat, tartományokat a programból, és minden törlés után győződjünk meg a LIST paranccsal, hogy mi maradt meg! Ha egy sort véletlenül törlünk, de a képernyőn még valahol szerepel, akkor lépjünk a kurzorral a kívánt sorba és nyomjuk le az ENTER-t! Ugyanazt érjük el, mintha újra begépeltük volna a sort. Ha a keresett sor már nincs a képernyőn, akkor lépkedjünk felfelé a kurzorral és próbáljuk meg így, a képből már korábban kilépett sorok között megkeresni.
A gyakorlottabb programozókat és azokat, akik papíron előre megírják a programjaikat segíti az AUTO utasítás. Nézzük meg hogyan! Töröljük ki, ami még megvan a programból, és nyomuk le az F3 billentyűt. (Ezzel az AUTO parancsot lehet kiadni.) Most a 100-as sorszám látható. Egészítsük ki egy teljes programsorrá, mondjuk így:
100 PRINT "Ez az AUTO parancs"
Nyomjuk le az ENTER-t, és azonnal felbukkan a 110-es sorszám. Ha ezt a sort is kiegészítjük és elküldjük az ENTER-rel, akkor a 120-as következik, és így tovább. Az AUTO parancs tehát arra jó, hogy egymás után következő sorszámokat ír ki a képernyőre, nekünk csak a programsorokat kell mögéjük írni. Ha már befejeztük programunk begépelését, akkor a sorszámok folyamatos kiírását kétféleképpen szüntethetjük meg. Az, egyik megoldás, hogy lenyomjuk a STOP gombot. Ennél is egyszerűbb, ha hagyjuk, hogy még egy új sorszám jelenjen meg, de nem írunk mögé semmit, hanem azonnal elküldjük az ENTER-rel. Mindkét esetben a gép abbahagyja az újabb sorszámok kiírását és a kurzort a következő sor elejére viszi.
Igen ám, de hogyan tudunk folytatni egy félbehagyott munkát? Hiszen az újabb AUTO parancs megint 100-tól kezdené a sorszámok kiírását. Nos, arra is van mód, hogy más számmal kezdjünk. Ilyenkor az AUTO parancsban, az AT szócska mögött kell megadnunk a kívánt kezdősorszámot:
AUTO AT 150
A fenti parancs a következő sorokat 150-től kezdi számozni, tízesével lépkedve. Azért növeli mindig tízzel a sorszámot, hogy később legyen lehetőségünk új sorokat beszúrni a korábbiak közé. Ha más lépésközt szeretnénk használni, akkor azt a STEP (magyar jelentése lépés) szócska mögött adhatjuk meg. A következő parancs a 200-as sortál kezdve írja a sorszámokat és ötösével sorszámoz.
AUTO AT 200 STEP 5
Ha megfelel a 100-as kezdősorszám, akkor az AT szócskát ki se kell írnunk.
AUTO STEP 15
Ez a parancs a 100-as sortál, tizenötösével számol.
Akármekkora lépésekkel számolunk, előfordulhat, hogy két utasítás között elfogynak az üres sorszámok és pontosan oda kellene egy újabb sort beszúrnunk. Ilyenkor bizony az eddigiek nem segítenek. A megoldás az lehet, ha a meglevő programsorok sorszámait anélkül változtatnák meg, hogy a sorrendjük felborulna. Ezt az átszámozást végzi a RENUMBER parancs. (A renumber, ejtsd rinámbör, azt jelenti, újra sorszámozni.)
A parancsot a SHIFT és az F3 együttes lenyomásával is kiadhatjuk. A RENUMBER, az AUTO utasításhoz hasonlóan, 100-tól tízesével sorszámozza át a sorokat. Töröljük ki, ami a gépben van és írjuk be a fejezet legelején megadott kis programot. A törléshez használhatjuk a DELETE, a begépeléshez az AUTO AT 10 parancsot.
Ha most kiadjuk a RENUMBER parancsot és újra kilistázzuk a programot, akkor azt látjuk, hogy a sorok sorszámai megváltoztak, de sorrendjük változatlan maradt. A sorszámok száznál kezdődnek és tízesével emelkednek. Ha nem felel meg a kezdősorszám vagy a lépésköz, akkor hasonlóan az AUTO parancshoz, az AT és a STEP szócska segítségével más adatokat is megadhatunk:
RENUMBER AT 1 STEP 1
Ez az utasítás egytől kezdve egyesével sorszámozza be a sorokat, azaz valóban "sorszámot" ad nekik. Próbáljuk ki!
Gyakran előfordul, hogy nem az egész programot akarjuk újra sorszámozni, hanem csak egy részét. Lehetőségünk van tartományok, eljárások, vagy akár egyetlen sor átszámozására is. Ilyenkor úgy kell megadnunk a kívánt tartományt, ahogy azt a LIST és a DELETE parancsnál már láttuk. A következő utasítás a 7-nél magasabb sorszámú sorokat sorszámozza újra, 200-tól kezdi és húszasával halad.
RENUMBER 7 TO LAST AT 200 STEP 20
A programban levő két eljárás közé így üres sorszámokat helyezünk, ahova új sorokat lehet beírni. Mindig gondoljunk azonban arra, hogy a sorok korábbi sorrendjét a RENUMBER paranccsal nem lehet megváltoztatni, tehát a következő parancs nem működik, a gép hibát jelez:
RENUMBER ELSO AT 500
Ha ugyanis az ELSO nevű eljárást átsorszámozná 500-tól tízesével, akkor ezek a sorok a MASOD nevű eljárás mögé kerülnének, míg eddig előttük voltak. A RENUMBER ELSO AT 10 parancs azonban minden gond nélkül végrehajtható, hiszen ezzel a sorrend nem változik.
A korábbiakban már jónéhány függvényt megismertünk. Találkoztunk az INT-el, RND-vel, CHR$-el, TIME$-al, és még sok mással is. Az ENTERPRISE lehetőségei azonban szinte kifogyhatatlanok. Ma ismét ismerkedjünk meg néhánnyal, amelyek igen hasznosak lehetnek programjainkban.
Osztani például már tudunk, és az osztás eredményének egész részét is ki tudjuk számítani, az INT függvény segítségével. Például INT(26/5) az 5, mivel a 26/5 az 5.2, ennek az egész része pedig 5. Próbáljuk ki ezt most -26-tal is!
PRINT INT(-26/5)
A gép válasza -6. Talán elromlott? Természetesen nem erről van szó. Akkor miért hibás az eredmény? Ahhoz , hagy ezt megfejthessük, meg kell vizsgálnunk az INT függvény működését. A gép először kiszámította a -26/5-öt, ami -5.2. Az INT függvény mindig a neki megadott számnál kisebb, de hozzá legközelebb levő számot adja meg. Ez nullánál nagyobb számokra valóban a szám egész része, a negatív számoknál azonban hiba keletkezik. A -5.2-nél kisebb, hozzá legközelebbi egész szám nem a -5, hiszen az nagyobb -5.2-nél, hanem a -6.
Éppen ezért van az ENTERPRISE-nak egy másik egész rész függvénye is, az IP, amely valójában két szónak a rövidítése: integer part (ejtsd: intidzsör part), azaz egész rész. Ez a függvény már valóban a szám egész részét adja vissza, negatív számokra is. A két függvény közül sok más számítógép csak az INT-et ismeri, így azt többen használják. Ha azonban olyan műveleteket végzünk, ahol gondot okozhatnak a negatív számok, ott az ENTERPRISE-on nyugodtan használhatjuk az IP függvényt.
Egész rész függvényből már kettőt is ismerünk, de a számok tört részét még mindig elég körülményesen tudjuk csak kiszámítani. Arra ugyanis lehetőségünk van, hogy egy számból levonjuk az egész részét, ami marad, az természetesen a törtrész. Ezt használja a következő program. Írjuk be és futtassuk le néhányszor!
10 CLEAR SCREEN
20 DO
30 PRINT " Add meg a szamot:";
40 INPUT SZAM
50 PRINT " A";SZAM;"tortresze:";
60 PRINT SZAM-IP(SZAM)
70 LOOP
A törtrész kiszámítása és kiírása is a 60-as sorban történik, ahol a SZAM-ból kivonja a SZAM egész részét, amit az IP függvénnyel számol ki, majd a kivonás eredményét kiírja. Szerencsére nem kell mindig ilyen bonyolult módon számítanunk a törtrészt. Van erre ugyanis egy külön függvény, az FP. Az FP is rövidítés, a törtrész ugyanis angolul fraction part (kiejtése: fraksön part). Írjuk most át a 60-as sort:
60 PRINT FP(SZAM)
Indítsuk el a programot és győződjünk meg róla, hogy az tényleg helyesen működik! Most már könnyen megkapjuk az osztások eredményének törtrészét is. Például az FP(26/5) az 0.2, mivel 5.2-nek ez a törtrésze. Az osztásnak azonban van még egy jellegzetes adata, ez pedig a maradék. A maradékot, a törtrészhez hasonlóan, külön függvény nélkül is ki tudjuk számítani, ezt végzi a következő program:
10 CLEAR SCREEN
20 DO
30 PRINT "Add meg az elso szamot:";
40 INPUT SZAM1
50 PRINT "Add meg a masodik szamot:";
60 INPUT SZAM2
70 PRINT SZAM1;"/";SZAM2;"maradeka:";
80 PRINT SZAM1-(SZAM2*IP(SZAM1/SZAM2) )
90 LOOP
A maradékot a 80-as sorban levő hosszú kifejezés adja meg. Ha elindítjuk a programot, látjuk, helyesen számol. Természetesen nem kell mindig ilyen hosszú kifejezéseket használnunk, mert a gép ismeri a maradékot számító függvényt is. Ennek neve REM, ami az angol remainder (ejtsd:riméjnder, jelentése maradék) szó rövidítése. A REM függvényt onnan lehet megkülönböztetni a REM utasítástól, hogy a függvény neve mögött természetesen mindig ott állnak zárójelben a szükséges adatok. A REM függvénynek meg kell adnunk, hogy melyik két szám osztásának a maradékára vagyunk kíváncsiak. A 80-as sor helyett tehát tökéletesen megfelel a következő rövid utasítás is. Írjuk be és próbáljuk ki a programot!
80 PRINT REM(SZAM1,SZAM2)
Ahogy az IP függvénynek van egy különleges társa, az INT, úgy tartozik a REM-hez a MOD függvény. A MOD a matematikában használt modulóosztás rövidítése, ez majdnem ugyanaz, mint a maradékképzés. A különbség akkor lép fel, ha az első szám, azaz amit osztani akarunk negatív. Figyeljük ezt meg egy néhány példán:
REM(5,5)=0 | MOD(5,5)=0 |
REM(4,5)=4 | MOD(4,5)=4 |
REM(3,5)=3 | MOD(3,5)=3 |
REM(2,5)=2 | MOD(2,5)=2 |
REM(1,5)=1 | MOD(1,5)=1 |
REM(0,5)=0 | MOD(0,5)=0 |
REM(-1,5)=-1 | MOD(-1,5)=4 |
REM(-2,5)=-2 | MOD(-2,5)=3 |
REM(-3,5)=-3 | MOD(-3,5)=2 |
REM(-4,5)=-4 | MOD(-4,5)=1 |
REM(-5,5)=0 | MOD(-5,5)=0 |
REM(-6,5)=-1 | MOD(-6,5)=4 |
REM(-7,5)=-2 | MOD(-7,5)=3 |
Nézzük meg, ha az osztandó szám negatív, a REM függvény az osztás negatív maradékát adja. A MOD függvény viszont továbbra is nulla és négy közötti számokat határoz meg, az eredmény nem lehet negatív. Vajon mire jó egy ilyen függvény? Példa erre a következő program.
1 PROGRAM "MozgoO.bas"
10 SET KEY CLICK OFF
20 CLEAR SCREEN
30 LET X=10
40 PRINT AT 10,11:"O"
50 DO
60 LET Y=UJY
70 LET Y=MOD(Y,37)
80 IF Y<>X THEN
90 PRINT AT 10,X+1:" "
100 PRINT AT 10,Y+1:"O"
110 LET X=Y
120 END IF
130 LOOP
140 DEF UJY
150 SELECT CASE JOY(0)
160 CASE 1
170 LET UJY=X+1
180 CASE 2
190 LET UJY=X-1
200 CASE ELSE
210 LET UJY=X
220 END SELECT
230 END DEF
A program egy O betűt mozgat a képernyőn a tizedik sorban. Az O mozgását a botkormánnyal tudjuk irányítani. Az X nevű változó tartalmazza azt, hogy most éppen hányadik sorban van az O. (Pontosabban az X+1-edik oszlopban van.)
A programban az UJY eljárás megnézi a botkormány helyzetét, és annak függvényében az UJY értékét az X-hez képest eggyel nagyobbra, kisebbre, vagy azzal megegyezőre állítja be. Ehhez használja a SELECT utasítást (HETEDHÉT ENTERPRISE harmadik hét 2. nap) és a JOY(0) függvényt (HETEDHÉT ENTERPRISE +1 nap). Az UJY lesz az D új helyének oszlopszáma. Illetve majdnem az.
Gondoljuk csak végig, mi történne, ha mindig az UJY lenne az új oszloppozíció! Ahogy jobbra lépkednénk az O-val, egyre nőne az X értéke, tehát az UJY is. Amikor azonban az X elérné a 40-et, akkor az UJY 41 is lehet, ebbe az oszlopba viszont már nem lehet írni, mivel ilyen oszlop nincs is. Ezt úgy kerülhetnénk el, hogy az UJY negyvennel való osztásának a maradékával számolunk, hiszen amikor az UJY 41, akkor a REM(UJY,40) az 1, tehát érvényes oszlopszám. Ezzel elérnénk azt, hogy ha a képernyőn jobbra már kilépnénk az O-val, akkor az baloldalról, az első oszlop felől újra előbukkanna. Igen ám, de ha UJY 40, akkor a REM(UJY,40) az 0, nulladik oszlop pedig nincs. Hogy ezt a problémát kikerüljük, mi eggyel arrébb, a kiszámított értékhez képest mindig eggyel nagyobb sorszámú sorba írunk. Ezt a 90-es és a 100-as sorban meg is lehet figyelni.
Ebben a programban számunkra kényelmetlen a REM függvénynek az a tulajdonsága, ahogyan a negatív számokat kezeli. Ha ugyanis nem jobbra, hanem balra kezdenénk el lépkedni, akkor az X, és vele az UJY egyre csökkenni kezdene. Amikor az UJY elérné a -1-et, akkor a REM(UJY,40) értéke is -1 lenne, a gép tehát ismét egy nem létező oszlopba próbálna írni. Ezen segít a MOD függvény. MOD(-1,40) értéke 39, nem pedig -1, ugyanis a MOD(valami,40) mindig 0 és 40 közé eső értéket, tehát pozitív számot ad vissza.
Az ENTERPRISE néhány más tulajdonsága miatt mi a 70-es sorban, ahol a MOD függvény van, nem 40-el, hanem 37-el osztunk, de a lényeg ugyanaz, az új pozíciót tartalmazó Y változót itt állítjuk be. Ha az új oszlopszám nem egyezik a régivel, akkor töröljük az előző 0-t (90-es sor), és kiírunk egy újat (100-as sor). Ismét figyeljünk fel arra, hogy ez a két PRINT utasítás az X-hez és az Y-hoz képest egy oszloppal jobbra ír!
Néha igen hasznos lehet az ARS függvény is. Mi az az ABS? Ez a függvény a számok abszolút értékét adja meg, például:
ABS(23)=23
ABS(0)=0
ABS(-5)=5
A pozitív számok és a nulla tehát nem változnak, míg a nullánál kisebb számok előjelét megfordítja. Ez főleg a számolást végző programokban hasznos. Alkalmazhatjuk a MAX és a MIN függvényt is. Ezek két szám közül a nagyobbat, illetve a kisebbet választják ki. Például:
MAX(5,3)=5 | MIN(5,3)=3 |
MAX(3,3)=3 | MIN(3,3)=3 |
MAX(1,3)=3 | MIN(1,1)=1 |
MAX(-3,3)=3 | MIN(-3,3)=-3 |
Ezek a függvények annyira könnyen érthetőek, hogy tovább is léphetünk. Vizsgáljuk meg a POS függvényt! A position angol szó, pazisbn-nek kell ejteni és helyzetet, elhelyezkedést jelent. A POS függvénynek két szöveget kell megadni. Megkeresi, hogy a második szöveg benne van-e valahol az elsőben, és ha megtalálta, akkor megadja, hogy az első szöveg hányadik betűjénél kezdődik. Például:
POS("elso szoveg","so")=3
Az "elso szoveg"-ben a "so" részlet először a harmadik betűtől kezdődően található meg. Fontos, hogy ha többször is előfordul a keresett szövegrész, akkor mindig a legelső előfordulást adja meg. Például:
POS("leheleted","le")=1
A "leheleted"-ben a "le" kétszer is megtalálható, de a függvény az első helyét, azaz az első betűt jelöli ki.
POS("huszonegy","het")=0
A matematikusokat talán zavarja, de mi akkor is tudjuk, hogy a "huszonegy" szövegben a "het" szöveg nem található meg, bár huszonegyben a hét háromszor is megvan. A POS függvény így nullát ad vissza.
Van ennek a függvénynek még egy különleges tulajdonsága. Ha egy szövegben egy többször is előforduló másik szöveget, és annak nem a legelső előfordulását keressük, akkor megadhatjuk, hogy az első szöveg hányadik betűjénél kezdje a gép a keresést. Például:
POS("felebele","le",1) = 3
POS("felebele","le",3) = 3
POS("felebele","le",4) = 7
POS("felebele","le",7) = 7
POS("felebele","le",8) = 0
A "felebele" szövegben a "le" részletet a harmadik betűnél találjuk meg, ha a keresést az első betűn kezdjük. A negyedik betűnél kezdve újra meg lehet találni, a hetedik pozíciónál. Ha pedig a nyolcadik karakternél indulunk el, akkor már nem találjuk' sehol, tehát a függvény nullát ad vissza. Ezt használja fel a következő program, amelyik egy megadott szóban az e betűket -számolja meg.
1 PROGRAM "E_betu.bas"
10 DO
20 PRINT "Add meg a szot";
30 INPUT SZO$
40 LET SZAM=0
50 LET HELY=1
60 DO
70 LET POS1=POS(SZO$,"e",HELY)
80 IF POS1=0 THEN EXIT DO
90 LET HELY=POS1+1
100 LET SZAM=SZAM+1
110 LOOP
120 PRINT "A ";SZO$;" szoban"
130 PRINT "az e betu";
140 PRINT SZAM;"-szor szerepel"
150 LOOP
A 70-es sor utasítása szerint a program a HELY pozíción kezdve a keresést megnézi, hogy vajon van-e e betű a szóban. A HELY kezdőértéke 1. Ha nem talál e betűt, akkor a 80-as sorban kiugrik a ciklusból és kiírja az eredményt, az eddig megtalált e betűk számát (SZAM). Ennek kezdőértéke nulla. Ha talált e betűt, akkor eggyel növeli a SZAM értékét, és a találat helye (POS1) utáni pozícióról folytatja a keresést. Ezt a 90-es és a 100-as sorban állítja be.
Ma rajzolni fogunk. Rajzolni csak grafikus lapra tudunk, aki nem emlékszik rá, az olvassa el újra a HETEDHÉT ENTERPRISE harmadik hetének 1. és 3. napját! Grafikus lapot a GRAPHICS utasítással tudunk létrehozni. Mire jó ez az utasítás? Nos, egyrészt tisztára törli a képernyőt, másrészt két részre bontja, a felső húsz sorba kerülnek a rajzok, alulra pedig a szövegek. Van azonban egy ennél fontosabb feladata is, amiről eddig nem esett szó.
Mi már sokat írtunk és rajzoltunk is a képernyőre, de nem foglalkoztunk még a kép keletkezésével. Nos, a gép a saját memóriájában lefoglal egy területet, amelyet VIDEO memóriának nevezünk. Ezen a területen pontról pontra tárolja, ami majd a képernyőn megjelenik. A VIDEO memóriában a kép minden egyes kis pontocskájához tartozik egy-egy memória rekesz, ahova be van jegyezve, hogy az adott ponton van-e tinta, avagy sem. Amelyik ponton nincs tinta, ott a papír látható. A gép mindig ezekből a kis pontocskákból rakja össze a képeket és betűket. Ha jó a televíziónk és közelről megvizsgáljuk a betűket, akkor ezt láthatjuk is.
Természetesen egyáltalán nem mindegy, hogy hány ilyen kis pontocskából áll a kép. Minél több pontbál rakjuk össze, annál több hely kell ahhoz, hogy rögzíteni lehessen. Minél több pontra bontjuk fel a képernyőt, annál több helyet kell lefoglalni a VIDEO memória részére, tehát annál kevesebb- marad a többi feladatra, programunk számára. Az ENTERPRISE lehetőséget ad arra is, hogy takarékoskodjunk a memóriával, csökkentsük a képpontok számát.
A kép pontokból való összerakásakor a pontok száma változtatható. Azt, hogy hány pontra bontjuk fel a képet, a kép felbontásának nevezik. A felbontás angol neve resolution (ejtsd: rezolúsn), és magas (high, eitsd:háj) vagy alacsony (low, kiejtve: lou) felbontásról szoktunk beszélni. Az ENTERPRISE ezt a két fogalmat rövidítve jelöli, és HIRES, illetve LORES grafikus lapot használ, ami a high resolution és e low resolution rövidítése. Azt, hogy milyen lapot akarunk elővenni, a GRAPHICS parancsban adhatjuk meg. Ezt mutatja be a következő program:
10 DEF IDO
20 DO
30 GET A$
40 LOOP UNTIL A$<>""
50 END DEF
60 DO
70 GRAPHICS HIRES
80 PLOT 10,10;500,500
90 CALL IDO
100 GRAPHICS LORES
110 PLOT 10,10;500,500
120 CALL IDO
130 LOOP
Indítsuk el a programot! Az IDO rutin csak annyit csinál, hogy megvárja a következő billentyű leütését. A program fő része a 60-as sorban kezdődik. Itt valójában annyi történik, hogy felváltva egy HIRES és egy LORES lapra rajzol a program egy-egy ferde vonalat. A két vonal rajzolása között mindig megvárja, hagy megnyomjunk egy billentyűt. Figyeljük meg, hogy a két kirajzolt vonal miben különbözik egymástál! A vonalak helyzete nem változik, tehát a gép mindig ugyanazt a koordináta rendszert használja. A bal alsó sarokban van a 0,0 pont, a jobb felsőben az 1279,719. A kép felbontása, azaz a vonal vastagsága azonban más és más.
Ha a GRAPHICS parancsban nem adunk meg sem HIRES, sem LORES felbontást, akkor mindig azt a felbontást fogja használni, amit legutoljára adtunk meg. Amikor a gépet bekapcsoljuk, GRAPHICS parancsra mindig egy HIRES lapot vesz elő, azaz annak elegendő helyet foglal le a memóriából a VIDEO memória részére. A képernyő tartalmának tárolásához szükséges hely nagysága nemcsak attól függ, hogy hány pontra bontjuk fel a képernyőt, hanem attól is, hogy hány színt akarunk használni. Az egyes pontoknál ugyanis nemcsak azt kell feljegyezni, hogy ott van-e tinta, vagy sem, hanem azt is, hogy milyen színű tinta van ott. Éppen ezért lehetőségünk van arra is, hogy megválasszuk, hány színt akarunk használni. Az ENTERPRISE esetében minél több színt használunk, annál kevesebb pontra bontja fel a képet, hogy a felhasznált VIDEO memória nagysága ugyanakkora legyen.
A GRAPHICS parancsban a HIRES vagy a LORES kulcsszó után megadhatjuk, hogy 2, 4 vagy 16 színre van szükségünk. Minél több színt adunk meg, annál kisebb lesz a kép felbontása. Most már tehát hat féle grafikus lapot ismerünk:
GRAPHICS HIRES 2
GRAPHICS HIRES 4
GRAPHICS HIRES 16
GRAPHICS LORES 2
GRAPHICS LORES 4
GRAPHICS LORES 16
írjuk át a programban a 70-es és a 100-as sort a következőkre, és indítsuk el a programot!
70 GRAPHICS LORES 4
100 GRAPHICS LORES 16
Most állítsuk meg, újra javítsuk át ezt a két sort úgy, hogy most nagyfelbontású lapokat hozzunk létre! Indítsuk el a programot!
70 GRAPHICS HIRES 4
100 GRAPHICS HIRES 16
Látható, hogy a felbontás az alkalmazható színek számától is függ. Mit is jelent ez a szám? Mit jelent az, hogy egy lapon 2, 4 vagy 16 színt használhatunk?
Talán emlékszünk még (HETEDHÉT ENTERPRISE harmadik hét 3. nap), hagy rajzolás előtt mindig négy tégely közül kell kiválasszuk, melyikből veszünk festéket ecsetünkre. A tinta színének kiválasztására a SET INK utasítás szolgált, amiben a kívánt tégely számát adhattuk meg. A tégelyekbe a SET COLOR utasítással tudtuk betölteni a tintát. Eddig mindig négy tégelyünk volt, ennek megfelelően egyszerre négyféle színt használhattunk. Az ENTERPRISE ugyanis bekapcsoláskor a GRAPHICS parancs hatására egy GRAPHICS HIRES 4 lapot vesz elő. Ha mi más számot adunk meg, akkor csak 2, avagy 16 tégelyünk lesz, persze a felbontás is ezzel együtt változik.
Ha GRAPHICS HIRES 2 utasítással létrehozott lap esetén csak két tégelytank van, a nullás és az egyes. GRAPHICS HIRES 16-nál pedig 16 db., nullástól kezdve egészen a tizenötösig. Ilyenkor mind a tizenöt tégely közül választhatunk.
Általában a SET COLOR utasítással töltjük a festéket a tégelyekbe. Van azonban ez alól kivétel is. írjuk be a következő parancsokat, sorszám nélkül, hogy a gép azonnal végrehajtsa ezeket! Figyeljük meg közben, hogyan változik a képernyő színe!
graphics hires 16 set color 7,red
set ink 7
plot paint
(A PLOT PAINT utasítással a HETEDHÉT ENTERPRISE harmadik hetének 3. napján találkozhattunk.) A képernyő felső részén, a grafikus lap pirosra változott. Most Írjuk be a következőt!
set color 7,yellow
A kép máris sárga, hiszen kicseréltük a tégelyben a tintát, és így mindaz, amit ebből a tégelyből festettünk ki, megváltoztatta a színét. Folytassuk a parancsokat!
set ink 8
plot paint
A képernyő most fekete, ezek szerint a nyolcas tégelyben fekete festék volt. Próbáljuk meg megváltoztatni!
set color 8,red
Semmi sem történik. Vajon mi lehet az oka? Nos, a gép az első nyolc tégelyt (0-7) rendkívül szabadon kezeli. Ezekbe a tégelyekbe bármilyen festék betölthető a lehetséges 256 (0-255) változat közül. A második nyolc tégelybe viszont már nem kerülhet akármilyen festék és nem is a SET COLOR utasítással tudjuk betölteni azokat. Erre a SET BIRS utasítás szolgál.
Mint már tudjuk, 256 színnel dolgozhatunk, amelyek mindegyikét egy-egy számmal adhatjuk meg, sorban 0-tál 255-ig. Ezeket a színeket a gép 32 db nyolcas csoportra bontja; 0-7, 8-15, 16-23, 24-31, és így tovább, egészen az utolsó, 248-255-ös színeket tartalmazó csoportig. A felső nyolc tégelybe egyszerre csak egy ilyen teljes csoport kerülhet. Válasszuk ki a nekünk tetsző csoportot és abból bármelyik elem számát írjuk be a SET BIAS utasításba!
Az első csoportban például a nullától hetesig terjedő számot viselő színek vannak. Akár azt írjuk, SET BIAS 0, akár azt, SET BIAS 1, vagy azt, hogy SET BIAS 7, ezzel mindenképpen az első csoportot választottuk ki, hiszen a 0, 1, 7, mind az első csoportban vannak. Mindhárom utasítás hatása ugyanaz, azaz a csoport első eleme, a nullás szín (ami a fekete) kerül a nyolcas tégelybe, a csoport második színe, a kettes szín (ami a piros) a kilences tégelybe, és így tovább. Amikor a gépet bekapcsoljuk, az első csoport van ezekben a tégelyekben.
A SET BIAS 8 a második csoport színeit tölti a felső tégelyekbe, tehát a nyolcas tégelybe a nyolcas szín kerül, a kilencesbe a kilences és így tovább. SET BIAS 248-at megadva az utolsó csoport (248-255) színeit juttatjuk a 8-15 számú tégelyekbe.
A SET BIAS utasítás az alsó nyolc tégelyben levő színeket nem változtatja, azokat továbbra is a SET COLOR utasítással lehet beállítani. Aki azonban ezeket is egy utasítással akarná meghatározni, ne búsuljon, erre is van mód. Az alsó nyolc színt együttesen palettának nevezzük, ezért ezeket a SET PALETTE utasítással lehet megadni, ahol a kulcsszó után sorra meg kell adni, melyik színt akarjuk a nullás, egyes, kettes, stb. tégelyekbe tölteni. Próbáljuk ki a következő parancsokat!
set palette red,black,1,0,green,2,3,4
set ink 0
plot paint
set ink 1
plot paint
set ink 2
plot paint
set ink 3
plot paint
set ink 4
plot paint
set ink 7
plot paint
Az első parancs különböző festékeket töltött alsó nyolc tégelybe, az utána következő sorokkal csak azt vizsgáltuk, hogy milyen festék került ezekbe a tégelyekbe. A nullás tégelyben piros festék van (red), a kettesben szintén, ugyanis a piros szín száma 1, tehát a SET PALETTE utasításban a harmadik helyen álló egyes is a piros színt jelöli. Ugyanígy a fekete színre utal a második helyen álló black, és a negyedik helyen álló 0. Az ötödik, tehát négyes számú tégelybe zöld, az utolsó, hetes tégely pedig kék tintát tartalmaz.
Ezzel a palettával már szinte festeni is tudunk. A festők azonban nemcsak boltban vásárolható festékeket használnak, hanem azokat összekeverve új színeket is előállítanak. Azt tapasztalták, hogy a piros (Red), a zöld (Green) és a kék (Blue) szín összekeverésével bármilyen más színt létre tudnak hozni. Az ENTERPRISE lehetővé teszi, hogy mi is e három szín összekeverésével készítsünk új színeket.
Mivel a három szín neve angolul Red, Green és Blue, a függvény neve RGB lett. Három paramétere egy-egy szám, 0 és 1 között, amelyekkel mehatározhatjuk, hogy mennyi piros, zöld illetve kék festéket kell összekeverni. Ezeket az értékeket az RGB kulcsszó mögött zárójelben, a függvény nevében szereplő színek sorrendjében kell feltüntetni. Az RGB függvényt mindenütt használhatjuk, ahol eddig a színek számát vagy nevét írtuk le. A következő utasítás pirosra változtatja a keretet:
set border rgb(1,0,0)
(A SET BORDER utasítást a HETEDHÉT ENTERPRISE harmadik hetének 3. napján ismertük meg.) A következő sorok zöldre festik a grafikus lapot:
clear graphics
set color 0,rgb(0,1,0)
A sárga szín a piros és a zöld keverékeként jön létre, töltsünk tehát sárga festéket az egyes tégelybe:
set color 1,rgb(1,1,0)
Húzzunk egy vonalat is ezzel a festékkel:
set ink 1
plot 0,0;500,500;
Most pedig nézzünk meg egy programot, amely a színek keverését mutatja be:
1 PROGRAM "Szin.bas"
10 SET KEY CLICK OFF
20 GRAPHICS HIRES 2
30 LET X=.5
40 LET Y=.05
50 DO
60 SELECT CASE JOY(0)
70 CASE 1
80 LET X=X+Y
90 IF X>1 THEN LET X=1
100 CASE 2
110 LET X=X-Y
120 IF X<0 THEN LET X=0
130 CASE ELSE
140 END SELECT
150 SET COLOR 0,RGB(1,X,0)
160 LOOP
A SELECT utasítást a HETEDHÉT ENTERPRISE harmadik hetének 2. napján, a JOY(0) függvényt pedig a +1. napon ismertük meg. Amikor a programot elindítjuk a zöld festék mennyiségét a botkormány jobbra-balra mozgatásával tudjuk szabályozni. A 160-es sorból látszik, hogy a másik két szín közül csak pirosat tettünk a festékbe, de azt a lehető legtöbbet. Ha más színkeveréket akarunk használni, akkor a 150-es sort kell megváltoztatnunk. Például így:
160 SET COLOR 0,RGB(X,0,1)
Vállalkozó kedvűek készíthetnek olyan programot, amivel egyszerre több összetevő arányát is lehet változtatni, mondjuk a pirosét és a kékét. Mire jó azonban ez a sok szín, ha egyszerre úgyis csak 16-ot használhatunk? Nos, nem kell lebecsülni azt a 16-ot sem, a legtöbb esetben négy színre sincs szükségünk, de ha mégis sokféle színnel akarunk egyszerre dolgozni, arra is van mód. Ilyen sokszínű lapot nyit a GRAPHICS HIRES 256, és a GRAPHICS LORES 256 utasítás. Ezekkel olyan lapot hozunk létre, amelyeken mind a 256 szín egyszerre használható. Természetesen ennek megfelelően a felbontás tovább romlik. A 256 színű lapokon sem palettára (PALETTE), sem csoportszínekre (BIAS) nincs szükség, a SET COLOR utasításnak sincs értelme, hiszen ha 256 szín használható, akkor nem kell tégelyeket igénybe venni, hanem közvetlenül a szín azonosító számával, nevével, vagy az RGB függvénnyel mondhatjuk meg, milyen színnel akarunk festeni. Ennek megfelelően a SET INK és a SET PAPER utasítások nem a kívánt tégely számát adják meg, hanem a színét. Példa erre az itt következő néhány utasítás:
graphics hires 256
set color 1,green
set ink 1
plot paint
Azt várnánk, hogy a képernyő zöldre vált, hiszen az egyes számú tégelybe zöld festéket töltöttünk, aztán ebből a tégelyből vettünk az ecsetünkre (SET INK 1), s végül ezzel festettük ki a grafikus lapot. A 256 színű lapon azonban a SET INK 1 utasítás nem az első tégelyt, hanem az egyes számú színt, a pirosat jelöli ki.
Már valóban szép, színes rajzokat készíthetünk, ha ehhez jó programokat írunk. Rajta hát!
4. nap - Alkossunk függvényeket
Programjainkban gyakran használjuk azokat a függvényeket, amelyeket az ENTERPRISE ismer. Ezek hasznos segítőtársaink, és egyben kényelmes eszközeink. Sajnos azonban az ENTERPRISE sem mindent tudó csodagép. Néha olyan függvényekre is szükségünk lehet, amelyeket még ő sem ismer. Mit tudunk ilyenkor csinálni? Az lenne a jó, ha meg tudnánk tanítani új számításokra is. Új függvényeket kellene létrehozni. De hogyan? Nos, kezdjük azzal, hogy végiggondoljuk, mi is az a függvény?
Minden függvénynek neve van, ez az egyik jellemzőjük. Ezek a nevek egy-egy értéket jelölnek, akárcsak a változók nevei. A változók nevének értéke attól függ, hogy mit töltöttünk be a változóba. A függvények értéke pedig aszerint változik, hogy milyen adatokat adunk meg nekik, ezért hívjuk őket függvényeknek. A függvények másik fontos tulajdonsága, hogy adatokat adhatunk meg nekik. Ezeket az adatokat a függvény paramétereinek nevezzük, és mindig a függvény neve után állá zárójelek között kell szerepelniük.
A függvényeken és a változókon kívül az eljárások neveinek is lehet értéke. Kaphatnak-e az eljárások a függvényekhez hasonlóan paramétereket? Miért ne? Csináljunk egy eljárást, ami három szám összegét számolja ki!
10 DEF OSSZ(EGYIK,MASIK,HARM)
20 LET OSSZ=EGYIK+MASIK+HARM
30 END DEF
Az eljárás elején, a 10-es sorban, megadjuk az eljárás nevét és paramétereit. Az eljáráson belül ezeket a paramétereket úgy használjuk, mint bármely más változót. A 20-as sorban összeadjuk a három paramétert és az összeget betöltjük az eljárás nevébe.
Ha ezt az eljárást akarjuk meghívni, akkor ugyanúgy használhatjuk a nevét, mint egy függvényét, és a neve mögött, zárójelek között, egymástól vesszővel elválasztva kell megadnunk a paramétereit. A paraméterek értékét a 10-es sor zárójelben álló változói sorrendjében írjuk be, tehát az első paraméter értéke az EGYIK nevű változóba kerül, a másodiké a MASIK változóba, a harmadik értéke pedig a HARM-ba. Nézzük meg ezt egy példán is!
40 LET SZAM=OSSZ(1,2,3)
50 PRINT SZAM
Indítsuk el a programot, amely a 40-es sorban meghívja az OSSZ eljárást. A 10-es sorban, a zárójelen belül három paraméterváltozó nevét soroltuk fel, tehát három adatot kell a paraméterváltozók sorrendjében megadnunk. Legyenek ezek most egyszerű számok, az egy a kettő és a három. A gép akkor tölti be ezeket a számokat a paraméterváltozókba, amikor meghívjuk az eljárást, azaz a 40-es sorban. Az eljárás kiszámítja a megadott értékek összegét és betölti az OSSZ névbe. A 40-es sorban ezt az értéket írjuk át a SZAM nevű változóba, majd az 50-es sorban kiíratjuk a SZAM tartalmát.
Természetesen paraméterként nemcsak számokat, hanem változókat is megadhatunk. Töröljük ki a 40-es és az 50-es sort, és írjunk be helyettük két másikat!
40 LET HAROM=3
50 PRINT OSSZ(HAROM,HAROM,HAROM)
Az 50-es sorban megfigyelhetjük, hogy az OSSZ eljárást, akárcsak egy függvényt, közvetlenül is használhatjuk a PRINT utasításban, ahogy azt már eddig is tudtuk, hiszen az előző hét 4. napján volt róla szó. Az OSSZ eljárás háremparamétereként most egy-egy változót adtunk meg. Az eljárás meghívásakor ezeknek a változóknak az értékét tölti a gép egymás után a paraméterváltozókba. A dolog külön érdekessége, hogy most a három paraméter ugyanaz a változó, mégpedig a HAROM, s így a 40-es sorba, mind a három paraméterváltozóba a HAROM változótartalmát, azaz hármat töltöttünk.
A program futása során a gép a HAROM változó tartalmát, azaz a hármat, sorra betölti az EGYIK, MASIK illetve a HARM nevű paraméterváltozókba, összeadja őket, majd az eredmény az OSSZ-be, onnan kiírva pedig a képernyőre kerül. Természetesen
az eljárás neve és a paraméterek is lehetnek szöveg típusúak. Példa erre a következő program. írjuk be és futtassuk le!
1 PROGRAM "Fordit.bas"
10 DEF FORD$(SZO$,KEZD,VEG)
20 LET TXT$=""
30 FOR I=VEG TO KEZD STEP-1
40 LET TXT$=TXT$&SZO$(I:I)
50 NEXT
60 LET FORD$=TXT$
70 END DEF
80 PRINT FORD$("satidrof",1,8)
90 PRINT FORD$("satidrof",1,7)
A FORD$ eljárás paraméterként egy szöveget és két számot kap. Az eljárás a SZO$ paraméterváltozóban megkapott szöveg betűi közül a KEZD és a VEG pozíció közöttieket tölti be a FORD$ névbe, de fordított sorrendben. A 80-as és a 90-es sorban ennek az új függvénynek a segítségével írtuk ki a "satidrof" szöveget, illetve egy részletét fordítva.
Új függvény? De hiszen mi egy eljárást használtunk! Igen, de ezt az eljárást nyugodtan nevezhetjük függvénynek is, hiszen a nevét leírva hívtuk meg, zárójelek között adtuk meg paramétereit és nevének értékeként kaptuk meg az eredményt. Hogy ne keverjük össze az általunk létrehozott függvényeket az eredetiekkel, ezért az utóbbiakat előre definiált függvényeknek nevezzük. A két függvény közti alapvető különbség az, hogy a mi függvényeink a gép kikapcsolásakor vagy a program törlésekor elvesznek.
Ehhez hasonlóan, azokat a változókat, amelyeket a gép magától hoz létre (például az első hét 2. napján megismert TIME, DATE$, INKEY$), paraméter nélküli előre definiált függvényeknek is tekinthetjük, és ezekhez hasonló, paraméter nélküli függvényeket is létrehozhatunk. Az első hét 4. napján valójában ilyen függvényekkel ismerkedtünk meg, csak akkor még eljárásoknak neveztük őket. Az eljárások, a függvények és a változók tehát sokszor nem is különböztethetők meg egymástól, olyannyira, hogy néha nem is lehet tudni, melyiket használjuk. Szerencsére ez semmiben sem nehezíti meg a kezelésüket, nyugodtan dolgozzunk velük.
Az eljárások. paraméterváltozóiról tudjuk, hogy az eljáráson belül ugyanúgy használhatjuk őket, mint bármely más változót. Az értéküket közvetlenül az eljárás meghívása előtt, a megadott paraméterekből, egyenként tölti be a gép. Van azonban egy másik fontos tulajdonságuk, mégpedig az, hogy az eljáráson kívül nem használhatók.
Töröljük ki az eddigi programot és írjuk be a következőt:
30 DEF ELJ(PARAM)
40 LET PARAM=PARAM*2
50 LET ELJ=PARAM+1
60 END DEF
70 PRINT ELJ(5)
Az eljárás a paraméterként megkapott érték kétszeresénél eggyel többet számit ki, azt adja vissza a nevében. A 40-es sorban a PARAM nevű paraméterváltozót megkétszerezi, majd az 50-esben ehhez ad egyet, és az eredményt az ELJ névbe tölti. A 70-es sorban az 5-re hívjuk meg az eljárást, ha lefuttatjuk a programot, szépen ki is írja a 11-et.
Tegyük fel, hogy minket érdekelne, mennyi lett a PARAM változó értéke az eljárás után. Ezt sajnos nem tudjuk megállapítani. Hogyhogy nem? Hiszen bármikor kiirathatom egy PRINT utasítással? írjuk be a 80-as sort és indítsuk el a programot!
80 PRINT PARAM
A gép hibát jelez a 80-as sorban. Vajon miért? Mondtuk már, hogy az eljárások paraméterváltozóit csak az eljáráson belül lehet használni, azon kívül olyan, mintha nem is léteznének. A 80-as sor az eljáráson kívül van, tehát ebben a sorban a számítógép már nem ismeri a PARAM nevű változót. Nagyon hasonlít ez arra a problémára, amivel a HETEDHÉT ENTERPRISE harmadik hetének 4. napján találkoztunk, amikor a BILLBE, vagy a KORBEO eljárás által beolvasott adatokhoz nem tudtunk hozzáférni. Vegyük elő azt a könyvet és nézzük meg, mi volt ott a megoldás!
Nos, akkor az okozta a gondot, hogy az eljárások belső változói az eljárás vége után elvesztik értéküket. Ennek elkerülésére a program elején külön jeleztük, hogy ezeket a változókat külső változóként szeretnénk használni, erre szolgált a STRING és a NUMERIC utasítás. Próbáljuk ki ezt most is! írjuk be a következő sort és indítsuk el a programot!
10 NUMERIC PARAM
Sajnos semmi nem változott, a gép ugyanúgy hibát jelez, az eljárások paraméterváltozói ugyanis mindig belső változóknak számítanak. Ha létezik olyan külső változó, amelynek megegyezik a neve egy belső változóval, akkor az eljáráson belül csak a belső, kívül pedig csak a külső változót tudjuk használni. A 10-es sor hatására létrejön egy külső változó, de a 40-es, 50-es sorokban a gép természetesen a belső PARAM nevű változót fogja használni, hiszen ezek a sorok az eljáráson belül vannak. A 80-as sorban levő PRINT utasítás a külső PARAM nevű változó tartalmát próbálja kiírni, de mivel ebbe a változóba még nem töltöttünk semmit, ezért hibát jelez. Próbáljunk valamit beírni a külső PARAM változóba! írjuk be a következő sort és futtassuk le a programot!
20 LET PARAM=1
Most már nem jelez hibát a gép, a második kiírt szám azonban természetesen a külső változó tartalma, azaz egy. A teljes program most így néz ki:
10 NUMERIC PARAM
20 LET PARAM=1
30 DEF ELJ(PARAM)
40 LET PARAM=PARAM*2
50 LET ELJ=PARAM+1
60 END DEF
70 PRINT ELJ(5)
80 PRINT PARAM
Tanulmányozzuk át figyelmesen, próbáljuk megmagyarázni az egyes sorok jelentését! Gondoljuk végig, hogy melyik sor melyik változó tartalmát változtatja meg. Figyeljünk arra is, hogy külső vagy belső változóról van-e szó! Futtassuk le a programot úgy is, hogy megváltoztatjuk a 20-as és a 70-es sorban a PARAM nevű külső illetve belső változóba kerülő értéket!
Használjuk bátran új függvényeinket, sok feladat megoldását egyszerűbbé teszik.
1. nap - Programok egymás közt
Eljárásainkat úgy tudjuk megkülönböztetni, hogy mindegyiknek más és más nevet adunk. Programjainknak azonban eddig csak akkor tudtunk nevet adni, amikor felvettük őket kazettára, a SAVE paranccsal. (Lásd a HETEDHÉT ENTERPRISE első hetének 3. napját.) Lehetőség van arra is, hogy már a program első sorában kijelöljük a program nevét. Erre szolgál a PROGRAM utasítás, amelynek sorrendben mindig a legelsőnek kell lennie. Ha nem így van, a gép ezt a hibát magától sajnos nem jelzi, csak onnan vehetjük észre, hogy időnként egészen mást csinál, mint amit szeretnénk. Nézzünk egy példát!
10 PROGRAM "neves"
20 REM Ennek a programnak
30 REM az a neve, hogy neves
Ha ezt a programot fel akarjuk venni kazettára, akkor nem kell neki nevet adni, hiszen már van, elég annyit mondanunk:
SAVE
A legfelső sorban azonnal megjelenik a SAVING NEVES felirat, tehát a gép ezt a nevet írta fel a program elé, a kazettára. Természetesen haakarjuk, más néven is szalagra vehetjük programunkat, ilyenkor a SAVE parancsban adjuk meg a nevet:
SAVE "masnev"
Ezzel a paranccsal most egy másik névvel vettük fel a programot, a kazettára, a program elé a MASNEV került. Ugyanakkor a programban a 10-es sor továbbra is a régi maradt, a PROGRAM utasítás nem változott.
Az eljárásoknak nemcsak nevet, hanem paramétereket is tudtunk adni. Vajon lehetnek a programoknak is paramétereik? Igen. Az eljárások paraméterváltozóit az eljárás első sorában, a DEF utasításban adtuk meg, a programokét pedig a PROGRAM utasításnál, az eljárásokhoz hasonlóan, zárójelek között. Igen ám, de hogyan lehet a programot meghívni, megadni a paramétereit? A program indítására a START parancs szolgál, ennek megfelelően a paraméterek értékét is itt adhatjuk meg. Írjuk be a következő programot!
10 PROGRAM "neves"(SZAM)
20 PRINT SZAM
Most indítsuk el a START paranccsal (F1). A program nullát ír ki. Ez igen fontos különbség az eljárásokhoz képest. Ha egy eljárásnak paraméterei vannak, és mi anélkül hívjuk meg, hogy megadnánk a paraméterváltozók értékeit, akkor a gép hibát jelez. A fenti programnak van egy paraméterváltozója, a SZAM nevű, de amikor a programot meghívtuk, nem adtunk neki értéket. A programok esetében ilyenkor nem lép fel hiba, hanem automatikusan nullát, vagy ha szöveg típusú, akkor egy üres szöveget tölt a gép a paraméterváltozóba. Ha viszont megadunk egy értéket, akkor az kerül bele. Például futtassuk le a programot a következő paraméterrel:
START (15)
Most már 15-öt ír ki, hiszen ez került a SZAM változóba. Közben megtanultuk, hogy a programok paramétereit a START parancsban, zárójelek között adhatjuk meg. Sőt, nemcsak a paramétereit, hanem azt is meghatározhatjuk, hogy hol kezdje végrehajtani a programot! Nézzük a következő példát:
10 PROGRAM "pelda"(SZAM)
20 PRINT MASIK
30 PRINT SZAM
Indítsuk el a START (15) utasítással! A gép hibát jelez a 20-as sorban, hiszen a MASIK változónak nem adtunk értéket. Most próbálkozzunk egy új megoldással:
START 30 (15)
Ez a parancs azt jelenti, hogy a 30-as sortól kezdve hajtsa végre a programot a gép, de előtte töltsön be 15-öt a paraméterváltozóba. A program hiba nélkül lefut, és ki is írja a 15-öt. Most már programjainknak is tudunk paramétereket adni, és meg tudjuk mondani, hol kezdődjön a program végrehajtása. Vajon azt is meg tudjuk adni, hol legyen a vége? Természetesen. Erre való az END utasítás.
Mi már több helyen használtuk az END szócskát, például az END SELECT, vagy az END DEF utasításban. Ha nem írunk az END után semmit, akkor ez az utasítás jelzi a program végrehajtásának a végét. Az END-nek nem kell a legutolsó sorban állnia, és egy programon belül akár több helyen is előfordulhat. A gép akkor fejezi be a futást, amikor valamelyik END-hez, vagy a legutolsó sorhoz ér. Nézzük meg a következő programot:
10 DO
20 INPUT SZIN
30 LET SZIN=IP(SZIN)
40 IF SZIN<0 THEN
50 END
60 END IF
70 IF SZIN>255 THEN
80 END
90 END IF
100 SET BORDER SZIN
110 LOOP
Ez a program a keret színét állítja be a megadott értékre. Ha azonban nullánál kisebb, vagy 255-nél nagyobb számot adunk meg, akkor az 50-es, vagy a 80-as sorban levő END utasításra kerül a vezérlés, és a gép megáll. Próbáljuk ki, indítsuk, el a programot!
Programjainknak, az eljárásokhoz hasonlóan, most már van neve. Az eljárások neve azonban arra is szolgál, hogy az egyszerre a gépben levő több eljárás közül kiválasszuk azt, amelyiket végre akarunk hajtani. Vajon lehet-e egyszerre több program a gépben? Igen, lehet. Az ENTERPRISE 128 db, egymástál különböző programot képes egyszerre tárolni. Pontosabban csak annyit, amennyi a memóriájában elfér. Hosszú programokból tehát kevesebbet, rövidebbekből többet. Hogyan lehet a memóriában egyszerre tárolt programokat egymástál megkülönböztetni? Honnan tudjuk, hogy mikor melyikkel van dolgunk?
A programoknak nemcsak nevük, hanem sorszámuk is van. Amikor a gépet bekapcsoljuk, a nullás programot kezdjük írni. A programok számát a legfelső sorból tudjuk meg, ahol a következő olvasható:
IS-BASIC program 0
írjunk be ide egy rövid programot:
10 PROGRAM "nullas" (SZAM)
20 PRINT SZAM
Most térjünk át egy másik programra, mondjuk a hetesre. Ehhez az EDIT parancsot kell használnunk, amely mögött jelölnünk kell, hogy melyik programot szeretnénk használni. írjuk be:
EDIT 7
A legfelső sorban azonnal feltűnik az új program száma:
IS-BASIC program 7
Most próbáljuk meg kilistáztatni a programot:
LIST
A gép azonban nem ír ki semmit! Nem is írhat, hiszen a hetes programnak még egyetlen sorát sem írtuk meg. A LIST AUTO, RENUMBER, stb. parancsok mindig az aktuális programra vonatkoznak, amelyiknek a számát a legfelső sorban olvashatjuk. A nullás program kilistázásához vissza kell térnünk az előző programunkhoz. Erre is az EDIT parancsot kell használnunk. Megfelel az EDIT 0 utasítás is, de a nullás programnak mi már nevet is adtunk, a PROGRAM utasításban. Használhatjuk ezt a nevet is, írjuk be:
EDIT "nullas"
A felső sorbál láthatjuk, hogy tényleg visszatértünk a nullás sorszámú programra. Ha lenyomjuk az F2 billentyűt, ki is tudjuk listáztatni.
Az eljárások fontos tulajdonsága, hogy az egyik eljárás meg tudja hívni a másikat. Vajon a programok is képesek erre? Igen, erre is van mód. Lépjünk át a 10-es programra:
EDIT 10
Most írjuk be következő rövid programot:
10 PROGRAM "masik"
20 PRINT "szervusz!"
Futtassuk le a programot! A gép kiírja a szervuszt, és szépen rendben leáll. A felső sorból látható, hogy még mindig a tizes programot használjuk. Hogyan lehetne meghívni a nullás programot? Nos, erre szolgál a CHAIN parancs. A CHAIN parancsban, hasonlóan az EDIT-hez, egy másik program számát vagy nevét kell megadnunk. Ha a másik programnak paraméterei is vannak, azokat is itt kell zárójelek között felsorolni. írjuk be a következő sort:
30 CHAIN 0 (21)
Ez lett a tízes program harmincas sora, hiszen mi most - amint ezt a legfelső sorban látjuk is - a tízes programot használjuk. A teljes programot kilistázva (F2) ez látható:
10 PROGRAM "masik"
20 PRINT "szervusz!"
30 CHAIN 0(21)
A harmincas sorban levő CHAIN utasítás hatására a gép majd meghívja a nullás sorszámú programot, és átadja neki paraméterként a 21-et. Indítsuk el!
A program kiírja, hogy szervusz, majd a következő sorba a 21-et. A szervuszt a tízes program 20-as sora írta ki, ezután hívtuk meg a nullás programot, ami a paraméterként megkapott értéket írta fel, azaz a 21-et. És utána visszatért a tízes programhoz? Ha megnézzük a legfelső sort, láthatjuk, hogy még mindig a nullás programban vagyunk. A programok tehát abban is különböznek az eljárásoktól, hogy ha egy programból meghívunk egy másikat, akkor annak végrehajtása után a gép nem folytatja az első programot, hanem leáll. Ha a nullás program után újra a tízesre szeretnénk sort keríteni, akkor újabb utasítással kell jeleznünk ezt. Semmi baj, mondanánk, írjuk be a nullás program végére a következő sort:
30 CHAIN "masik"
Indítsuk el! A képernyőn végtelen sorban tűnnek fel a szervuszok és a 21-ek. Igen, a CHAIN parancs ugyanis mindig a hívott program legelején kezdi meg a végrehajtást, a gép tehát ide-oda ugrál a nullás és a tízes program között, az egyik mindig kiírja a 21-et, a másik meg a szervuszt. Állítsuk meg a gépet a STOP billentyűvel! Vajon mit lehet itt tenni?
Használjuk fel azt, hogy a programok a paramétereken keresztül egymásnak üzenhetnek, így lehetőségünk van segíteni a bajon. A megoldás azonban nem olyan általános, mint azt már megszoktuk. A problémát minden programnál más-más módszerrel lehet kiküszöbölni. A példa kedvéért mutatunk egy lehetséges javítást, ami ebben az egy esetben sikeres lehet.
A hiba kijavításának módját keresve gondoljunk arra, mit írt ki legelőször a nullás program. Ha már nem emlékszünk rá, akkor az EDIT paranccsal lépjünk át a nullás programra, s erről a legfelső sort megnézve győződjünk is meg! Indítsuk el újra a programot és figyeljük meg, mi az első szám, amit kiír!
A nulla! Amikor ugyanis a START paranccsal indítjuk a programot, akkor a paraméterváltozó nem kap értéket, tartalma tehát nulla lesz. De ha a tízes sorszámú programból hívjuk meg, akkor a paraméterváltozóba már 21-et töltünk. A nullás program tehát a paraméteréből meg tudja állapítani, hogy a START paranccsal, vagy a tízes programból a CHAIN-nal indítottuk-e el. Ha most olyan utasításokat írunk a program végére, amelyek csak akkor hívják meg a MASIK programot, amikor a paraméter értéke nulla, akkor a végtelen ugrálásnak hamar vége szakad. Ha tehát a tízes programbál hívjuk meg a nullás programot, akkor annak paramétere már nem nulla lesz, s így a gép már nem tér vissza a hívó programba. Lépjünk tehát át az edit paranccsal a nullás programba (EDIT 0), és javítsuk át a végét:
30 IF SZAM=0 THEN CHAIN "masik"
Indítsuk el a programot! A következő tűnik fel:
0
szervusz!
21
Először lefutott a nullás program, paraméter nélkül, pontosabban nulla értékű paraméterrel, így nullát is írt ki. Ezután meghívta a MÁSIK programot, ami kiírta a szervuszt, és újra elölről kezdte a nullás programot. Igen ám, de a paraméter értéke ekkor már 21 volt. A nullás program 21-et írt ki, és mivel a 21 nem 0, tehát nem hívta meg újra a tízes programot, hanem leállt.
Most már két programunk van a gépben. Ezeket még fejben tudjuk tartani, de ha többet is szeretnénk egyszerre elhelyezni a memóriában, akkor nehezen fogunk eligazodni közöttiek. Az ENTERPRISE egy különleges parancsa éppen az ilyen tájékozódást könnyíti meg. Ez az INFO. Az INFO parancsot kiadhatjuk az F8 billentyűvel is, próbáljuk ki! A képen körülbelül ezt látjuk:
131072 bytes in system
98410 bytes unused
0* 64 10 PROGRAM "nullas"
(SZAM)
10 46 10 PROGRAM "masik"
Az első két sorból megtudjuk, hogy a gépben 131072 memória rekesz (azaz 128 kilobájt) van. Ebből 98410 még szabad, senki sem használja. A szabad rekeszekbe írhatunk újabb programokat vagy adatokat tárolhatunk bennük. A már foglalt rekeszekben vannak az eddig megírt programjaink és a VIDEO memória is. A képernyőn olvasható következő sorok már a memóriában levő programokról adnak információkat.
Az első másfél sor a nullás sorszámú programról tájékoztat. Mivel ez a program van éppen használatban, ezért a nullás sorszám mögé egy csillagot is tett a gép. Ezután kiírta, hogy ez a program 64 memória rekeszt foglal le, majd a program első sorát. Most már látjuk, miért volt fontos a PROGRAM utasítást az első sorba írni! Ez a sor tartalmazza ugyanis a program nevét és paramétereinek listáját is.
A következő sorban a tízes program adatait (sorszámát, helyigényét és az első sorát) olvashatjuk. Mivel több programot jelenleg nem tartalmaz a memória, ezért más nem jelenik meg. Az INFO utasítással mindig adatokat kaphatunk arról, hogy mennyi szabad helyünk van még, mekkora programot tudunk még beírni. A már bent levő programokról is fontos információkhoz jutunk. Ha pedig kevés a hely, kiválaszthatjuk, hogy melyik programot töröljük ki.
Hogyan tudunk programot törölni? Nos, az egyik megoldás az, hogy az EDIT paranccsal belépünk a már feleslegessé vált programunkba, majd a DELETE paranccsal töröljük. Ezt egy külön paranccsal, a NEW-val is elvégezhetjük. A new (ejtsd: nú) szó jelentése: ti. Programokat általában azért szoktunk törölni, hogy újakat írhassunk be helyettük. Ha minden programot egyszerre szeretnénk kitörölni, akkor ezt az ALL szócskával kell jeleznünk. Az all (ejtsd: ó1) angol szó, azt jelenti, összes. Nagyon vigyázzunk azonban ezzel a paranccsal, mert valóban az összes programunkat egy csapásra kitörli. Tehát a NEW ALL utasítást csak a legritkábban alkalmazzuk.
A számítógép az üzeneteit jelekkel írja ki a képernyőre. Ezek a jelek lehetnek betűk, számok vagy írásjelek, amelyeket egységesen karaktereknek nevezünk. Az egyes karaktereket egymástól formájuk, alakjuk alapján különböztetjük meg. Az U betű alakja más, mint az O-é, és így tovább.
A gép azonban nem lát, így a jeleket sem ismerheti fel az alakjukról. A jelek helyett számokat használ. Minden karakternek egy-egy szám felel meg. Már találkoztunk ezekkel a számokkal, tudjuk, hogy az ORD függvénnyel megállapíthatjuk, melyek az egyes betűkhöz tartozó számok, és a CHR$ függvénnyel a számokhoz tartozó karaktereket kaphatjuk meg.
De ha egyszer nem ismeri a jelek alakját, akkor hogyan tudja kirajzolni azokat a képernyőre? Nos, a gép a betűket is pontosan ugyanúgy írja ki, mint ahogy bármi mást: pontról pontra. A memóriájában van egy szótár, amiben minden érvényes számhoz (0-255) tartozik egy bejegyzés. Ez a bejegyzés tartalmazza egy-egy adott betű pontokból kirakott képét, vagyis azt, hogy ezek a pontok egymáshoz képest hogyan helyezkednek el. Olyan ez, mint egy kirakás játék, pontokból rakunk ki betűket. Az A betűt például valahogy így:
O |
O |
O |
|||||
O |
O |
||||||
O |
O |
||||||
O |
O |
||||||
O |
O |
O |
O |
O |
O |
O |
|
O |
O |
||||||
O |
O |
||||||
O |
O |
||||||
Minden jelhez kilenc sor tartozik, minden sorban nyolc pont lehet. Mivel ez a jeltár a memóriában van, ezért mi is írhatunk bele, módosítani is tudjuk a betűk alakját! Ehhez azonban a kívánt jel alakját a gép számára is érthető számokká kell alakítani. Közismert tény, hogy a számítógépek kettes számrendszert használnak. Ebben a számrendszerben csak kétféle számjegyet szabad használni, az egyest és a nullát. Ezzel a két számjeggyel kell tehát felírnunk a kívánt jel alakját. Mindent festékpont helyére kerüljön egy egyes, ahova nem akarunk festéket tenni, oda pedig egy nulla. Az A betű valahogy így nézne ki:
0 |
0 |
0 |
1 |
1 |
1 |
0 |
0 |
0 |
0 |
1 |
0 |
0 |
0 |
1 |
0 |
0 |
1 |
0 |
0 |
0 |
0 |
0 |
1 |
0 |
1 |
0 |
0 |
0 |
0 |
0 |
1 |
0 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
0 |
1 |
0 |
0 |
0 |
0 |
0 |
1 |
0 |
1 |
0 |
0 |
0 |
0 |
0 |
1 |
0 |
1 |
0 |
0 |
0 |
0 |
0 |
1 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
Ezeket a kettes (idegen nevén bináris) számrendszerben felírt számokat a BIN függvénnyel tudjuk a mindennapi életben használt tízes számrendszerbe tartozó számokká alakítani. A következő programmal megtudhatjuk bármely bináris szám tízes számrendszerbeli megfelelőjét:
10 DO
20 PRINT "A binaris szam"
30 INPUT BINSZAM
40 PRINT "A binaris ";BINSZAM;"=";
50 PRINT BIN(BINSZAM)
60 LOOP
Indítsuk el! Írjuk be a fenti bináris számokat, a gép pedig majd szépen sorba kiírja a tízes számrendszer szerinti megfelelőjüket:
BIN(00011100) = 28
BIN(00100010) = 34
BIN(01000001) = 65
BIN(01000001) = 65
BIN(01111111) = 127
BIN(01000001) = 65
BIN(01000001) = 65
BIN(01000001) = 65
BIN(00000000) = 0
Most már csak azt kell eldöntenünk, hogy melyik számhoz akarjuk hozzárendelni ezt az alakot. Legyen ez mondjuk a 105-ös, ami egyébként az i betű. A jeltárba a SET CHARACTER utasítással tudunk beírni, amely után meg kell adnunk, a módosítani kívánt jel számát, ezután pedig egymás után sorra be kell írnunk az új jelalak sorainak megfelelő tízes számrendszerbeli számokat.
set character 105,28,34,65,65,127,65,65,65,0
Ettől kezdve, ha lenyomjuk az i betűt, akkor nem i, hanem egy A, pontosabban az az alak jelenik meg, amit mi rajzoltunk fel. Próbáljuk ki, nyomjuk le néhányszor az i billentyűt! Figyeljük meg azt is, hogy a képernyőn Levő összes i betű is átváltozott!
De ha nincs i betűnk, akkor hogyan tudunk programozni? Hiszen nem egy kulcsszóban van i betű is, azokat tehát nem tudjuk i nélkül leírni! Ilyen például a PRINT, IF, vagy a LIST. Semmi baj nincs. A számítógép ugyanis, mint tudjuk, nem lát, nem ismeri a jelek alakját, tehát nem is foglalkozik azzal, hogy mit rajzol ki a képernyőre. A billentyűket kódszámukról ismeri fel, az i billentyű kódszáma azonban továbbra is 105, legfeljebb ha lenyomjuk, akkor nem i, hanem egy A jelenik meg. A gép viszont ezt az A-t továbbra is i-nek tekinti, hiszen a száma 105. Próbáljuk ezt ki, írjuk be kisbetűkkel a list parancsot. A képernyőn, természetesen, a kis i helyett egy nagy A jelenik meg, Így:
lAst
Az ENTER leütése után a gép szépen ki is írja a programot, tehát felismerte a parancsot. Csakhogy kiírás közben továbbra is minden kis i helyett nagy A-t írt. A nagy I-k nem változtak, hiszen azok kódszáma nem 105, hanem 73. A lista így néz ki:
10 DO
20 PRINT "A bAnarAs szam"
30 INPUT BINSZAM
40 PRINT "A bAnarAs";BINSZAM;"=";
50 PRINT BIN(BINSZAM)
60 LOOP
A 20-ass és a 40-es sorban láthatók az A-vá változott i-k. Bármelyik betű képét megváltoztathatjuk így a képernyőn, vagy akár lehetőségünk van az ékezetes magyar betűk megrajzolására is, csak azt ne felejtsük el, hogy a gép számára ezek az új betűk továbbra is az eredeti billentyűket jelentik.
Ha azonban már elég sok billentyűt átrajzoltunk, előbb utóbb szeretnénk visszatérni az eredeti karakterekhez is. A CLEAR FONT utasítás hatására valamennyi billentyű egy csapásra visszanyeri az eredeti alakját, úgyhogy kezdhetjük elölről a rajzolgatást.
Az ENTERPRISE-al nemcsak a betű alakját változtathatjuk meg, hanem a kurzort is átrajzolhatjuk. Pontosabban megmondhatjuk, hogy melyik billentyűhöz tartozó betűt szeretnénk kurzorként használni. Tegyük fel, hogy az éppen most felrajzolt, az i billentyű kódjával jelölt, A jelet akarjuk kurzornak. Ekkor a következő utasítást kell kiadnunk:
SET CURSOR CHARACTER 105
írjuk is be! A kurzor abban a pillanatban egy ugráló A betűvé változik. Adjuk most ki a CLEAR FONT parancsot! Most meg i betű lett a kurzor. Ez így van rendjén, ugyanis a SET CURSOR CHARACTER utasítással a kurzorhoz a 105-ös számú jelalakot rendeltük. Ez az alak akkor az általunk tervezett A betű volt. A CLEAR FONT utasítás azonban az eredetire állította vissza billentyűk alakját, így a 105-ös számhoz újra az i alak tartozik, tehát ez villog a kurzor helyén.
A kurzor eredeti alakjának kódszáma 142, így az eredetei kurzort a következő utasítás állítja vissza:
set cursor character 142
A kurzor színét is alakjához hasonlóan változtathatjuk. A SET CURSOR COLOR utasítással megadhatjuk, hogy hányas tégelyből vett festékkel rajzolja ki a kurzort a gép. Fontos tudnunk, hogy erre a színre ugyanaz a szabály vonatkozik, mint amit a HETEDHÉT ENTEPRISE harmadik hetének 3. napján a szöveges lap tintájának színére megismertünk. A gép tehát vagy az 1-es, vagy a 3-as tégelyből veszi a tintát, még akkor is, ha mi 0-t vagy 2-t adtunk meg az utasításban. Próbáljuk ki a következő utasítást:
set cursor color 1
Lám, a kurzor színe megváltozott, ahogy azt vártuk. Az eredeti színe a 3-as volt.
Ezeket az eszközöket ritkán használjuk, de néha igen hasznos segítőink lehetnek, ne feledkezzünk meg róluk!
Bizony gyakran megesik velünk, hogy elveszítjük a türelmünket, szeretnénk, ha valami korábban történne meg, mint szokott. Van aki a télapót szeretné hamarább viszontlátni, van aki a kedvenc együttesének következő nagylemezét siettetné, és van aki szeretne mások előtt szóhoz jutni. Az is megesik, hogy a nagy sietségben néha egymás szavába vágunk. A számítógép egyedül van, de vele is megeshet, hogy miközben éppen valamit zenél, hirtelen szeretne közbeszólni, valami más hangot lejátszani. Ilyenkor meg kell szakítania a dallamot. Vajon hogyan dalol a gép? Erre a HETEDHÉT ENTERPRISE harmadik hetének 6. napján kaptunk választ, ott olvastunk a SOUND utasításról. Most ismét nézzünk meg egy egyszerű programot!
10 SOUND PITCH 37,DURATION 50
20 SOUND PITCH 41,DURATION 50
30 SOUND PITCH 44,DURATION 50
40 SOUND PITCH 49,DURATION 50
50 PRINT "VEGE"
Futtassuk le a programot! A hangszóróból rövid kis dallamot hallunk és a képernyőn megjelenik a VEGE felirat. Most futtassuk le mégegyszer, de közben figyeljük meg, hogy mikor jelenik meg a szöveg!
Ahogy azt a HETEDHÉT ENTERPRISE-ban olvashattuk, a program nem várja meg, amíg az egyes hangok véget érnek, hanem sorra megadja a hangok adatait a gépnek, amely majd egymás után megszólaltatja azokat, eközben pedig a program tovább halad. Még az első hang sem ért véget, s program máris a PRINT utasításhoz érkezett, így a VEGE feliratot jóval a dallam befejeződése előtt kiírja.
Látjuk, hogy a program végét jelző "ok" Üzenet és a villogó kurzor jóval hamarabb tűnik fel, mielőtt még a zene véget érne. Próbáljuk meg jelezni a program végét egy hanggal! Ehhez írjuk be a követekező sort:
60 SOUND PITCH 65,DURATION 100
Ez most a program legutolsó utasítása, tehát közvetlenül a program vége előtt szólal meg ez a kis sípszó és jelzi a feladat befejezését. Futassuk le!
Bizony nem az történik, amit szerettünk volna. A gép, mint azt tudjuk, a programban megadott hangokat szépen sorba rakja és egymás után szólaltatja meg. A 60-as sorban megadott hangot nem akkor halljuk, amikor a program véget ér, hanem amikor elfogynak előle a sorban álló hangok, azaz amikor a dallam véget ér. Igen ám, de mi már tudjuk, hogy a program jóval hamarább befejeződik, mint a zene! Hogyan érhetjük azt el, hogy a síp tényleg akkor szólaljon meg, amikor a program végéhez érünk?
Valójában itt azt szeretnénk elérni, hogy a gép a saját szavába vágjon, azaz szakítsa meg a programban megadott hangok lejátszását és soron kívül szólaltasson meg egy másikat. A megszakítás angol neve interrupt, amit interáptnak ejtünk. írjuk be a 60-as sor végére, vesszővel elválasztva ezt a szót
60 SOUND PITCH 65,DURATION 100,INTERRUPT
Most futtassuk le ismét a programot! Először megszólal a dallam legelső hangja, majd megjelenik a VELE felirat. Ezután azonban nem a dallam folytatását halljuk, hanem megszólal a síp! Azok a hangok, amelyek eddig nem kerültek sorra eltűnnek , a dallam folytatását a gép már nem játssza le.
Még egy dolgot érdemes megfigyelnünk! A 60-as sor hatására egy sípszó hallható. Ez a program utolsó utasítása, tehát ez a síp a program végét jelzi. A sípszó hossza két másodperc, hiszen DURATION 100-at adtunk meg. Igen ám, de az "ok" felirat és a kurzor még jóval azelőtt látható, lesz, mint ahogy a sípszó véget ér. Ez érthető is, hiszen ezt a sípot ugyanúgy szólaltatja meg a gép, mint a többi hangot, csak előtte kiüríti azt a várakozási listát, amiben a korábban megadott hangok várakoznak. Az INTERRUPT hatására tehát nem csupán az éppen hallható dallam szakad félbe, hanem ez a várakozási sor is kiürül, majd az INTERRUPT szóval kiegészített SOUND utasításban megadott hang kerül a sor legelejére, és azonnal meg is szólal. Ezt a hangot azonban ugyanúgy játssza le a gép, mint bármelyik másikat, tehát ezt is félbe lehet szakítani. írjuk be a következő sort:
70 SOUND PITCH 50,DURATION 100,INTERRUPT
Indítsuk el ismét a programot! Most is a dallam kezdőhangját szólaltatja meg először, majd kiírja a VEGE szöveget és felharsan a síp. Rögtön ezután azonban félbe is szakad, mert a 70-es utasításban szereplő SOUND INTEERUPT félbeszakítja, s helyette egy dudát szólaltat meg.
Próbáljuk ki a programot úgy is, hogy az első négy SOUND utasítás végére is INTERRUPT-ot írunk. Magyarázzuk meg, mi a különbség! Most töröljük ki az 50-es, 60-as, 70-es sorokat, helyettük pedig írjuk be a következő két sort:
5 DO
100 LOOP
Figyeljünk arra, hogy a megmaradt 10-es, 20-as 30-as és 40-es sorok végén ott álljon az INTERRUPT szócska! Most indítsuk el a programot! Ugye jópofa? Ha akarjuk kipróbálhatjuk úgy is, hogy kitöröljük az INTERRUPT-okat, ezután azonban győződjünk meg arról, hogy valóban sikerült-e a módosítás! Listáztassuk ki a programot! Ezt kell látnunk:
5 DO
10 SOUND PITCH 37,DURATION 50
20 SOUND PITCH 41,DURATION 50
30 SOUND PITCH 44,DURATION 50
40 SOUND PITCH 49,DURATION 50
100 LOOP
Ha így indítjuk el a programot, sokkal lassabban fogják váltani egymást a hangok, hiszen mindegyik szépén megvárja, amíg az előtte levő véget ér. Akkor is tovább szól a zene, ha a STOP billentyűvel leállítjuk a programot? Igen, hiszen a gépben levő várakozási sor még nem ürült ki, az ott szereplő hangokat még lejátssza a számítógép. Közben azonban mi már mást is csinálhatunk, hiszen a program valójában véget ért, a gép újabb parancsokra vár.
Töröljük ki ezt a programot és próbáljunk ki valami mást! Mi lenne, ha egy véletlen dallamot énekeltetnénk el a géppel? Véletlen dallam az, amelynek hangjai véletlenszerűen követik egymást. Mivel mi a hangokat számokkal jelöltük, ezért ha elő tudunk állítani véletlen számokat, akkor az ezeknek a számoknak megfelelő hangokat lejátszva egy véletlen dallamot kapunk.
Véletlenszámokat a HETEDHÉT ENTERPRISE +1 napján megismert RND függvénnyel tudunk előállítani. Mivel az RND értéke mindig nulla és egy között levő szám, nekünk azonban körülbelül harminc és ötven közötti számokra lenne szükségünk, ezért mi mindenütt az RND*20+30 értéket fogjuk használni. Írjunk hát egy rövid kis programot, ami három véletlenhangból állá dallamot játszik le:
10 SOUND PITCH RND*20+30
20 SOUND PITCH RND*20+30
30 SOUND PITCH RND*20+30
Nyomjuk le az F1 billentyűt, azaz indítsuk el a programot! Három teljesen össze-vissza hangot hallunk. Érthető, a gép ugyanis három véletlenszámot állított elő, tehát az ezeknek megfelelő három hang is ilyen rendezetlen.
Most ismét nyomjuk le az F1-et. A program ismét lefut, három véletlen hangot hallunk. De figyeljünk csak oda! Hallgassuk meg újra ezt a három hangot! Hiszen ugyanezeket játszotta az előbb is a gép! Talán valahol bent maradtak a gépben, és most csak ezeket lehet előhívni? Vajon mi lehet az oka, hogy akárhányszor futtatjuk le a programot, mindig ugyanaz a három véletlenhang hallatszik?
Nos, ha mindig ugyanazok a hangok hallhatóak, akkor bizonyára ugyanazok a nekik megfelelő véletlenszámok is. Ha pedig a véletlenszámok ismétlődnek, akkor valahol a véletlenszám-generátorban van a hiba. Pontosabban ez nem is hiba, csupán az RND függvény egyik tulajdonsága. Ez a függvény egymás utáni véletlenszámokat állít elő. Azt, hogy melyik számnál kezdi a számok felsorolását, tehát hogy melyik lesz a legelső és milyen sorrendben követik azt a többiek mi nem tudhatjuk előre, ezért is véletlenek ezek a számok. A gép azonban meg tudja ismételni őket. Valahányszor újra elindítjuk a programot, a véletlenszám-generátor mindig elölről kezdi a működést, azaz elölről kezdi a véletlenszámok felsorolásit.
De hát milyen véletlenszám-generátor az, amelyik mindig ugyanazokat a számokat adja vissza? Nos, a probléma oka az, hogy ez a generátor mindig az előző véletlenszámból számítja ki egy igen-igen bonyolult műveletsorozattal a következőt. Ha tehát ugyanabból a kezdőszámból indulunk ki, akkor egymás után mindig ugyanazokat az értékeket kapjuk. A mi programunk valójában mindig ugyanannak a három értéknek, a három legelső véletlenszámnak megfelelő hangot játssza le. De hát hogyan lehetne ezen segíteni?
Erre való a RANDOMIZE utasítás. Ennek hatására az RND függvény ugrik egyet, és nem onnan kezdi a számokat sorolni, ahol éppen tart, hanem valahonnan máshonnan. Ha a program legelején adjuk ki a RANDOMIZE-t, akkor a gép mindig más és más dallamot fog lejátszani. Próbáljuk ezt ki! írjuk be a következő sort és indítsuk el a programot!
5 RANDOMIZE
Ha egymás után többször lenyomjuk az F1 billentyűt mindig más és más zenét hallhatunk, feltéve, hogy ezek az össze-vissza hangok egyáltalán zenének nevezhetők.
A mai nap végén álljon egy program, ami igazi számítógépes zenét játszik, azaz véletlen hangokat egymás után:
10 DO
20 SOUND PITCH RND*20+30,INTERRUPT
30 LOOP
Indítsuk el és gyönyörködjünk benne! Lehet, hogy ez a jövő zenéje?
4. nap - Bit Béla a tanárok réme,
avagy segít a változó paraméter
A tanítás utolsó napján történt. Bit Béla, az osztály legjobb számítástechnikusa szomorúan ballagott hazafelé. Bizony nem sikerült javítania matematikából. Holnap még lesz néhány óra (torna és számítástechnika), de ezek már mit sem változtathatnak a matekjegyén, ami bizony csak kettes. Az utolsó óra után az osztályfőnök szépen kiíratja az iskola számítógépéből az osztályzatokat - ez ugyanis egy igen modern iskola, ahol még a diákok jegyeit is számítógéppel tartják nyilván - és könyörtelenül beírja az ott szereplő kettest az ellenőrzőbe. Ezen már senki sem segíthet.
Még az a szerencse, hogy számítástechnikából nincs semmi vész. Béla eddig is csupa ötöst vitt haza. A másnapi feladat sem volt nehéz. Billentyű tanárúr (a fiúk csak úgy hívták: Enterke) mindenkit megbízott azzal, hogy készítsen egy olyan eljárást, amellyel majd kiszámíthatja jegyeinek átlagát. A négy legfontosabb osztályzatot, a matematika, a történelem, a magyar és a fizika jegyet kell paraméterként megadni, ebből kell átlagot számítani és betölteni az eljárás nevébe. Béla fejében már kész is volt a megoldás:
10 DEF BELA(MATEK,TORI,MAGYAR,FIZIKA)
30 LET BELA=(MATEK+TORI+MAGYAR+FIZIKA)/4
40 END DEF
Amikor hazaért, bekapcsolta jó öreg ENTERPRSE-át, és begépelte az útközben kigondolt eljárást. Kipróbálásához egy rövid programot is kellet írni, amelyik meghívta az eljárást:
90 CLEAR SCREEN
100 LET MATEK=2
110 LET TORI=4
120 LET MAGYAR=4
130 LET FIZIKA=5
140 PRINT "Bela atlaga=";
150 PRINT BELA(MATEK,TORI,MAGYAR,FIZIKA )
160 PRINT
170 PRINT "Bela jegyei:"
180 PRINT ,"matek=",MATEK
190 PRINT ,"tori=",TORI
200 PRINT ,"magyar=",MAGYAR
210 PRINT ,"fizika=",FIZIKA
220 PRINT
Ahogy el készült , azonnal le is futtatta a programot:
Bela atlaga= 3.75
Bela jegyei:
matek= 2
tori= 4
magyar = 4
fizika = 5
ok
Lám - gondolta Béla - milyen egyszerű is volna megváltoztatni a matekjegyet, mindössze egy új sort kellene beszúrni az eljárásba, húszas sorszámmal:
20 LET MATEK=5
Ezután így nézne ki az eljárás:
10 DEF BELA(MATEK,TORI,MAGYAR,FIZIKA)
20 LET MATEK=5
30 LET BELA=(MATEK+TORI+MAGYAR+FIZIKA)/4
40 END DEF
Begépelte az új sort és elindította a programot:
Bela atlaga= 4.5
Bela jegyei:
matek= 2
tori= 4
magyar = 4
fizika = 5
ok
Hát bizony ez nem jött be! Igaz ugyan, hogy az átlag majdnem egy jegyet javult, de ha ENTERKE csak rápillant az alatta levő osztályzatokra, rögtön láthatja, hogy turpisság történt.
Ha Béla nem tudta volna olyan jól a számítástechnikát, akkor talán nem értette volna, hogy miért írt ki a gép matematikából kettest, amikor pedig ő átírta ezt a jegyet ötösre (abban a bizonyos 20-as sorban). Béla azonban már elolvasta figyelmesen a HETEDHÉTEN TÚL második hetének 4. napját, így pontosan tudta, hogy az eljárások paraméterváltozói belső változók, azaz hiába is írunk beléjük akármit, a velük megegyező nevű külső változók értéke nem módosul.
A BELA eljárásban tehát hiába írjuk át a MATEK változó tartalmát 5-re, a főprogram 180-as sorában nem ebből a belső változóból, hanem a vele azonos nevű, de külső MATEK változóból írjuk ki az osztályzatot. Annak az értéke pedig továbbra is kettes.
Az lenne a jó, ha meg lehetne mondani a számítógépnek, hogy ezt a paraméterváltozót külsőként kezelje, mert akkor amit az eljáráson belül beleírok, az beíródna az eredeti külső MATEK változóba is" - s közben megsimogatta a jó, öreg ENTERPRISE-t. Ekkor azonban hirtelen egy kis manó bukkant elő a gép háta mögül.
- Ne búsulj, Béla! - szólt a manó - Én vagyok a te számítógéped bűvös bitkezelője. Ha valaki úgy összezavarja a programját, hagy már csak a csoda segíthet rajta, akkor én szoktam szépen rendbe rakni a gépben a biteket. De te olyan ügyes voltál, hogy melletted alig-alig volt dolgom, így jó sokat pihenhettem. Jótett helyébe jót várj, ezért én elárulom most neked a változó paraméterek titkát!
Béla döbbenten ült a gép mellett, figyelmesen hallgatta a manó szavait, az pedig nyugodtan folytatta tovább:
- Ha egy paraméterváltozó értékét az eljáráson belül úgy szeretnéd megváltoztatni, hogy az az eredeti külső változóba is bekerüljön, akkor az eljárás legelején, ott, ahol az eljárás nevét és paramétereit felsorolod, a paraméter neve elé írd azt, hogy REF. Ettől kezdve ez a paraméter referencia paraméterré változik át, azaz amit beléje írsz, az a megfelelő külső változóba is bekerül.
Béla szeme csillogni kezdett, ő már értette, hogyan segíthet rajta a referencia paraméter.
- De nehogy azt hidd, hogy akármikor össze-vissza használhatod ezeket a paramétereket. Jól vigyázz velük, mert ha egyszer eltéveszted a használatukat és rossz programot írsz velük, akkor hetvenhét napon keresztül kell majd keresned a hibát, mire megtalálod! - fejezte be szavait a manó, s azzal köddé vált.
Bélának nem is volt ideje megköszönni a segítséget, szégyellte is magát ezért egy kicsit, hát inkább azonnal munkához látott. Átírta az eljárás első sorát, a 10-est, pontosabban egy szót szúrt be a paraméterek listája elé:
10 DEF BELA(REF MATEK,TORI,MAGYAR,FIZIKA)
Ezután elindította a programot:
Bela atlaga= 4.5
Bela jegyei:
matek= 5
tori= 4
magyar = 4
fizika = 5
ok
Hurrá - kiáltotta Béla -, javítottam matekból. Éljen a referencia paraméter!
Másnap ezt a módosított eljárást vitte az iskolába, s nyugodtan várta a bizonyítványosztást, mert biztos volt győzelmében. Hogy meglepődött, amikor a matematika rubrikában egy jókora kettest talált! A bizonyítvány mellé Billentyű tanár úr egy rövid levelet is mellékelt:
"Kedves Fiam!
A referencia paramétereket titkának megfejtéséért külön dicséretet érdemelsz. Csalással azonban a számítástechnikában sem fogsz boldogulni!
Enterke "
Eddig tart Bit Béla története, mi azonban még foglalkozhatunk egy kicsit a referencia paraméterekkel. Ezek a paraméterek nem arra valók ugyanis, hogy egymást, vagy a tanárokat becsaphassuk. Ilyen paraméterekre akkor van általában szükségünk, amikor egy eljárással egynél több értéket akarunk kiszámítani.
Ha egy eljárás egyetlen értéket állit elő, akkor azt célszerű az eljárás nevébe tölteni, így kényelmesen, gyorsan tudjuk felhasználni.
Ha egynél több új érték keletkezett, akkor azokat idáig csak úgy tudtuk az eljárást hívó programrészletnek visszaadni, ha külső változókba töltöttük őket. E megoldásnak nagy hibája, hogy a külső változókat bármelyik másik eljárás is megváltoztathatta. Ilyen esetekben gyakran használjuk a referencia paramétereket. Nézzünk erre egy példát! A következő eljárás két paramétert kap, és helyes sorrendbe rendezi őket:
10 DEF SORRA( REF KISEBB,REF NAGYOBB)
20 IF KISEBB>NAGYOBB THEN
30 LET CSERE= KISEBB
40 LET KISEBB= NAGYOBB
50 LET NAGYOBB= CSERE
60 END IF
70 END DEF
Ezt az eljárást a következő főprogrammal hívhatjuk meg:
80 INPUT A,B
90 CALL SORBA(A,B)
100 PRINT "a kisebb=",A
110 PRINT "a nagyobb=",B
A program beolvas két számot és sorba rakja azokat. Manapság még a legmodernebb számítógépek is ilyen egyszerű kis eljárásokkal végeztetik el az egyes elemi feladatokat, mint például két szám sorrendbe rendezését. Ha bonyolultabb programokat szeretnénk készíteni, a referencia paraméterek nélkülözhetetlenek.
Ma megint külső és belső változókkal fogunk foglalkozni. Induljunk ki a harmadik hét 4. napjának utolsó eljárásából, amelyik sorba rendezi a két paraméterét:
100 DEF SORBA(REF A,REF B)
110 IF A>B THEN
120 LET C=A
130 LET A=B
140 LET B=C
150 END IF
160 END DEF
Az eljárásnak két paramétere van, ha ezek közül az első nagyobb, mint a második, akkor kicseréli őket. Mivel mindkét paramétere referencia típusú, ezért a változás az eljáráson kívül is végbemegy. A két szám kicseréléséhez egy harmadik változót is fel kellett használnunk, ez a C. Bár ez nem az eljárás paramétere, nem is az eljárás neve, nyugodtan használhatjuk, a számítógép majd automatikusan létrehozza ezt a változót is. Most készítsünk egy egyszerű programot, amelyik majd ezzel az eljárással rak sorba három számot:
10 INPUT PROMPT "A=":A
20 INPUT PROMPT "B=":B
30 INPUT PROMPT "C=":C
40 CALL SORBA(A,B)
50 CALL SORBA(A,C)
60 CALL SORBA(B,C)
70 PRINT "LEGKISEBB=",A
80 PRINT "KOZEPSO=",B
90 PRINT "LEGNAGYOBB=",C
A program először beolvas három számot. Ezután összehasonlítja az elsőt a másodikkal, majd az elsőt a harmadikkal. Az első két összehasonlítás után, tehát az 50-es sort követően, az A-ban már a legkisebb szám van. A 60-as sorban már csak a másik két számot kell sorba rendeznünk. Végül a gép ki is írja a helyes sorrendet. Indítsuk el a programot és írjuk be a következő három számot: 1,2,3. Ezt a választ kapjuk:
LEGKISEBB= 1
KOZEPSO= 2
LEGNAGYOBB= 3
Ez így jó is. Most azonban indítsuk el újra a programot és adjunk meg másik három számot: 3,2,1. Ez persze ugyanaz a három szám, csak más sorrendben. A válasz viszont lehangoló:
LEGKISEBB= 2
KOZEPSO= 3
LEGNAGYOBB= 3
Vajon mi történhetett a programmal, hogy így megbolondult? Listáztassuk ki most a teljes programszöveget, ami a gépben van és nézzük meg:
10 INPUT PROMPT "A=":A
20 INPUT PROMPT "B=":B
30 INPUT PROMPT "C=":C
40 CALL SORBA(A,B)
50 CALL SORBA(A,C)
60 CALL SORBA(B,C)
70 PRINT "LEGKISEBB=",A
80 PRINT "KOZEPSO=",B
90 PRINT "LEGNAGYOBB=",C
100 DEF SORBA(REF A,REF B)
110 IF A>B THEN
120 LET C=A
130 LET A=B
140 LET B=C
150 END IF
160 END DEF
A hiba oka azonnal felismerhető. A C változót a főprogramban egy beolvasott érték tárolására használtuk, az eljárásban pedig a cseréhez, munkaváltozónak. Igen, hiszen amikor az eljárást írtuk, akkor még nem tudtuk, hogy ilyen változónk lesz a főprogramban is, tehát nem is gondoltunk arra, hogy ezzel egy C nevű külső változó tartalmát is elronthatjuk.
Mi lehet a megoldás? Természetesen minden ilyen belső munkaváltozónak megjegyezhetjük a nevét, és gondosan ügyelhetünk arra, hogy ezeket még csak véletlenül se használjuk másutt. Ez azonban rendkívül nehézkes, arról nem is beszélve, hogy ha egyszer véletlenül mégis elrontjuk, akkor nagyon nehezen találjuk majd meg ezt a hibát.
Az ENTERPRISE ennél sokkal egyszerűbb lehetőséget is kínál. Hozzuk létre a C változót mégegyszer, de most már az eljáráson belül, mint belső változót!
Hogyan is tudunk egy változót létrehozni? Nos, ha még nem használtunk egy változót, akkor az első alkalommal, amikor majd használjuk, a gép automatikusan létrehozza nekünk. Ha ekkor éppen egy eljárás belsejében vagyunk, akkor a változó az eljárás belső változója, ha pedig eljáráson kívül, akkor külső változója lesz. Amikor az eljárást írtuk éppen erre számítottunk, ebben az esetben azonban ez nem volt jó megoldás, a későbbiek során ugyanis olyan programsorokat írtunk le, amelyek az eljáráson kívül, még az eljárás meghívása előtt használják a C-t.
Egy változót korábban is létrehozhatunk, mintsem használnánk. Ezt láttunk a HETEDHÉT ENTERPRISE harmadik hetének 4. napján, amikor egyes változókat előre külsőnek jelöltünk meg a STRING és a NUMERIC utasítás segítségével.
Ez a két utasítás azonban alkalmas arra is, hogy belső változókat hozzunk létre. Ha a NUMERIC-et egy eljáráson belül alkalmazzuk, akkor az így keletkező változó az eljárás belső változója lesz, tehát az értékéhez eljáráson kívül nem férhetünk hozzá, viszont ha használjuk, akkor ezzel nem rontjuk el a hasonló nevű külső változó tartalmát.
Próbáljuk ki ezt a mi esetünkben! Eljárásunk elejére, de már belülre, tehát a DEF sor után, írjuk be a következő utasítást:
105 NUMERIC C
Most futtassuk le a programot és ismét adjuk meg a korábbi három számot, méghozzá a problémás sorrendben: 3,2,1. Most már helyes választ kapunk:
LEGKISEBB= 1
KOZEPSO= 2
LEGNAGYOBB= 3
Természetesen nemcsak a NUMERIC, hanem a STRING utasítás is használható ilyen célra. A STRING-nek azonban van egy másik szolgáltatása is. Alakítsuk át a programot úgy, hogy ne számokat, hanem szövegeket rendezzen sorba! Ehhez a változókat szöveges típusúvá kell változtatnunk, ez azonban tudjuk, hogy nem nagy dolog, csak mindegyiknek a végére egy-egy dollárjelet ($) kell tennünk.
A 110-es sorban levő összehasonlítás - a dollárjelekkel kiegészítve - továbbra is jól fog működni, erről még a HETEDHÉT ENTERPRISE második hetének 4. napján olvashattunk. Ne feledkezzünk meg a szövegek összehasonlításának különlegességeiről sem, amiket szintén ott ismertünk meg. Nem egy numerikus (szám) változót akarunk létrehozni, hanem egy szöveg típustút, tehát a 105-ös sorban a NUMERIC utasítás helyett a STRING-et kell használnunk:
105 STRING C$
A teljes program a következő:
10 INPUT PROMPT "A=":A$
20 INPUT PROMPT "B=":B$
30 INPUT PROMPT "C=":C$
40 CALL SORBA(A$,B$)
50 CALL SORBA(A$,C$)
60 CALL SORBA(B$,C$)
70 PRINT "LEGKISEBB=",A$
80 PRINT "KOZEPSO=",B$
90 PRINT "LEGNAGYOBB=",C$
100 DEF SORBA(REF A$,REF B$)
105 STRING C$
110 IF A$>B$ THEN
120 LET C$=A$
130 LET A$=B$
140 LET B$=C$
150 END IF
160 END DEF
Próbáljuk ki, indítsuk el és adjunk meg három nevet, mondjuk: Lajcsi, Feri, Józsi. A gép persze átrendezi a sorrendet: Feri, Józsi, Lajcsi. Vigyázzunk, mert az összehasonlítás szempontjából a szövegek hossza fontosabb, mint a tartalma, a nagybetűk pedig mindig kisebbnek számítanak, mint a kisbetűk! Ezt is próbáljuk ki! Indítsuk el a programot és írjuk be: Zsuzsi, Anette, anette. A válasz:
LEGKISEBB= Anette
KOZEPSO= Zsuzsi
LEGNAGYOBB= anette
A Zsuzsi azért kisebb, mint az anette, mert nagybetűvel kezdtük írni! Ha most még a nevek hossza is eltérő, akkor mindig a rövidebb név számít majd kisebbnek. Adjuk meg a következő három nevet: Adrienn, Gizi, Zsuzsa. A gép a következő sorrendet írja ki:
LEGKISEBB= Gizi
KOZEPSO= Zsuzsa
LEGNAGYOBB= Adrienn
Látjuk, hogy a rövidebb szöveg mindig kisebbnek számit. Ne felejtsük el, hogy a STRING utasításban az egyes változók hosszát is megadhatjuk, tehát azt, hogy hány betű férhet az egyes szövegváltozókba. írjuk most be a következő programsort:
5 STRING A$*1,B$*2,C$*3
Ezzel a három külső szövegváltozót előre definiáltuk, méghozzá úgy, hogy az A$-ba csak egy, a B$-ba kettő, a C$-ba pedig három betű hosszúságú szöveg kerülhet. Ez persze nem jelenti azt, hogy hármójuk közül mindíg az A$ lesz a legkisebb, hiszen a B$-ba is írhatunk egybetűs szöveget. Próbáljuk ki most a programot az alábbi három szöveggel: b, aa, a.
LEGKISEBB= a
KOZEPSO= b
LEGNAGYOBB= aa
A legkisebbnek ítélt szöveg; az "a", eredetileg a C változóban volt, amiben akár három betű hosszúságú szöveg is lehet, de mivel most csak egy betűnyi volt, így ez nem okozott gondot. Mi történik azonban, ha ismét megváltoztatjuk az 5-ös sort, a következőre:
5 STRING A$*3,B$*2,C$*1
Nos, próbáljuk ki! Ismét indítsuk el a programot és írjuk be: b, aa, a. A gép hibát jelez! Ez azonban nem meglepő, ha végiggondoljuk, hogy a sorbarendezés során a C$ változóba az "aa" szöveget próbáltuk betölteni, ami két betű hosszúságú, tehát több, mint amennyi a C$-ba fér.
Ha mind a három változónak ugyanazt a szöveghosszüságot, betűszámot szeretnénk megadni, akkor ezt elegendő a STRING kulcsszó után egyszer leírnunk:
5 STRING *3 A$,B$,C$
Most már csak arra kell ügyelnünk, hogy ne gépeljünk be három betűnél hosszabb szöveget, mert azokat ez a program nem képes használni.
A szövegváltozók maximális hosszának megadása - láthattuk - sok kényelmetlenséget okoz. Erre mégis sokszor van szükségünk, különösen akkor, ha sok adatot szeretnénk a számítógépben tárolni. Ha nem adjuk meg a szövegek hosszát, akkor a gép automatikusan 132 betűhelyet foglal le a memóriában. Ez óriási pazarlássá válik, ha esetleg csak 10-20 betűhelyre lenne szükségünk.
A neveknek például negyven betűhely bőven elegendő. Egy neveket tároló tömb lehet a következő:
STRING *40 NEVEK$(1 TO 10)
Töröljük ki a korábbi program elején álló sorokat, de hagyjuk meg a sorba rakó eljárást, és írjuk be a következő programot! (A könnyebb érthetőség kedvéért az eljárás szövegét is újra közöljük.)
1 PROGRAM "Nevek.bas"
5 STRING *40 NEVEK$(1 TO 10)
10 FOR I=1 TO 10
15 PRINT "Nev(";I;")=";
20 INPUT NEVEK$(I)
25 NEXT
30 FOR I=1 TO 9
35 FOR J=I+1 TO 10
40 LET X$=NEVEK$(I)
45 LET Y$=NEVEK$(J)
50 CALL SORBA(X$,Y$)
55 LET NEVEK$(I)=X$
60 LET NEVEK$(J)=Y$
65 NEXT
70 NEXT
75 FOR I=1 TO 10
80 PRINT "Az ";I;"-ik nev:";NEVEK$(I)
85 NEXT
90 DEF SORBA(REF A$,REF B$)
95 STRING C$
100 IF A$>B$ THEN
105 LET C$=A$
110 LET A$=B$
115 LET B$=C$
120 END IF
125 END DEF
Ez a program tíz nevet (szöveget) olvas be egymás után, majd sorba rendezi őket. A felhasznált utasítások közül a FOR ciklust a HETEDHÉT ENTERPRISE második hetének 2. napján, a tömböket pedig a harmadik hét 7. napján ismertük meg. A program a beolvasott neveket úgy rendezi sorba, hogy mindegyiket mindegyikkel összehasonlítja!
Külön fel kell hívnunk a figyelmet a 40-es, 45-ös, 55-ös és a 60-as sorra. Ezekben az éppen vizsgálandó tömbelemek tartalmát két segédváltozóba (X$ és Y$) töltjük át, azokban végezzük el az esetleg szükséges cserét, majd ismét visszatöltjük az eredményt a tömb elemeibe. Erre azért van szükség, mert tömbelemek nem lehetnek referencia paraméterek. Ha ezt nem vennénk figyelembe, akkor a gép hibát jelezne. A program logikája szempontjából azonban ennek nincs jelentősége, ez csupán egy olyan szabály, amelyre az ENTERPRISE használatakor figyelnünk kell.
A mai napon először néhány új beépített, elsősorban a matematikában használt függvényt fogunk megismerni. Akik pedig nem szeretnek számolni, azoknak megnyugtatásul elmondjuk, hogy másról is lesz szó.
Kezdjük rögtön a függvényeket a szögfüggvényekkel, azaz a szinusszal, koszinusszal, tangenssel. Ezeket a lehető legegyszerűbben nevüknek három betlis rövidítésével jelöljük: SIN, COS, TAN. Például a tíz fok szinuszát a következő utasítással írjuk ki:
PRINT SIN(10)
Álljunk csak meg egy pillanatra! Honnan tudja a gép, hogy mi fokokban adjuk meg a szöget? Nos, ahogy azt a HETEDHÉT ENTERPRISE harmadik hetének 5. napján már olvashattuk, ezt nekünk kell előre megadnunk az OPTION ANGLE DEGREES utasítással. Ne feledjük el ezt begépelni még mielőtt szögfüggvényeket használnánk!Szükségünk lehet a szögfüggvények ellentettjeire is, az úgynevezett arkusz függvényekre. Ezeket sorra ASIN-nek, ACOS-nak és ATN-nek kell írnunk. Próbáljuk ki! Az OPTION ANGLE DEGREES parancs után adjuk ki a
PRINT SIN (10)
utasítást. A gép 0.1736481777-et ír ki. Ha most kiíratjuk a 0.17 arkusz szinuszát (PRINT ASIN(0.1)), akkor 9.78-at kapunk, ami tényleg majdnem 10. Tehát a két függvény valóban egymás ellentettje.
A szögek nagyságát nemcsak fokokban, hanem radiánokban is megadhatjuk. A radián is szögmérték, mint a fok, csak éppen 180 fok az 3.14 radiánnak felel meg. Ez a 3.14 egy "bűvös" szám, nagyon sokszor lehet szükségünk rá. Éppen ezért ezt a számot a számítógépbe előre beépítették, méghozzá két tizedes jegynél sokkal nagyobb pontossággal. Ha használni akarjuk, elég csak leírnunk a nevét: PI. Ez ugyanis a pí. írassuk ki a pí értékét:
PRINT PI
3.141592654
Ha azonban valaki radiánokban szeretné megadni a szögeket, nem kell azokat átszámítani fokokra, elég ha megmondja a számítógépnek, hogy mostantól fogva a szögek mértéke a radián. Erre való az OPTION ANGLE RADIANS utasítás.
Előfordul, hogy fokokban számolunk, mégis érdekelne egy-egy szög mértéke radiánokban is. Nem kell a PI-vel bonyolultan számolgatnunk, a számítógépben előre készen van az átszámítást végző függvény, ennek neve RAD. Mivel 180 fok az egyenlő PI, azaz 3.14 radiánnal, ezért a RAD(180) pontosan 3.14. írassuk is ki! Az is érthető, hogy az
OPTION ANGLE DEGREES
PRINT SIN(10)
és az
OPTION ANGLE RADIANS
PRINT SIN(RAD(10))
megegyezik, mindkettő 0.1736.
A RAD függvény ellentettje, a DEG függvény, amely a radiánokban megadott szög értékét számítja ki fokokban.
Néha szükségünk lehet egy szám előjelére is. Ezt az SGN (az előjel angolul signum, kiejtve szignum) függvény számítja ki. Ha egy szám nagyobb, mint nulla, akkor az SGN függvény értéke 1, ha a szám pont nulla, akkor nulla, ha pedig kisebb, mint nulla, akkor -1 lesz. Például az SGN(-3)=-1.
További beépített függvény a négyzetgyökvonás, jele: SQR (az angol square ront, azaz négyzetgyök után, amit szkveer rútnak ejtünk). SQR(4)=2, ahogy azt vártuk is.
A négyzetgyökvonás ellentettje a négyzetreemelés, de ennek nincs külön jele. Nincs is rá szükség, hiszen ez nem más, mint a hatványozás egyik esete, a második hatvány kiszámítása. A hatványozásnak pedig van külön jele, a felfelé mutató kis nyilacska: ^. Például, ha a kettő második hatványára vagyunk kiváncsiak, azt így írhatjuk le: 2^2.
A hatványozást persze nemcsak négyzetre emelésre használhatjuk, hanem bármilyen más hatványt is számíthatunk hasonló módon. Például a kettő harmadik hatványa a nyolc. Ezt így íratjuk ki:
PRINT 2^3
8
Ha tudunk hatványozni, akkor tudunk gyököt vonni is. Méghozzá nemcsak négyzetgyököt, hanem bármelyik más gyökvonást is el tudjuk végezni. Ha például egy szám harmadik gyökét keressük, az nem más, mint annak a számnak az 1/3-dik hatványa. A nyolc harmadik gyökét tehát úgy kaphatjuk meg, hogy kiíratjuk a 8^(1/3)-at. írassuk ki az 1024 tizedik gyökét:
PRINT 1024^(1/10)
Most már tudjuk használni a szögfüggvényeket, meg tudjuk határozni a szögeket fokokban és radiánokban, tudunk hatványozni, gyököt vonni, és természetesen szorozni és osztani is. Álljon itt hát egy olyan program, amellyel számolhatunk, azaz számokat adunk meg és a felsorolt műveletek közül néhányat elvégzünk.
100 PROGRAM "Szamol.bas"
110 CLEAR SCREEN
120 OPTION ANGLE DEGREES
130 PRINT "Add meg a kezdeti szamot:"
140 INPUT SZAM
150 PRINT
160 DO
170 PRINT "SINUS / COSINUS / TANGENS / INT / +/-"
180 PRINT
190 DO
200 LET A$=INKEY$
210 LOOP UNTIL A$="s" OR A$="c" OR A$="t" OR A$="i" OR A$="+" OR A$="-"
220 SELECT A$
230 CASE "s"
240 PRINT "SINUSA"
250 LET SZAM=SIN(SZAM)
260 CASE "c"
270 PRINT "COSINUSA"
280 LET SZAM=COS(SZAM)
290 CASE "t"
300 PRINT "TANGENSE"
310 LET SZAM=TAN(SZAM)
320 CASE "i"
330 LET SZAM=INT(SZAM)
340 CASE "+","-"
350 IF A$="+" THEN
360 PRINT "MEG ";
370 ELSE
380 PRINT "MINUSZ ";
390 END IF
400 INPUT PROMPT "":SZAM2
410 IF A$="+" THEN
420 LET SZAM=SZAM+SZAM2
430 ELSE
440 LET SZAM=SZAM-SZAM2
450 END IF
460 END SELECT
470 PRINT " =";SZAM
480 LOOP
Amikor a programot elindítjuk, meg kell adnunk egy számot, amelyikkel kezdeni akarjuk a számolást. Ezután a program megkérdezi, hogy milyen műveletet akarunk elvégezni. (A műveleteket a nevük első betűjével rövidítettük.) Ha egy műveletnek két operandusa van - ilyen például az összeadás - akkor azt is beolvassa a program. Ezután elvégzi a műveletet és kiírja az eredményt. Az eredménnyel további műveleteket végezhetünk. Ezt a programot sokmindennel bővíthetjük is, nemcsak gyakorlásnak jó, hanem egy igen hasznos segédprogramot is nyerhetünk vele. Elkészíthetjük a saját külön zsebszámológépünket, pontosabban az annak megfelelő programot.
Használjuk most a ENTERPRISE egyik, már korábban megismert szolgáltatását: e könyv harmadik fejezetének 1. napján olvastuk, hogy ez a számítógép egyszerre több programot is tud tárolni. írjuk be a számológép programját az egyes program helyére. (Ide az EDIT 1 paranccsal tudunk átkapcsolni.) Ezután EDIT 0-val visszakapcsolva a nullás programra nyugodtan dolgozhatunk. Ha szükségünk lenne a számolóprogramra, azt bármikor elindíthatjuk a CHAIN 1 paranccsal. Ennék olcsóbb számológépet még senki se látott, arról nem is beszélve, hogy mi magunk dönthetjük el, mire van szükségünk, mire tanítjuk meg számológépünket.
Mire is tudjuk megtanítani? Nos, megpróbálhatjuk bővíteni a műveletek körét. A már meglevők mintájára beépíthetjük a szorzást, az osztást, az inverz szögfüggvényeket, konstansokat, mint például a PI-t. Nemcsak azokat a műveleteket használhatjuk, amelyeket ebben a fejezetben ismertünk meg, hanem korábbiakat is, ilyen lehet például az abszolút érték számítás. Újabb műveleteket is kitalálhatunk és létrehozhatunk, ilyen például a százalékszámítás.
Akinek van kedve, memóriát is létrehozhat, amellyel lehetővé teheti, hogy a számológéppel végzett műveletek során kapott eredmények bármelyikét "elmentse" és később újra felhasználhassa. Ha szükségünk van rá, használhatunk fokokat és radiánokat is a szögek mérésére. Az egészen ügyesek még a zárójelek kezelését is beprogramozhatják, bár ez elég ravasz feladat, nem olyan egyszerű, mint amilyennek első pillantásra látszik. Végül, a CHAIN utasítással megtaníthatjuk programunkat egy előre meghatározott, vagy éppen a program használata közben megadott számú másik programba való visszatérésre is.
A számítógép tehát igazán mindenttudó számológéppé válhat, most már csak rajtunk a sor, írjuk meg a programot!
3. nap - Kalandozás a csatornák útvesztőjében
Ha azt a szót halljuk, csatorna, eszünkbe juthat az öntözővizet szállító csatorna, vagy a hajózás megkönnyítésére épített csatorna, de előfordulhat az is, hogy a szennyvíz elvezetésére szolgáló csatornára gondolunk. Csatorna valóban sokféle van, egy dologban azonban mind megegyeznek, ez pedig a funkciójuk: minden csatorna valahonnan valahova valamit szállít. Van amelyiken vizet továbbítanak, van amelyiken hajókat. A számítógép csatornái pedig információt szállítanak.
Mi is az az információ? Nos, számunkra minden olyan adat, jel, hang, betű vagy szám, ami valamiről tudósít, valamilyen hírt, jelzést, netalán parancsot jelent az információ. A számítógép mindig ilyen információ sorozatokat dolgoz fel és állít elő.
A program a billentyűzetről érkező betűk sorozata, tehát információ. A képernyőre kiírt szöveg valójában betűk sorozata, a képernyő felé továbbított információ. Ha megszólal a hangszóró, akkor a számítógépnek sikerült eljuttatni a hangszórót kezelő egységhez azt a parancsot, hogy szólaljon meg. Ezek az ínformációk a számítógépben csatornákon keresztül terjednek. Ilyen csatornák kötik össze magát a számítógépet a billentyűzettel, a képernyővel, a hangszóróval, a magnetofonnal és a nyomtatával illetve mágneslemezzel is.
A csatornákat egymástál a számuk alapján tudjuk megkülönböztetni. Minden csatornának van egy száma, 0 és 255 között.
Ahhoz, hogy a csatornákon keresztül eljuthasson az információ a számítógép központi egységétől a kívánt egységekhez, meg kell adni, hogy melyik csatorna melyik egységhez kapcsolódjék, azaz az adott csatornán keresztül melyik egységről lehessen információt beolvasni, vagy az egységhez információt eljuttatni. így például a gépnek mindig tudni kell, hogy melyik csatornán keresztül tudja beolvasni a leütött billentyűket, vagy hogy melyik csatornán keresztül tud a képernyőre írni.
Ehhez hasonlóan, ha mi írunk egy programot, és az a program valamilyen információt olvas be vagy ír ki, akkor ki kell választanunk egy csatornát, amelyen keresztül az információt majd átvisszük. Ezt a csatornát kell hozzákapcsolni a kívánt eszközhöz és végül minden egyes utasításban, ahol az adott eszközre szeretnénk kiírni valamit, meg kell mondanunk, hogy melyik csatornán keresztül lehet ezt az eszközt elérni.
Ez így nagyon bonyolult, figyeljük meg egy példán! Ha egy hangot szeretnénk megszólaltatni, akkor ezt az információt el kell juttatnunk a hangszórót kezelő egységhez. Ehhez először egy csatornát kell kiválasztanunk, és ezt a csatornát hozzá kell kapcsolnunk a hangszóró egységéhez. Ettől kezdve amit erre a csatornára kiírunk, az a hangszóróban hallhatóvá válik, hiszen ez a kiválasztott csatorna minden információt elvisz a hangszóróhoz.
Ehhez hasonlóan, ha mi írunk egy programot, és az a program valamilyen információt olvas be vagy ír ki, akkor ki kell választanunk egy csatornát, amelyen keresztül az információt majd átvisszük. Ezt a csatornát kell hozzákapcsolni a kívánt eszközhöz és végül minden egyes utasításban, ahol az adott eszközre szeretnénk kiírni valamit, meg kell mondanunk, hogy melyik csatornán keresztül lehet ezt az eszközt elérni.
Ez így nagyon bonyolult, figyeljük meg egy példán! Ha egy hangot szeretnénk megszólaltatni, akkor ezt az információt el kell juttatnunk a hangszórót kezelő egységhez. Ehhez először egy csatornát kell kiválasztanunk, és ezt a csatornát hozzá kell kapcsolnunk a hangszóró egységéhez. Ettől kezdve amit erre a csatornára kiírunk, az a hangszóróban hallhatóvá válik, hiszen ez a kiválasztott csatorna minden információt elvisz a hangszóróhoz.
Mint arról már volt szó, a csatornák 0-tól 255-ig vannak megszámozva. Ezek közül a csatornák közül az 1-99 terjedőket a gép alapértelmezésben nem használja, ezeket nekünk hagyja szabadon. Egy ilyen a gép által nem használt csatornát az OPEN utasítással tudunk egy eszközhöz kapcsolni - a számítástechnikában használatos kifejezéssel megnyitni - és használat után a CLOSE utasítással zárhatjuk le. Az utasításokban a £ jel után kell megadnunk a csatorna számát, majd ezt követően az OPEN-nél a használni kívánt eszköz nevét. A használható eszközök neveit a Felhasználói kézikönyv 135-136-ik oldalán találhatjuk meg. Ezek a nevek mindig kettőspontra végződnek. Ilyen eszköznév a VIDEO:, a KEYBOARD:, vagy a SOUND:.
Ha egy csatornát már megnyitottunk valamelyik eszköz felé, akkor minden olyan utasításban, amelyikben használni akarjuk ezt az eszközt, meg kell adnunk a csatorna számát. Nézzünk erre egy példát! Ha a hangszóró egységet a 3-as csatornán akarjuk elérni, akkor- egy hangot a következő utasítással állíthatunk elő:
SOUND £3:
Igen ám, de ha kiadjuk ezt a parancsot, akkor a gép hibát jelez:
***Channel not open
azaz a csatorna nincs megnyitva, nem használható. Valóban, elfelejtettük megnyitni a csatornát. Nyissuk most meg:
OPEN £3:"SOUND:"
Erre megint hibajelzést kapunk:
***Channel already open
Az eszközt már egy másik csatorna használja. No igen, hiszen volt róla szó, hogy a gép automatikusan minden eszközt hozzá kapcsol egy-egy csatornához. A felhasználói leírásban a 134.-135. oldalakon olvashatjuk ezek listáját, ebből megtudjuk, hogy a hanggenerátor a 103-as csatornához csatlakozik. Először tehát le kell zárnunk azt a csatornát:
CLOSE £103:
ok
Ezután jöhet az új csatorna megnyitása:
OPEN £3:"SOUND:"
ok
Végül kipróbálhatjuk az új csatornát:
SOUND £3:
ok
Ettől kezdve minden SOUND utasításban meg kell adnunk, hogy a hármas csatornát használja, különben a gép hibát jelez. Az alapértelmezés szerint ugyanis a 103-as csatornán keresztül érhető el a hanggenerátor, ha tehát nem adunk meg csatornaszámot, akkor a gép azzal a csatornával kísérletezik és hibát jelez:
SOUND
***Channel not open
Az eredeti állapot visszaállításához vagy a gépet kell újraindítanunk (nem kell kihúznunk, elég a hátoldalán jobbkézfelöl levő piros RESET gombot megnyomnunk), vagy nekünk kell utasításokkal visszaállítani az eredeti állapotot:
CLOSE £3:
OPEN £103:"SOUND:"
Valójában ilyen külön csatornák megnyitására nagyon ritkán van csak szükségünk. A gép által automatikusan kijelölt és megnyitott csatornákat nyugodtan használhatjuk. Az INPUT, a PRINT és a GET utasításokban szinte soha sem kell megadnunk a csatornaszámot.
Kivételek természetesen itt is akadnak. Vegyük csak elő a HETEDHÉT ENTERPRISE harmadik hetének 1, és 3. napját. Ott ugyan nem beszéltünk csatornákról, de használtuk a 101-es és a 102-es csatorna számát. A 101-es csatorna a szabványos grafikai laphoz van rendelve, amit a GRAPHICS utasítással nyitunk meg, a 102-es csatorna pedig a szöveglaphoz. Az egyes utasítások alapértelmezésben az egyik vagy a másik lapra vonatkoznak, de ha akarjuk, természetesen a másik lap csatornaszámát megadva fel is cserélhetjük funkciójukat. Ezt tettük, amikor a grafikai lapra írtunk, vagy amikor a szöveglap színét megváltoztattuk. Természetesen a szöveges lapra nem tudunk rajzolni, hiszen akkor nem is lenne különbség a szöveges és a grafikai lap között.
A csatornaszámok azonban nemcsak a PRINT utasításnál lehetnek hasznosak. A GET utasítás alapértelmezésben a 105-ös csatornáról, tehát a billentyűzetről (KEYBOARD:) olvas. Ha azonban akarjuk, a szöveglapról is tudunk olvasni. Nézzünk egy példaprogramot:
10 CLEAR SCREEN
20 PRINT AT 10,20:"Lilike";
30 PRINT £102,AT 10,23:;
40 GET £102:A$
50 PRINT "A BEOLVASOTT BETU:";A$
Futtassuk le a programot! A képernyőn a következő jelenik meg:
LilA BEOLVASOTT BETU:i
ok
Nézzük végig a program sorait! Az első sor törli a képernyőt. A második sor a szöveges lap 10-ik sorának 20-ik oszlopába kiírja a Lilike nevet, mint azt már tudjuk a 102-es csatornán keresztül. A harmadik sor a 102-es csatornán a kurzort a 10-ik sor 2-ik oszlopára állítja. A legfontosabb a negyedik sor, amelyik a 102-es csatornáról olvas egy betűt, mivel pedig ez a csatorna a szöveglaphoz van rendelve, ezért onnan olvas, ahol éppen a kurzor áll. Azaz beolvassa az i betűt. A GET hatására a kurzor nem lép tovább, tehát továbbra is a 10-ik sor 23-ik oszlopán áll. Az ötödik utasításban levő PRINT tehát ide írja ki az "A BEOLVASOTT BETU:" szöveget, és utána a beolvasott i betűt. Ezzel a módszerrel visszaolvashatjuk, ellenőrizhetjük, hogy mit írtunk ki korábban a képernyőre.
A csatornákkal ritkán kell foglalkoznunk, a számítógép általában leveszi vállunkról ezt a terhet. Mégis érdemes volt egy kis időt szánnunk erre is, mert így jobban megérthettük gépünk működését, segítséget kaphattunk néhány ötletes trükkhöz. Kísérletezzünk velük! Egy kis szorgalommal még sok érdekességet fedezhetünk fel.
Amióta az ENTERPRISE-al ismerkedünk, egyre bonyolultabb feladatok újabb és újabb megoldásaival találkoztunk. Megtudtuk hogyan lehet ezeket a feladatokat a lehető legegyszerűbben, leggyorsabban, a legkevesebb munkával elvégezni. A programok írását is meg lehet gyorsítani, egyszerűbbé lehet tenni. Ismerkedjünk meg egy olyan trükkel, amelyik ezt teszi lehetővé.
Az elmúlt hetekben egyre-másra írtuk a különféle eljárásokat. Minden eljárás elején egy DEF sor, a végén pedig egy END DEF sor állt. Az eljárás nevében egy értéket tudunk visszaadni, ezáltal új függvényeket is létrehozhatunk. Függvényeink jelentős része azonban semmilyen más tevékenységet nem csinál, mint egy előre ismert képletbe behelyettesíti a kapott paramétereket és a kifejezés értékét tölti az eljárás nevébe. Ilyen például az átlagot számító függvény, a három szám közül a legnagyobbat kiválasztó függvény és a névkezdőbetűket kiválasztó függvény. Most ezeket fogjuk sorra venni.
Két szám átlagát a legegyszerűbb dolog kiszámítani. Nem kell mást tenni, mint a két számot összeadni és az eredményt elosztani kettővel. Ha a két számot A-val és B-vel jelölöm, akkor az átlaguk képlete a következő:
Átlag = (A + B) / 2
Az ezt kiszámító eljárás a következő:
DEF ATLAG(X,Y)
LET ATLAG=(X+Y)/2
END DEF
Az első sor tartalmazza az eljárás nevét és paramétereit, a második sor a paraméterekkel végzendő műveleteket és végül harmadik sor egyszerűen csak az eljárás végét jelzi. De hát mi szükség van erre a bonyolult megoldásra? Nem lenne egyszerűbb egyetlen sorban felírni, hogy mit mivel kell összeadni, mivel elosztani és az eredményt hova kell tölteni?
Az ENTERPRISE erre is módot ad. Az olyan eljárásokat, amelyek csak egyetlen képlet behelyettesítését végzik el, tehát egyetlen sorrá alakíthatók, lehetőségünk van az értékadáshoz hasonló formában felírni. Mivel azonban ez nem értékadás, hanem egy eljárás meghatározása, ezért az elején nem a LET, hanem a DEF kulcsszót kell használnunk. Természetesen az eljárás neve mögött a szokott módon kell megadni a paramétereket. Nézzük meg az előző eljárást az új formában:
DEF ATLAG(X,Y)=(X+Y)/2
Mennyivel egyszerűbb, áttekinthetőbb ez a forma! Következzék most egy rövid program, amely ezzel az eljárással számol:
10 DEF ATLAG(X,Y)=(X+Y)/2
20 DO
30 INPUT X,Y
40 PRINT ATLAG(X,Y)
50 LOOP
Próbáljuk ki!
Az ENTERPRISE rendelkezésünkre bocsát egy olyan függvényt, amivel két szám közül kiválaszthatjuk a nagyobbikat. Ez a maximumfüggvény, amelynek a neve MAX. Igen ám, de mi van akkor, ha három szám közül kell a legnagyobbat kiválasztani? Ekkor bizony új eljárást kell írnunk.
Az új eljárás lényegében két lépcsőben működik. Az első fokozatban az első és a második, illetve az első és a harmadik szám közül választja ki a nagyobbikat. Ha egyik összehasonlítás eredményeként sem az első szám a nagyobb, akkor még egy vizsgálatra van szükségünk, mégpedig a két első összehasonlítás eredményét kell összevetnünk. A második fokozatot akkor is érdemes elvégeznünk, ha már az első vizsgálat alapján eldönthettük volna, hogy melyik a három szám közül a legnagyobb, mert a helyes eredményt ez nem változtatja meg. A képlet tehát a következő:
MAX( A,B,C )=MAX(MAX(A,B),MAX (A,C))
Az eljárás és az azt használó kis program pedig így néz ki
10 DEF MAX3(A,B,C)= MAX(MAX(A,B),MAX(A,C))
20 DO
30 INPUT A,B,C
40 PRINT MAX3(A,B,C)
50 LOOP
A megoldás rendkívül jól áttekinthető. Valószínű, hogy az esetek többségében a harmadik - tehát a legkülső - összehasonlítást feleslegesen végzi el a gép, de az ilyen esetek kiszűrése és külön kezelése sokkal több időt és helyet igényel, mint ez az egy felesleges művelet.
Ha megértettük a MAX függvény használatát, akkor próbáljuk meg elkészíteni a négy szám maximumát kiszámító eljárást is. A megoldás a fentiekhez nagyon hasonló. Ugyanígy a három illetve a négy szám átlagát kiszámító függvényeket is elkészíthetjük. Ehhez szükségünk van a két szám átlagát kiszámító függvényre?
Végül nézzünk meg még egy eljárást. A következő példa egy két tagból álló név kezdőbetűit állítja elő. Ha a név Kovács István, akkor a függvény értéke KI lesz.
A megoldás logikája igen egyszerű. Először kiválasztjuk a név legelső betűjét a NEV$(1:1) kifejezéssel. A név második tagját onnan ismerjük fel, hogy egy szóköz áll előtte. A szóközt a POS előre definiált függvénnyel keressük meg: POS(NEV$," "). Ez után áll a név második tagjának első betűje, amelynek pozíciója tehát POS(NEV$," ")+1. Ezt a betűt a
NEV$(POS(NEV$," ") +1:POS(NEV$," ")+1)
kifejezéssel lehet kijelölni. Végül ezt és a legelső betűt össze kell konkatenálni, így jön létre a teljes monogram. A program a következő:
10 DEF INIC$(NEV$)=NEV$(1:1)&NEV$(POS(NEV$," ")+1:POS(NEV$," ")+1)
20 DO
30 INPUT NEV$
40 PRINT INIC$(NEV$)
50 LOOP
Itt láthatjuk ezeknek az eljárásoknak a legfőbb hátrányát. Bizony, a kicsit is bonyolultabb képleteknél már áttekinthetetlenné válik az eljárás, arról nem is beszélve, hogy a POS függvény értékét teljesen feleslegesen számítjuk ki kétszer, hiszen mindkét alkalommal ugyanazokkal a paraméterekkel hívjuk meg. Ez az a pont, ahol célszerűbb a korábban ismert eljárásformára visszatérni és belső segédváltozókat használni:
DEF INIC$(NEV$)
NUMERIC POZICIO
LET POZICIO=POS(NEV$," ")+1
INIC$=NEV$(1:1)&NEV$(POZICIO:POZICIO)
END DEF
A képlet jellegű eljárásokban nem tudunk belső változókat használni. További fontos tulajdonsága az ilyen függvényeknek, hogy mivel ezen eljárásokon belül nem tudunk belső értékadásokat megadni, ezért referencia paramétereket sem használhatunk, hiszen azokat nem tudnánk módosítani.
Ma az eljárások új formájával ismerkedtük meg, amely alkalmas az egyszerű, rövid képletek áttekinthető, gyors felírására.
+1. nap - Ami mindenhonnan kimaradt
Ezen a napon röviden ismertetjük azokat az utasításokat, amelyeket a gép ugyan ismer és más BASIC-ekben elterjedt a használatuk, de az ENTERPRISE-on szerepüket más, kényelmesebb vagy célszerűbb megoldások töltik be.
Bizony nem is egy olyan BASIC utasítás van, amit egy COMMODORE 64-esen vagy egy ZX SPECTRUM-on lépten- nyomon használnunk kell, nélkülözhetetlenek. Az ENTERPRISE szerencsére olyan sok kényelmes, egyszerű formát kínál, hogy hiányukat észre se vettük. Most mégis essék néhány szó ezekről, hogy ha találkozunk ilyen utasításokkal, ne álljunk értetlenül az ismeretlen szavak előtt.
Elsőként nézzük a GOTO utasítást. Ez egy ugró utasítás, amelynek egy paramétere van. Az ilyen ugrásnak azonban nincs semmilyen feltétele, ezt tehát mindig végrehajtja a gép, ha ehhez az utasításhoz ér a program. Az ugrás célját egy sorszámmal kell megadni, méghozzá annak a programsornak a számával, ahova ugorni fog. Mivel a GOTO-nak feltétele nincs, feltételessé csak egy IF ág belsejében tehetjük.
Vannak olyan gépek, amelyeken nem is lehet IF és ELSE után utasításokat beírni, nem ismerik az END IF lezárást, hanem mindig az IF utáni THEN-et követő egyetlen utasítás tartozik az IF-hez. Ilyen gépeken gyakori az "IF feltétel THEN GOTO sorszám" szerkezet, ahol ha a feltétel, igaz, akkor a gép végrehajtja, ha pedig nem igaz, akkor nem hajtja végre az ugrást. Nézzünk egy egyszerű mintát:
10 GET A$
20 IF A$<>" " THEN GOTO 10
30 PRINT "EZ SZOKOZ"
40 GOTO 10
Ugyanez a program az ENTERPRISE-on a következő:
10 DO
20 GET A$
30 IF A$=" " THEN PRINT "EZ SZOKOZ"
40 LOOP
Ugye mennyivel érthetőbb?
Az ENTERPRISE eljárásainak is van megfelelője a legtöbb BASIC-ben, de ezek a megoldások sokkal kevesebbet tudnak. A legleterjedtebb a GOSUB utasítás, ami a GOTO-hoz hasonlóan egy sorszámra mutat. A GOSUB utasításra a gép a program megadott sorára ugrik, de megjegyzi, hogy honnan jött, és ha ezután egy RETURN utasítást talál, akkor oda tér vissza. A RETURN tehát az ilyen eljárások végét jelzi. Nézzünk erre is egy példát! A két számot megcserélő eljárás a következő:
10 LET SEGED=EGYIK
20 LET EGYIK=MASIK
30 LET MASIK=SEGED
40 RETURN
...
100 GOSUB 10
...
Az ennek megfelelő ENTERPRISE eljárás így néz ki:
10 DEF CSERE(REF A,REF B)
20 NUMERIC SEGED
30 LET SEGED=A
40 LET A=B
50 LET B=SEGED
60 END DEF
...
100 CALL CSERE (EGYIK,MASIK)
...
Látható, hogy a GOSUB-os szerkezet nem tud sem belső változókat kezelni (a SEGED ott külsőnek számít!), sem paramétereket használni. A paraméterek hiánya azt jelenti, hogy valahányszor meg akarjuk hívni az eljárást, a GOSUB-os megoldásnál mindig be kell előre töltenünk a két felcserélendő számot az EGYIK és a MASIK változóba. Ezt a töltögetést automatikusan maga az ENTERPRISE végzi el, amikor a paraméterváltozókba tölti a paraméterek értékét.
Mivel ezekben az egyszerűbb BASIC-ekben nincsenek belső és külső változók, hanem minden változó külső, ezért nincs szükség a NUMERIC és a STRING utasításokra sem, s így nincs lehetőség a szövegváltozók maximális hosszának megadására sem. Tömböket a DIM utasítással hozhatunk létre, de a tömbök indexelése mindig nullánál indul, csak a felső határt változtathatjuk. Lássuk a példát:
DIM TOMB(20)
A TOMB tömb 21 darab számváltozóból áll (mivel a neve mögött nincs dollárjel). A legelső indexe nulla, a legutolsóé 20. Ugyanez az ENTERPRISE-on a következő lenne:
NUMERIC TOMB(0 TO 20)
Természetesen ebben az utóbbi esetben arra is van mód, hogy az alsó tömbhatárt ne nullának jelöljük ki. Ez a DIM utasításnál nem lehetséges.
Végül szinte mindenütt a START utasítás helyett a RUN kulcsszót használják, ami futást jelent. A RUN az ENTERPRISE-on is használható, de ezzel az utasítással nem tudunk paramétereket megadni a programnak. A legtöbb számítógépen semmilyen mód sincs arra, hogy indításkor paramétereket adjunk át a programnak.
Ezzel végére is értünk a felsorolásnak, amelyben más számítógépek gyakran használt nyelvi elemeit ismertettük. Ezeket az utasításokat lehetséges, de nem célszerű az ENTERPRISE-on is alkalmazni, mert vannak náluk jobbak, egyszerűbbek és kényelmesebbek is.
Az ENTERPRISE egyik legnagyobb előnye az, hogy különféle eljárásokat hozhatunk létre, ezeknek az eljárásoknak paramétereket adhatunk át, s azok a nevükön keresztül kényelmesen adhatják vissza a kiszámított eredményt. E könyvnek körülbelül negyede foglalkozik ezzel a témakörrel.
Az eljárások jelentősége valójában akkor derül ki, ha valamilyen nagyobb feladat megoldására vállalkozunk. A nagyobb programokat már nem készíthetjük el egyetlen ötlet alapján, rögtön a gépbe beírva a programot. A feladatot fel kell bontanunk részfeladatokra, kisebb problémákra, amelyeket egyenként és külön-külön oldhatunk meg. Minden részprobléma megoldása egy-egy eljárást jelent. Az ilyen eljárásokat egyenként hozzuk létre és csak a legvégén rakjuk össze a teljes programot.
A feladat megoldását mindig az eredeti probléma részfeladatokra bontásával kezdjük. Ha sikerül úgy elvégezni ezt a munkát, hogy az egyes részek jól érthetőek, megoldhatóak lesznek, akkor a teljes program is hamarább készül el és kevesebb lesz benne a hiba. Az egyes feladatokat mindaddig egyre kisebb részekre kell bontanunk, amíg végül áttekinthető feladathoz nem jutunk. Ne felejtsük el, hogy a számítógép képernyőjén egyszerre legfeljebb huszonegynéhány sort láthatunk, az is fontos, hogy az egyes eljárások lehetőleg még olvasható méretűek legyenek.
Végül soha ne feledjük el, hogy a számítógépet nem a lusta agyú emberek kedvéért alkották meg. Gondolkozzunk! A feladat megoldását mindig nekünk kell megtalálni. Jó fejtörést!
1. példaprogram - Kanyargó |
Ez a program egy egyszerű szimulációs játék, amellyel egy képzeletbeli gépkocsit irányíthatunk. A gépkocsi kanyargós úton halad, a mi feladatunk úgy kormányozni, hogy ne térjen le az útról. A gépkocsit a beépített botkormány jobbra vagy balra döntésével kormányozhatjuk, előre vagy hátra húzva pedig gyorsíthatjuk és lassíthatjuk. Ha egy hosszabb szakaszon hiba nélkül haladtunk végig, akkor a program egy másik, keskenyebb útra irányítja kocsinkat.
Gépeljük be a teljes programot! Mielőtt megvizsgálnák az egyes részletek működését játsszunk néhány fordulót!
A program szövegében az egyes részeket megjegyzés sorokkal (REM) választottuk el egymástól. A legelső ilyen szakasz tartalmazza a program nevét és a külső változók listáját.
100 PROGRAM "Kanyargo.bas"
110 NUMERIC KAPUX
120 NUMERIC KOCSIX
130 NUMERIC SZINT
140 NUMERIC SZEL
150 NUMERIC VEGE
160 STRING KAPU$
A gépkocsi helyzetét a KOCSIX változóban fogjuk nyilvántartani, azaz mindig ide írjuk be, hogy a kocsit szimbolizáló "^" jel a képernyő hányadik oszlopában helyezkedik el. A játék során minden lépésben egy sorral lejjebb toljuk a képernyő tartalmát, ezt a játékos úgy látja, mintha az út haladna hátrafelé. De mivel a KOCSIX változó alapján újra és újra kirajzoljuk a képernyőre a gépkocsit, így az látszólag előre halad az úton.
Az út vonalát úgy hozzuk létre, hogy a képernyő lefelé léptetésénél keletkező legfelső üres sorba mindig odarajzoljuk az út szélét jelző köveket, majd azokat a képernyővel együtt lefelé léptetgetjük. Az út két oldalát kijelölő kövek közötti részt kapunak hívjuk, a gépkocsi ezeken a kapukon belül kell, hogy végighaladjon. A legfelső sorba kerülő új kapu baloldalának helyzetét (oszlopszámát) a KAPUX változóban, a kapu, vagyis az út szélességét a SZEL változóban fogjuk tárolni. A kapu képét, tehát a két-két útszéli követ és közöttük a SZEL tartalmának megfelelő helyet a KAPU$ szövegváltozó tartalmazza.
A kocsit szimbolizáló ^ jelet, a gépkocsi sebességétől függően, mindig más és más sorba rajzoljuk ki. Ha gyorsabban halad a kocsi, akkor feljebb jelenik meg, tehát kevesebb időnk marad az út kanyarodását követni. Azt, hogy hányadik szintre, azaz hányadik sorba kerül a jel, a SZINT változó tartalmazza.
Végül szükség van a VEGE változóra is, amelyben a megfelelő eljárás jelzi, hogy letértünk az útról, árokba sodródott a kocsi, ezért vége az utazásnak.
A főprogram a 1110-es sornál kezdődik, de mi nem itt fogunk hozzá az ismerkedéshez, hanem az egyik eljárásnál. Ez a FOCIM eljárás:
180 DEF FOCIM
190 TEXT 40
200 PRINT £102,AT 7,18:"KANYARGO"
210 PRINT £102,AT 10,14:"Ha kezdhetjuk,"
220 PRINT £102,AT 12,10:"nyomj le egy billentyut!"
230 DO
240 GET A$
250 LOOP UNTIL A$<>""
260 END DEF
Az eljárás egyetlen egyszer fut le, a program legelején. Törli a képernyőt és üdvözli a játékost. Megvárja, hogy az felkészüljön a játékra, és csak akkor megy tovább, ha akármelyik billentyű lenyomásával jelezzük, kész vagyunk a játékra.
A képernyő kiinduló állapotát a KEPKEZD eljárás hozza létre, ugyancsak ez az eljárás tölti be a változók kezdeti értékét:
280 DEF KEPKEZD
290 NUMERIC I
300 SET STATUS OFF
310 SET KEY CLICK OFF
320 SET £102:COLOR 0,BLUE
330 SET £102:COLOR 1,WHITE
340 SET BORDER BLUE
350 SET £102:PAPER 0
360 CLEAR SCREEN
370 PRINT £102,AT 2,1:"*************************************"
380 PRINT £102,AT 24,1:"*************************************"
390 LET KAPU$="ÄÄ"&" "(1:SZEL)&"ÄÄ" !ALT+M
400 LET VEGE=0
410 LET KAPUX=INT(RND(15))+5
420 LET KOCSIX=KAPUX+2
430 LET SZINT=18
440 FOR I=3 TO 17
450 PRINT £102,AT I,KAPUX:KAPU$;
460 NEXT
470 END DEF
Az eljárás törli a státusz sort és kikapcsolja a billentyűk hangját. Beállítja a keret és a képernyő színeit, és alulra meg fölülre egy-egy sor csillagot ír ki, ezzel jelzi, hol van a pálya vége. Figyeljük meg, hogy a 102-es csatornán keresztül ír a képernyőre, tehát a szabványos szöveglapot használja!
Ezután a változók kezdeti értékét tölti be. Ez az eljárás nem paraméterként kapja meg a beállítandó változókat, hanem külső változóként kezeli azokat. A KAPU$-ba beírja a megfelelő szélességű kapumintát (390-es sor). Gondoljuk végig, hogy a SZEL változó tartalmától függően hány szóköz kerül a KAPU$-ba két széle közé!
Nullázza a VEGE változót, majd véletlenszerűen kijelöli a kezdő kapu helyét (KAPUX - 410-es sor), és ennek megfelelően a kocsit is (420-as sor). Emlékezzünk arra, hogy az INT(RND(15)) egy 0 és 14 közötti véletlen egész számot ad vissza!
A gépkocsi kiinduló szintjét is meghatározza, ez mindig 18, majd kirajzolja az út első tizenöt kapuját, tehát az út elején levő egyenes szakaszt (440-460-as sorok). Ehhez használhatja a KAPUX és a KAPU$ változókat, mivel ekkor már azok be vannak töltve.
A játék folyamán a következő kapu helyét mindig a KOVKAPU eljárás jelöli ki:
490 DEF KOVKAPU(REF POS,SZOV$)
500 SET £102:SCROLL DOWN 35,55
510 SELECT CASE RND
520 CASE IS<.35
530 IF POS>1 THEN LET POS=POS-1
540 CASE IS<.75
550 IF POS<30 THEN LET POS=POS+1
560 CASE ELSE
570 END SELECT
580 SET £102:PAPER 0
590 PRINT £102,AT 3,POS:SZOV$;
600 END DEF
Ennek két paramétere van. Az egyik a kapu pozíciója, amit módosít is, tehát ennek referencia paraméternek kell lennie. A másik a kapu képét tartalmazó szöveg. Az eljárás először a képernyőt lépteti egy sorral lejjebb, ehhez a SET SCROLL DOWN utasítást használja, amit eddig ugyan nem említettünk, de leírását megtalálhatjuk a Felhasználói leírásban. Ezután a véletlentől függően vagy eggyel balra lépteti a legfelső kaput (POS=POS-1), vagy eggyel jobbra, vagy pedig helyben hagyja. Végül az új pozícióba ki is írja a kaput a 590-es sorban.
A gépkocsi következő pozícióját, a következő kapu helyét kijelölő KOVKAPU eljáráshoz hasonlóan, a KOVPOS eljárás állítja be:
620 DEF KOVPOS(REF OSZLOP,REF SOR)
630 SELECT CASE JOY(0)
640 CASE 2,6,10
650 LET OSZLOP=OSZLOP-1
660 CASE 1,5,9
670 LET OSZLOP=OSZLOP+1
680 CASE 8
690 IF SOR>4 THEN LET SOR=SOR-1
700 CASE 4
710 IF SOR<19 THEN
720 LET SOR=SOR+1
730 PRINT £102,AT SOR,OSZLOP:" ";
740 END IF
750 CASE ELSE
760 END SELECT
770 PRINT £102,AT SOR,OSZLOP:;
780 END DEF
Ez az eljárás nem véletlenszerűen, hanem a JOY függvény segítségével, a botkormánytól függően, módosítja a referencia paraméterként megkapott sor-, illetve oszlopszámot. Gondoljuk végig, hogy a botkormány milyen irányú helyzeteiben fogja a kocsit balra léptetni (OSZLOP=OSZLOP-1), jobbra léptetni (OSZLOP=OSZLOP+1), mikor fog gyorsítani (SOR=SOR-1) vagy lassítani (SOR=SOR+1). Ez utóbbi esetben, tehát amikor eggyel lejjebb lép a gépkocsi a képernyőn, egyúttal annak helyét is törölnie kell.
Erre azért van szükség, mert a KOVPOS eljárás maga - a KOVKAPU-tól eltérően - nem írja ki a gépkocsi jelét az új helyre, csak oda viszi a kurzort (770-as sor). A jel kirajzolása előtt még a VIZS eljárás következik, amelyik megvizsgálja, hogy a kocsi új pozíciójában nincs-e valami akadály:
800 DEF VIZS(REF KESZ)
810 GET £102:A$
820 IF A$<>" " THEN LET KESZ=1
830 END DEF
A VIZS eljárás a KESZ paraméterében visszajelzi, ha a kocsi az utat határoló falnak ütközött. Ezt ügy veszi észre, hogy a 102-es csatornáról beolvassa a kurzor pillanatnyi pozíciójában levő karaktert, és ha az nem szóköz, tehát már van ott valami, ahova a kocsival lépni akarunk, akkor ezt jelzi.
A KOVPOS eljárás 730-as sorában azért kellett a kocsi új pozíciójába egy szóközt kiírnunk, mert lassításnál, tehát amikor lefelé lépünk a képernyőn, nem tudhatjuk, nincs-e ott egy - a kocsi valamely korábbi pozícióját jelölő - "^" jel.
Miután a VIZS eljárás beállította a paraméterét, a LEPES eljárás következik, amelyik a gépkocsit írja ki a képernyőre:
850 DEF LEPES(HANGM)
860 SOUND PITCH 50-2*HANGM,DURATION 1
870 PRINT £102:"^"
880 END DEF
Maga az írás az 870-es sorban történik, a jel a kurzor - már korábban beállított - pozíciójába kerül. Az eljárás paraméterétől egy hangot is megszólaltat. Ha ez a paraméter a kocsi sebessége, akkor azzal arányos lesz a hang magassága. Végül szólunk még két eljárásról, amelyek egy-egy sikeresen vagy sikertelenül megtett útszakasz végén értesítik a játékost az eredményről:
1010 DEF NEVET
1020 SET BORDER GREEN
1030 PRINT £102,AT 10,10:"HURRA SIKERULT!"
1040 SOUND PITCH 37,DURATION 10
1050 SOUND PITCH 40,DURATION 10
1060 SOUND PITCH 44,DURATION 10
1070 SOUND PITCH 49,DURATION 10
1080 WAIT 2
1090 END DEF900 DEF SIR(REF TAV)
910 SET BORDER RED
920 LET TAV=TAV+2
930 PRINT £102,AT 10,10:"EZ NEM SIKERULT!"
940 SOUND PITCH 49,DURATION 10
950 SOUND PITCH 44,DURATION 10
960 SOUND PITCH 40,DURATION 10
970 SOUND PITCH 37,DURATION 10
980 WAIT 2
990 END DEF
A SIR eljárásnak egyik jellegzetessége, hogy paraméterként adjuk meg neki a kapu szélességét tartalmazó változót (SZEL), azt megnöveli, s így a minden forduló után automatikusan csökkenő útszélességet a korábbi szintre állíja vissza. így az út szélessége csak akkor csökken, ha sikeresen teljesítettünk egy útszakaszt.
A főprogram, ahogy azt már említettük, a 1110-es sornál kezdődik:
1110 CALL FOCIM
1120 RANDOMIZE
1130 FOR SZEL=5 TO 3 STEP-1
1140 CALL KEPKEZD
1150 FOR LEPSZAM=1 TO 100
1160 CALL KOVKAPU(KAPUX,KAPU$)
1170 CALL KOVPOS(KOCSIX,SZINT)
1180 CALL VIZS(VEGE)
1190 CALL LEPES(SZINT)
1200 IF VEGE THEN EXIT FOR
1210 NEXT
1220 IF VEGE=1 THEN
1230 CALL SIR(SZEL)
1240 ELSE
1250 CALL NEVET
1260 END IF
1270 NEXT SZEL
A program magja egy ciklus, amelyben az út szélessége (SZEL) 5-ről csökken 3-ig. A különböző szélességű utakon mind a három esetben (5, 4, 3) száz-száz lépést kell megtenni. A lépésszámot egy beágyazott ciklus (FOR LEPESSZAM=1 TO 100) figyeli. Az egyes lépések négy fázisból tevődnek össze:
- A következő kapu kiírása (KOVKAPU)
- A következő gépkocsi-pozíció kijelölése (KOVPOS)
- A pozíció megvizsgálása, hogy üres-e (VIZS)
És végül az új jel kiírása (LEPES)
Aki kíváncsi arra, hány lépést kell még megtennie az úton, az a következő sort iktassa a programba:
1155 PRINT £102:AT 1,18:LEPSZAM
Ennek hatására a program kicsit lassabb lesz, tehát könnyebb végighaladni a pályán, viszont játék közben a képernyő tetején mindig le lehet olvasni, hány lépést tettünk már meg az úton.
Ha a VIZS eljárás hibát észlel, akkor ezt a VEGE változóban adja tudtul. Ilyenkor a beagyazott FOR ciklus megszakad. Ha ilyen okból léptünk ki a ciklusból, tehát hiba történt, akkor a SIR eljárás kapja a vezérlést, ha nem, akkor a NEVET.
Végül, ha a külső ciklus ér véget, ez azt jelenti, hogy a játékos mind a három pályát teljesítette. Ilyenkor a ciklust követő programsorok futnak le, amelyek a játékost ünneplik:
1290 CLEAR SCREEN
1300 SET BORDER BLUE
1310 PRINT £102,AT 8,1:;
1320 FOR J=1 TO 6
1330 FOR I=1 TO 4
1340 READ HANG,HOSSZ
1350 SOUND PITCH HANG,DURATION HOSSZ
1360 NEXT
1370 PRINT £102:" BRAVO BRAVO BRAVO BRAVO BRAVO"
1380 RESTORE
1390 NEXT
1400 SOUND PITCH 37,DURATION 40
1410 WAIT 5
1420 PRINT AT 24,1:;
1430 DATA 37,5,41,5,44,5,49,5
Figyeljük meg, hogy az 1420-as sorban nem hivatkozunk a 102-es csatornára. Ennek egészen különleges hatása lesz, amelyet csak azok láthatnak, akik mind a három pályát hibátlanul teljesítik. Jó kocsikázást !
2. példaprogram - Hamika |
A HAMIKA játék sok szempontból hasonlít az előző - KANYARGO nevű - programunkra. Itt azonban nem egy autót, hanem egy kukacot kell irányítanunk a botkormánnyal. A kukac segítségével el kell tüntetnünk a képernyőn feltűnő csillagokat. Ha ez sikerül, akkor a képernyő peremén levő falon egy kapu nyílik, s nekünk ezen a kapun kell kivezetnünk a kukacot a képernyőről. Ez a kapu a korábbihoz képest nagyon szűk, mindössze egyetlen karakter széles. Ha a kukaccal nekimegyünk a falnak, vagy a kukac másik felének, akkor újra kell kezdenünk a pályát. Feladatunkat az is nehezíti, hogy meghatározott időn belül kell teljesítenünk a feladatot, különben a képernyőn újabb csillagok jelennek meg. A képernyő legfelső részén mindig leolvashatjuk, hogy hány lépésünk van még hátra.
Legelőször most is azt javasoljuk, hogy gépeljük be az egész programot és játsszunk vele egy kicsit!
A program szerkezete nagyon hasonlít a KANYARGÓ-óhoz. Itt is a külső változók állnak az elején, azt követik az eljárások, majd a 2390-es sortól a főprogram, s végül 2680-tól a győzelmet ünneplő utasítások.
Ezért vannak olyan eljárások, amelyekről nincs is értelme bővebben szólni, mert szinte prontosan ugyanazt végzik, mint egy-egy társuk a KANYARGO-ban.
Ilyen a FOCIM., ami a játékost üdvözli. A KERET a képernyőt hozza a kívánt alapállapotba, és beállítja a színeket is. A FALAK a keret belsejében levő falakat rajzolja fel, amelyek a feladat megoldásit nehezítik, attól függően, hogy hányadik fordulóban vagyunk, amit a SZINT változó tartalmaz. A nehezebb pályáknál nemcsak a falak számát emeli, hanem a PLUSIDO változóval meghatározott mértékben az alapidőn túl is lehetőséget nyújt a feladat megoldására.
A PALYA rutin az elfogyasztandó csillagokat helyezi el a pályán, és az AKADSZ változót növeli a kiírt csillagok számával. Az AKADSZ változó mindig azt tartalmazza, hogy hány elfogyasztandó csillag van még a pályán. Ha ez eléri a nullát, tehát az összes csillagot elfogyasztottuk, akkor kerül sor a KAPUKI eljárásra, amelyik egy kaput nyit a keret egyik véletlen oldalán és pontján.
Ha a rendelkezésünkre álló időn belül sikerül kimennünk ezen a kapun, akkor teljesítettük ezt a pályát, tehát egy nehezebb következik. Ha nem, akkor a KAPUBE eljárás becsukja a kaput, és újabb csillagok jelennek meg a képernyőn.
A pálya sikeres teljesítésénél a NEVET ünnepli, vagy hiba esetén a SIR eljárás bátorítja a játékost.
Mindezek a részletek annyira hasonlítanak a KANYARGÓ-nál megismertekre, hogy nem érdemes túl részletesen foglalkozni velük. Az igazi újdonság a kukac mozgását megvalósító eljárásokban kereshető.
A kukac valójában nem egy folyamatos vonal, hanem egy sor egymás utáni pontból áll. Ezeknek a pontoknak a koordinátái a KUKACX és a KUKACY tömbökben vannak, például a 3-as pont a KUKACX(3) sorban és a KUKACY(3) oszlopban helyezkedik el. A kukac mozgatásakor azonban nem kell az össze pontját mindig eggyel előrébb rajzolni, hiszen a második biztos, hogy az első helyére kerülne, a harmadik a másodikéra és így tovább. Ezért csak a legutolsó pontot kell törölnUnk a képernyőről, s kirajzolni egy Újat a legeleső elé. Ezt a LEPES eljárás végzi. Azt, hogy merre kell lépni, az IRÁNY eljárás állapítja meg.
870 DEF IRANY
880 IF VX=0 THEN
890 SELECT CASE JOY(0)
900 CASE 1
910 LET VX=0
920 LET VY=1
930 CASE 2
940 LET VX=0
950 LET VY=-1
960 CASE 4,5,6
970 LET VX=1
980 LET VY=0
990 CASE 8,9,10
1000 LET VX=-1
1010 LET VY=0
1020 CASE ELSE
1030 END SELECT
1040 ELSE
1050 SELECT CASE JOY(0)
1060 CASE 1,5,9
1070 LET VX=0
1080 LET VY=1
1090 CASE 2,6,10
1100 LET VX=0
1110 LET VY=-1
1120 CASE 4
1130 LET VX=1
1140 LET VY=0
1150 CASE 8
1160 LET VX=-1
1170 LET VY=0
1180 CASE ELSE
1190 END SELECT
1200 END IF
1210 END DEF
Ez leolvassa a botkormány helyzetét és beállítja a VX és a VY változókat. A kukac elejének pillanatnyi helyzetéből (X, Y) az új pont következőképpen adódik: X=X+VX, Y=Y+VY. Ezt a számítást már a LEPES eljárás végzi el.
1230 DEF LEPES
1240 NUMERIC S1,S2,UMT
1250 LET UMT=MOD(MT+1,HOSSZ)
1260 LET S1=KUKACX(UMT)
1270 LET S2=KUKACY(UMT)
1280 PRINT £102,AT S1,S2:" ";
1290 LET X=KUKACX(MT)+VX
1300 LET Y=KUKACY(MT)+VY
1310 LET MT=UMT
1320 LET KUKACX(MT)=X
1330 LET KUKACY(MT)=Y
1340 CALL VIZS
1350 PRINT £102,AT X,Y:"O";
1360 SOUND PITCH 25,DURATION 1
1370 PRINT £102,AT 1,19:IDO;
1380 END DEF
Az új pontot természetesen nemcsak a képernyőre kell kirajzolni, hanem a KUKACX- KUKACY tömbökbe is be kell jegyezni. Az MT mutató mindig a tömb azon elemére mutat, amelyik a kukac legutolsó pontjának helyzetét tartalmazza. A kukac végének törléséhez tehát a (KUKACX(MT), KUKACY(MT)) pontot kell leradírozni a képernyőn. A tömb így kiürült helyére kerül az új kukacpont, tehát az új X és Y.
A kukac úgy halad előre, hogy mindig töröljük a legutolsó pontját és kirajzolunk egy újat az elejére. Ehhez azonban a kukac elejét mutató MT változónak végig kell haladni a kukac pontjait tároló tömb elemein. Ez a tömb (KUKACX-KUKACY) egy maximum 80 elemű kukac tárolására alkalmas, de mi nem mindig rajzolunk ilyen hosszú állatot. Amikor a játék elkezdődik, a kukac hossza mindössze 5 elem, s minden csillag elfogyasztásánál eggyel nő. Hogy most éppen hány eleme van a kukacnak, azt a HOSSZ változó tartalmazza.
A LEPES eljárás a 1250-es sorban határozza meg az új mutató értékét. Ezután kiradarozza az új mutatóval megcímzett tömbelemnek megfelelő pontot a képernyőről (1280-as sor), kiszámítja a kukac elejének új pozícióján (1290-1300 sorok) és beírja azt, a tömbbe (1320-1330). Mielőtt a pontot a 1350-es sorban kiírná a képernyőre, a 1340-es sorban meghívja a VIZS rutint, amellyel megvizsgálja, hogy ennek a következő pontnak szabad-e a helye? Végül a lépés hangját indítja, el az 1360-as sorban és az IDO változó tartalmát, tehát a még rendelkezésünkre álló lépések számát írja ki a képernyő tetejére.
1710 DEF VIZS
1720 PRINT £102,AT X,Y:;
1730 GET £102:A$
1740 SELECT CASE A$
1750 CASE " "
1760 CASE "*"
1770 SOUND PITCH 70,DURATION 2
1780 CALL NOV
1790 LET AKADSZ=AKADSZ-1
1800 IF AKADSZ=0 THEN CALL KAPUKI
1810 CASE ELSE
1820 LET VEGE=1
1830 END SELECT
1840 END DEF
A VIZS eljárás abban az esetben, ha egy csillagot talál a kukac elejének új pozíciójában, meghívja a NOV eljárást, ami eggyel növeli a kukac hosszát. Ugyanekkor csökkenti a még hátra levő csillagok számát (AKADSZ), s ha az nulla, akkor kinyitja a kaput (KAPUKI).
510 DEF START
520 LET AKADSZ=0
530 LET HOSSZ=5
540 RANDOMIZE
550 IF RND<.5 THEN
560 LET Y=INT(RND(38))+2
570 LET VY=0
580 IF RND<.5 THEN
590 LET X=3
600 LET VX=1
610 ELSE
620 LET X=23
630 LET VX=-1
640 END IF
650 ELSE
660 LET X=(RND(21))+3
670 LET VX=0
680 IF RND<.5 THEN
690 LET Y=2
700 LET VY=1
710 ELSE
720 LET Y=39
730 LET VY=-1
740 END IF
750 END IF
760 FOR I=1 TO HOSSZ
770 LET KUKACX(I)=1
780 LET KUKACY(I)=1
790 NEXT
800 LET MT=0
810 LET KUKACX(0)=X
820 LET KUKACY(0)=Y
830 CALL VIZS
840 PRINT £102,AT X,Y:"O";
850 END DEF
Ahogy a képernyő kezdeti kialakítását a KERET, a FALAK és a PALYA eljárások végzik, ügy a kukac indítását a START eljárás intézi. Az 550-es és a 750-as sorok közötti részen kijelöli a kukac kezdőpontját és kezdeti mozgásirányát, ennek megfelelően betölti az X, Y, VX, VY változókat. A KUKACX és a KUKACY tömb elemeit ügy tölti fel, mintha a kukac a képernyő 1,1 pontfan állna, de ott nem jelenik meg semmi, mert ezek a pontok csak arra szolgálnak, hogy helyükre fokozatosan az új pozíciók töltődhessenek be. A kukac elejét mutató MT változó nulláról indul, így a X és Y értékét a KUKACX(0)-ba és a KUKACY(0)-ba kell tölteni. Végül, mielőtt kirajzolná a kukac kezdőpontját elvégzi a VIZS eljárást is, hiszen a véletlenszerűen kijelölt kezdőponton is állhat egy csillag, amit el kell fogyasztani.
100 PROGRAM "Hamika.bas"
110 STRING A$
120 NUMERIC X,Y,VX,VY
130 NUMERIC KUKACX(0 TO 79)
140 NUMERIC KUKACY(0 TO 79)
150 NUMERIC MT,KAPUX,KAPUY
160 NUMERIC AKADSZ,HOSSZ
170 NUMERIC IDO,PLUSIDO
A program elején állá változók közül az X, Y, VX, VY már ismert, ahogy a KUKACX és a KUKACY tömb is. Szó volt az MT mutatóról, az AKADSZ számlálóról és a HOSSZ változóról is. Az IDO változóban az adott pálya teljesítéséhez még rendelkezésünkre á11ó lépések száma van, a PLUSIDO-ben pedig az a többletidő, amit a nehezebb pályákon használhatunk fel. A KAPUX és a KAPUY a kereten nyíló kapu koordinátáit tartalmazza. Végül szerepel az A$ változó, amelybe a VIZS eljárás olvas, de amely nem belső változója a VIZS-nek, mivel a főprogram is megvizsgálja tartalmát a 2590-es sorban.
Eddig mindenütt a hasonlóságot hangsúlyoztuk a KANYARGO és a HAMIKA között, de van közöttük egy igen-igen fontos eltérés is. Ez pedig a paraméterhasználat. A KANYARGÓ-nál láttuk azt, hogy sokszor még olyan esetekben is paramétert használunk, amikor pontosan tudjuk, melyik külső változóra lenne szükségünk. Ennek az az előnye, hogy utólag könnyen felhasználhatjuk a már kész eljárásainkat más programokhoz is.
Itt, a HAMIKA-ban egy egészen más programozási stílust használtunk. Ez csak ilyen viszonylag kis programoknál engedhető meg, mert a programozónak az összes külső változót fejben kell tartania. A módszer lényege, hogy minden információt külső eljárásokban tárolunk, így valamennyi olyan eljárás, amelyiknek szüksége van rá, könnyen hozzáférhet. Ezek az eljárások mindig legyenek nagyon egyszerűek és rövidek, és minden belső változójukat az eljárás elején szigorúan jelezni kell, nehogy egy külső változóval összekeveredjen. Ez- a megoldás nagyon sok hibalehetőséget hordoz magában, éppen ezért kezdő programozóknak nem ajánljuk, de a gyakorlottak számára már igen kényelmes eszköz lehet olyan adatok tárolásához, amelyeket több eljárás is használ.
A főprogram egy számláló ciklus, amelyben a pálya nehézségi foka változik 1-től 4-ig. Ha nem sikerül teljesíteni a pályát, akkor a SIR rutin eggyel csökkenti a SZINT tartalmát. Ennek alapján azt gondolnánk, hogy a SZINT nem változik (hiszen a ciklus növeli, a SIR eljárás pedig csökkenti eggyel), de valójában mást tapasztalunk. Az 1-től 4-ig számláló cikluson belül ugyanis egy belső DO-LOOP ciklus van (a 2410-es sortól a 2650-es sorig), amelyből csak akkor lépünk ki, ha sikerül teljesíteni a pályát (2630-as sor). Hiba esetén tehát nem azt a szintet kell megismételnünk, ahol hibáztunk, hanem az eggyel könnyebbre ugrunk vissza.
Ennek a beágyazott DO-LOOP ciklusnak az elején mindig létrehozzuk az új pályát (KERET, FALAK, START). Mindaddig nem léphetünk tovább, amíg nem teljesítjük időre a pályát. Ez egy újabb DO-LOOP ciklust jelent, ami a 2450-es sortól a 2580-as sorig tart.
Mivel a pályán meghatározott ideig kell haladnunk, így a játék közben eltelt időt is számlálnunk kell. Ezt egy további beágyazott ciklus végzi, amely a 2480-as sorban indul és a 2520-as sorban végződik. Ez már számláló, azaz FOR ciklus, és az IDO változóval lépked a 120+PLUSIDO értéktől egészen 0-ig. Ha elértük a nullát, akkor kifutottunk az időnkből, tehát a DO-LOOP ciklusnak megfelelően újra kezdődik a számlálás, de előtte a 2460-as sorban újabb csillagokat kapunk a pályára.
A program szerkezete tehát igen bonyolult, négy ciklus ágyazódik egymásba. A legkülső FOR (2400-2660) a nehézségi szinteket számlálja, az ebbe ágyazott DO-LOOP (2410-2650) biztosítja, hogy csak a sikeresen elvégzett pálya után lehessen magasabb nehézségi fokú pályára lépni. Ezen belül áll egy másik DO-LOOP (2450-2580), ami arra ügyei, hogy az idő lejárta esetén ne lépjünk ki a pályáról, s végül a legbelső FOR (2480-2520) a lépéseket számlálja.
Ezen belül már tényleg csak lépegetni kell, azaz itt az IRANY és a LEPES eljárások szerepelnek. Mivel a LEPES eljárás automatikusan meghívja a VIZS eljárást, ezért nem kell külön jelölni azt. A 2510-es sorban mégis felhasználhatjuk a VEGE változót, amelyet a VIZS állít be.
A teljes játékprogram majdnem háromszáz sor. Talán kicsit soknak tűnik, de jelentősen nem rövidíthető anélkül, hogy a játék ne veszítsen túl sokat élvezetességéből. így azonban igazán kellemes kikapcsolódást kínál minden próbálkozónak. Jó szórakozást!