5.) Írjunk programot, mely
kiírja az összes ASCII karaktert a kódjával együtt.
Gyakran előfordul ugyanis, hogy a képernyőn való
megjelenítés egyetlen eszköze csak az lehet, ha a karaktereket kódjuk
segítségével visszük a listába, hiszen nincs minden karakterhez billentyű,
gondoljunk csak a kereteket megjelenítő karakterekre. A kódok megismerésében
lesz segítségünkre ez a program. A feladatot megvalósító rövid program több
újdonságot tartalmaz.
Program Karakter;
Uses NewDelay,
Crt;
Var I: Byte;
Begin
TextMode(CO80);
ClrScr;
For
I:= 0 To 255 Do
Write(I:3,': ',Chr(I),' ');
ReadLn;
End.
Mivel a karakterkészlet
a 0-255 kódokkal hívható, a feladatban 256-szor kellene kiíró művelet
végrehajtani. Ezt nyilván nem lenne célszerű ennyiszer a listába beírni. Van
olyan kódolási megoldás, amelynél a program egy része
többször is végrehajtódik. Ezzel elérhetjük, hogy kevés kóddal, nagyon sok
lépésre utasítjuk a gépet. Ezek a módszerek az iterációk. A Pascal nyelv
három iterációt ismer, amely közül most a For
ciklust alkalmaztuk. A For ciklus
alkalmazásának feltétele: véges sok és jól meghatározott alkalommal kell egy
utasítást végrehajtani. Ez az ismétlő eljárás elől tesztelő, tehát a ciklus
magja lehet, hogy egyetlen egyszer sem hajtódik végre. Kulcsszavai For … To … Do. Az I a ciklusváltozó. A Pascal nyelvben a változókat a program
elején, a program fejében deklarálni kell, azaz le kell írni. Vagyis, meg kell
adni a nevét (azonosítóját) és a típusát. Erre való a Var kulcsszó. A Var után
vesszővel elválasztva fel kell sorolni a változók nevét és kettőspont után a
típusát. A programban az I Byte típusú, ami 0-255 közötti egész számot jelent.
Az újabb típusú változókat pontosvesszővel kell elválasztani egymástól. Majd
egy olyan későbbi programban, amelyben több változó is lesz, megfigyelhetjük
ennek a szintakszisát. Az I:= 0 programrészlet az I változó értékét 0-ra
állítja. Ez az értékadó utasítás. Így olvasandó: I legyen egyenlő 0. Ez az I
ciklusváltozó kezdő értéke. A To
után álló

A lista Write
eljárásában is sok az újdonság. Eddig csak szöveget írattunk ki vele, itt
viszont egy változó és egy függvény értékét is. Ezek aktuális értékét illetve
aktuális visszaadott értékét írja ki az utasítás. A változó az I ciklusváltozó.
Az I:3 alakkal azt érjük el, hogy 0-255 szám mindegyike a képernyőn 3 helyet
foglaljon el. Ez a táblázatos kialakításhoz elengedhetetlen, hiszen az
intervallum számai 1,2 ill. 3 jegyűek, és ez elrontaná az azonos szélességű
kiírást. A másik szembetűnő dolog Write-ban, hogy egyszerre több dolog is
kiírható vele. Az egyes részeket vesszővel elválasztva kell felsorolni. Ebben a
Write-ban 4 szakasz figyelhető meg. 1.: az I kiírása három karakteren, 2.: egy
kettőspont és egy Space, tehát két karakteren, 3.: a Chr(I), amely az I kódhoz
tartozó karaktert jelenti egy képernyő helyen, 4.: két db. Space, ami ugye két
karakter. Ha az egyszerre kiírandó karakterek számát összeszámoljuk, akkor
nyolcat kapunk. Ez nem véletlen. A képernyő egy sorába 80 karakter fér, így egy
sorba pontosan 10 karakter foglal majd helyet. Ez összesen 2600 képernyőhely
lenne, ami azt mutatja, hogy ez biztosan nem fér el, lévén a képernyő 2000
karakteres. Azért, hogy a karakterek elejét is láthassuk és értelmezhessük,
legalább egy futtatás idejére a lista 255 értékét csökkentsük 200-ra. A
karaktertábla elején több olyan karakter is van, melyet Write utasítással még
Chr függvény segítségével sem lehet a képernyőre írni. Ezek a képernyőkezelő
vezérlő karakterek, amelyek kiírása a vezérlés végrehajtását jelenti, pl.:
soremelés, kocsi vissza, BackSpace, Tab, vagy a Chr(7), amely hangot ad.

Ismerkedjünk meg a karaktertábla
kódtartományaival:
0-31:
vezérlő karakterek,
32-47:
írásjelek,
48-57:
számjegyek,
58-64:
írásjelek, (64-es a @),
65-90:
az angol ABC nagy betűi,
91-96:
írásjelek,
97-122:
az angol abc kis betűi,
123-128:
írásjelek,
129-175:
nemzetközi karakterkészlet,
176-178:
kitöltő karakterek,
179-220:
grafikus jelek keretek rajzolásához,
221-255:
egyéb speciális karakterek és írásjelek.
További programjainkban
az egyvonalas keretek kódjaira szükség lesz. Célszerű ezt a program
segítségével kigyűjteni, és egy rajzon rögzíteni:
218 194 191
|
196 179 |
|
|
195 |
197
180 |
192 193 217
Az ábrán a
Gyakorló programozási feladatok:
F.5.: Írj programot, amely 3x4-es méretben
pálcika-emberkét rajzol a képernyőre. Keressünk a karakterkészletből olyan
karaktereket, hogy a figura minél jobban élethű legyen.
F.6.: Írj programot, amely a képernyőre egy
hangjegyfüzethez hasonló 5-ös vonalrendszert rajzol. Két vonal között maradjon
egy üres sor, az 5-ös vonalsorok között legalább 3 sor.
F.7.: Írj programot, amely bemutatja a következő
vezérlő karakterek hatását a képernyőre írás közben: #7, #8, #9, #10 és #13.
6.) Készítsünk
programot, amely egy 20 x 5 méretű keretet rajzol a képernyő bal felső sarkába.
A
szokásos kezdősorok után a karaktereket For
ciklus segítségével helyezzük a képernyőre. Eltekintünk a sarkok pontos
kezelésétől, akár többször is kirajzoljuk, csak a végeredményre koncentráljunk.
Program Keret;
Uses NewDelay, Crt;
Var I: Byte;
Begin
TextMode(CO80);
ClrScr;
For
I:= 1 To 20 Do
Write(Chr(196));
GoToXY(1,1);
For I:= 1 To 5 Do
WriteLn(Chr(179));
ReadLn;
End.
A ClrScr; biztosítja,
hogy a képernyőn csak a mi rajzunk lesz, valamint azt, hogy a rajzolást a bal
felső sarokban kezdjük. Az első For
ciklus egy 20 karakter hosszú vízszintes vonalat rajzol a képernyőre. A bal
szélső, függőleges oldal megrajzolását a második For ciklus végzi. Ha a GoToXY eljárást kihagyjuk, akkor a
függőleges keretelemeket a jobb felső sarokban kezdi el rajzolni. A második
Write sem a szokásos. WriteLn-nek írtuk. Eddigi Write-ok az író kurzor helyét
ott tartották, ahol az írás befejeződött. A WriteLn az írás után egy soremelés
+ kocsi vissza (ugrás a sor elejére) lépést is végrehajt, így minden kiírás új
sor elején kezdődik. Ez biztosítja, hogy a függőleges elemek egy oszlopba
kerülnek és összeáll belőle a keret bal széle. Rajzoljunk tovább:
Program Keret;
Uses NewDelay,
Crt;
Var I: Byte;
Begin
TextMode(CO80);
ClrScr;
For
I:= 1 To 20 Do
Write(Chr(196));
GoToXY(1,1);
For I:= 1 To 5 Do
WriteLn(Chr(179));
GoToXY(1,5);
For I:= 1 To
20 Do
Write(Chr(196));
ReadLn;
End.
Ez az állapot már az
alsó vízszintes oldalt is megrajzolta. De hogyan rajzoljuk meg a jobb oldali
függőleges vonalat. Gondoljuk csak meg: ha csak Write-ot használunk, akkor a
függőleges elemek egymás mellé kerülnek, ha WriteLn-t, akkor legfeljebb csak az
első elem kerül a helyére, a többi biztosan a sor elejére, azaz a már
megrajzolt oldalra, és nem a 20. oszlopba. Úgy néz ki, hogy a Do után nemcsak rajzolni kell, hanem
mindig azt is meg kell mondani, hogy hova, azaz előbb vezérelni a kurzort. Ez
két teljesen különböző utasítás. A Do
után viszont csak egy utasítás állhat ciklusmagként. A megoldás az összetett
utasítás, amelyet a következő listában látunk.
Program Keret;
Uses NewDelay,
Crt;
Var I: Byte;
Begin
TextMode(CO80);
ClrScr;
For
I:= 1 To 20 Do
Write(Chr(196));
GoToXY(1,1);
For I:= 1 To 5 Do
WriteLn(Chr(179));
GoToXY(1,5);
For I:= 1 To
20 Do
Write(Chr(196));
For
I:= 1 To 5 Do
Begin
GoToXY(20,I);
Write(Chr(179));
End;
ReadLn;
End.
A GoToXY(20,I)
biztosítja, hogy mindig a 20. oszlopba ugrik a kurzor, és ahogy az I nő, úgy
mindig eggyel lejjebb lévő sorba, azaz összeáll a jobb szélső oldal. Tehát a
második, 5-ig menő For ciklus után
egy új szerkezeti elemet találunk, az összetett utasítást. A program bármely,
de általában tartalmilag összetartozó, egymás után elhelyezkedő sorát Begin … End;-ba zárhatjuk. A programnak ezt a részét összetett utasításnak
nevezzük, amely a fordító számára egyetlen utasításnak számít, teljesen
mindegy, hogy egyébként hány tényleges utasítást, esetleg további összetett
utasítást is tartalmaz. Figyeljük meg, hogy ezen összetett utasítás végén lévő End után nem pont van, mint a program
végén, hanem pontosvessző. Valamint azt is vegyük észre, hogy a lista
megjelenése itt is tükrözi a strukturáltságot, az összetett utasítás belső
utasításait még beljebb írtuk. Ha most futtatjuk programunkat, láthatjuk, hogy
az oldalak már készen vannak, de a négy csúcsa még nem zárt, oda a megfelelő
sarokelemeket még ki kell rajzolni. Ez már nem jelenthet gondot:
Program Keret;
Uses NewDelay,
Crt;
Var I: Byte;
Begin
TextMode(CO80);
ClrScr;
For
I:= 1 To 20 Do
Write(Chr(196));
GoToXY(1,1);
For I:= 1 To 5 Do
WriteLn(Chr(179));
GoToXY(1,5);
For I:= 1 To
20 Do
Write(Chr(196));
For
I:= 1 To 5 Do
Begin
GoToXY(20,I);
Write(Chr(179));
End;
GoToXY(1,1);
Write(Chr(218));
GoToXY(1,5);
Write(Chr(192));
GoToXY(20,1);
Write(Chr(191));
GoToXY(20,5);
Write(Chr(217));
ReadLn;
End.

Ezzel a keretrajzoló
programunkat befejeztük. Ha fokozatosan írtuk be, akkor láthattuk a
kialakulásának menetét is. Mentsük ki, mert tanulságos programot írtunk.

7.) Írjunk programot,
amely egy boríték látványát adja a képernyőn, kb. olyat, mint amit a rajz
mutat, majd írjunk rá címzést is.

Mielőtt a programíráshoz
kezdenénk, nézzük csak meg okával, mi is az, amit meg kellene valósítani. Az
ábrán van 7 db keret és 6 db vízszintes vonal. Az előző program egyetlen,
speciális helyzetű keretet rajzol, és 23 sorban sikerült megoldani. Ha az előző
program tapasztalatait felhasználva, új módszer nélkül szeretnénk megoldást
adni, bizony lehet, hogy 200 sornyi programot is kellene írni. De van jobb
megoldás. A hét téglalap rajzolása lényegében ugyanolyan jellegű sorokat
jelentene, csak a képernyő helyeket megadó paraméterekben különböznének. Ha a
programnyelvben egy bizonyos, többször ismétlődő feladatra nincs eljárás, akkor
az lenne a jó, ha magunk is írhatnánk ilyeneket, és ezt a Pascal nyelv lehetővé
is teszi. Az eljárásokat a program elején, a deklarációs részben kell leírni.
Az eljárások csak akkor hajtódnak végre, ha a főprogramban meghívjuk,
használjuk őket. Nézzük, milyen eljárásokat tudnánk használni: a képernyő adott
helyére való írást, vízszintes vonalrajzolót, függőleges vonalrajzolót,
keretrajzolót. Első lépésként ezen eljárások fejét kell megírni. A pascal
nyelvben az eljárás neve: Procedure.
Formailag ugyanúgy néz ki, mint a program, csak magában a programban, annak
deklarációs részében foglal helyet. Ezen eljárások neve legyen: WriteXY,
VVonal, FVonal és Keret.
Program Boritek;
Uses NewDelay,
Crt;
Procedure
WriteXY;
Begin
End;
Procedure
VVonal;
Begin
End;
Procedure FVonal;
Begin
End;
Procedure
Keret;
Begin
End;
Begin
End.
Figyeljük meg, hogy
minden eljárást a Procedure
lefoglalt szó vezet be, mindegyiknek van Begin
.. End; -je. A főprogram még nem
tartalmaz egyetlen utasítást sem. A már deklarált eljárásokat pedig már
hívhatná is, csakhogy azok végrehajtó része üres, így semmit sem tennének. Az
egész lista csak egy keret, amelyet ezután töltünk meg tartalommal. De mit is
tudjanak ezek az eljárások? A WriteXY eljárás tudjon megadott helyre egy
szöveget kiírni. Azt, hogy hova és mit, azt a híváskor paraméterként kellene
megkapni, így bárhova, bármilyen szöveget vagy karaktert kiírna. Nézzük csak az
eljárást:
Procedure
WriteXY(X,Y: Byte; Sz: String);
Begin
GoToXY(X,Y);
Write(Sz);
End;
Az eljárás hívásához
szükséges paramétereket típusával együtt az eljárás neve után, zárójelben kell
felsorolni. A sorrend is számít, mert ugyanilyen sorrendben kell a híváskor a
paramétereket használni. Ebben az eljárásban egy új típust is találunk, amely
mint típusnév, lefoglalt szó: String.
Karakterláncot, vagy magyarosabban szöveget jelent, melynek hossza 0-255 lehet,
és tetszőleges karaktereket tartalmazhat. Érdekes módon a String lefoglalt szó. Az eljárás végrehajtó része magáért beszél.
Ezt az eljárást a következőképpen használhatjuk: WriteXY(40,12,’A’); aminek
hatására a képernyő közepére egy „A” betű kiíródik. A VVonal feladata az, hogy
a képernyő kezdő X koordinátájától vég X koordinátájáig az Y sorba vonalat
húzzon. Ez három paramétert jelent, és használjuk a most megírt WriteXY-t. Az
eljárás:
Procedure
VVonal(Xk,Xv,Y: Byte);
Var I: Byte;
Begin
For
I:= Xk To Xv Do
WriteXY(I,Y,Chr(196));
End;
Mint látjuk az
eljárásnak magának is lehet változója. Ez az úgynevezett lokális változó. Erről
egy másik eljárás nem tud, csak ez az eljárás használhatja, még a főprogram
sem. A Program kulcsszót követően, a
program globális változóit deklarálhatjuk, mint ahogy azt az eddigi
főprogramjainkban tettük, amelyeket az eljárások és a főprogram is használhat.
Az FVonal feladata az,
hogy függőleges vonalat húzzon az X oszlopba, Y kezdő értéktől, Y vég értékig.
Az eljárás:
Procedure
FVonal(X,Yk,Yv: Byte);
Var I: Byte;
Begin
For
I:= Yk To Yv Do
WriteXY(X,I,Chr(179));
End;
Az utóbbi két eljárás
használata: VVonal(20,60,8); illetve FVonal(55,3,22); az első egy vízszintes
vonalat húz a 8. Sorba 20-60 X koordináták között, a második az 55. Oszlopba
függőleges vonalat húz a 3-22 Y koordináták között. Milyen paraméterek
kellenének a Keret eljáráshoz? A válasz: ugyanazok, mint a Window-hoz. A keretet
a bal felső csúcsa és a jobb alsó csúcsa két-két koordinátája egyértelműen
megadja. A megvalósító eljárás:
Procedure
Keret(Bfx,Bfy,Jax,Jay: Byte);
Begin
VVonal(Bfx+1,Jax-1,Bfy);
VVonal(Bfx+1,Jax-1,Jay);
FVonal(Bfx,Bfy+1,Jay-1);
FVonal(Jax,Bfy+1,Jay-1);
WriteXY(Bfx,Bfy,Chr(218));
WriteXY(Jax,Bfy,Chr(191));
WriteXY(Jax,Jay,Chr(217));
WriteXY(Bfx,Jay,Chr(192));
End;
Ezt az eljárást
Keret(1,1,20,5); paraméterekkel használva a Keret
nevű programban megrajzolt téglalapot kapjuk. Természetesen bármely jól
megállapított paraméterekkel alkalmazhatjuk, ugyanaz vonatkozik a
paramétereire, mint a Window eljárásnak.
Nézzük
ezután a teljes Boríték programot:
Program Boritek;
Uses NewDelay,
Crt;
Procedure
WriteXY(X,Y: Byte; Sz: String);
Begin
GoToXY(X,Y);
Write(Sz);
End;
Procedure
VVonal(Xk,Xv,Y: Byte);
Var I: Byte;
Begin
For
I:= Xk To Xv Do
WriteXY(I,Y,Chr(196));
End;
Procedure
FVonal(X,Yk,Yv: Byte);
Var I: Byte;
Begin
For
I:= Yk To Yv Do
WriteXY(X,I,Chr(179));
End;
Procedure
Keret(Bfx,Bfy,Jax,Jay: Byte);
Begin
VVonal(Bfx+1,Jax-1,Bfy);
VVonal(Bfx+1,Jax-1,Jay);
FVonal(Bfx,Bfy+1,Jay-1);
FVonal(Jax,Bfy+1,Jay-1);
WriteXY(Bfx,Bfy,Chr(218));
WriteXY(Jax,Bfy,Chr(191));
WriteXY(Jax,Jay,Chr(217));
WriteXY(Bfx,Jay,Chr(192));
End;
Begin
TextMode(CO80);
ClrScr;
Keret(1,1,80,24);
Keret(69,2,78,6);
Keret(4,17,15,19);
Keret(55,21,57,23);
Keret(59,21,61,23);
Keret(63,21,65,23);
Keret(67,21,69,23);
VVonal(7,30,3);
VVonal(7,25,5);
VVonal(20,60,12);
VVonal(55,76,17);
VVonal(55,74,19);
WriteXY(2,2,'F.a.:');
WriteXY(6,18,'AJÁNLOTT');
WriteXY(71,4,'BÉLYEG');
GotoXY(1,25);
ReadLn;
End.
A teljes lista kb. 50
sorból áll, azaz jóval kevesebb, mint a számított

Megemlítjük még, hogy az
első keret eljárás nem véletlenül tartalmaz 24-et és nem 25-öt. A maximális
méretű keret rajzolására ez az eljárás nem alkalmas. Ez a benne rejlő Write
eljárás tulajdonságaira vezethető vissza. A legnagyobb keret készítése ugyanis
azt igényelné, hogy Write-al írjunk a képernyő utolsó helyére. Ekkor azonban a
kurzor az írás utáni helyre kell, hogy ugorjon. Mivel ilyen nincs (nem úgy,
mint a fentebbi soroknál, ahol ott van a következő sor első helye), ezért a gép
automatikusan soremelést hajt végre, aminek következtében az első sor (azaz a
felső keretvonal) eltűnik. Van rá megoldás, hogy ez ne következzen be, de ilyen
lehetőségekkel majd egy későbbi program kapcsán fogunk megismerni. További
érdekessége még a keret eljárásnak, hogy hibás nagysági-sorrenddel rendelkező
paraméterekkel is rajzol, sarokelemeket mindenképp, oldalakat viszont nem, a
benne rejlő For ciklus visszafelé
nem működik (mármint nagyobb kezdő értéktől a kisebb felé). Akkor sem kapunk
keretet, ha az X értékek, vagy Y értékek megegyeznek (nem úgy a Window
eljárásnál, ott „egy” szélességű vagy magasságú ablak is létrejöhet).
A lista, mint minden
Pascal lista, három fő részből áll, melyek elnevezése: Program és a Uses sora :
programfej, Procedure …End; : deklarációs rész (lehetne
benne Var és egyéb eddig még nem
használt dolog is), Begin … End. : főprogram.

Gyakorló programozási feladatok:
F.8: Írjunk programot, amely az előzőekben
bemutatott, a téglalap rajzolásához szükséges karaktereket és kódjukat jeleníti
meg a képernyőn. (Hasonlóan az előzőekben bemutatott ábrához.)
F.9.: Írjunk programot, mely egy kocka
kiterített felszínét rajzolja a képernyőre. Használjuk a Boritek program keretrajzoló eljárását.
F.10.: Írjunk programot, mely a nyakas játék
játékmezőit rajzolja a képernyőre. Aki nem ismeri: 8 négyzetből áll, 3 egyes
négyzet, majd egy kettős négyzet, majd egy négyzet (ez a nyak), majd újra 2
négyzet, mindez 6 négyzet magasan, és a kettős négyzetek egymás mellett vannak
az ábra hossztengelyére szimmetrikusan.
F.11: Írjunk programot, amely egy monitor képét
rajzolja a képernyőre. Igyekezzünk a karakteres képernyő lehetőségeit minél
jobban kihasználni az élethű megvalósítása érdekében. A monitoron legyen írás,
esetleg színes, kettős kerete (közte más színnel), legyenek kezelő gombok,
legyen lába (tartója) stb.