|
Hát! Alig kezdek beindulni, máris igazat kell adnom az észrevételnek:
"Ha ilyen lassan haladunk, mikor fogunk saját progit írni?"
Felhasználva, hogy már van néhány egyszerűbb magyar progi a Zillire
gyorsabban haladhatunk az Zilli-nyelv megtanulásában,
ha az azok még működő lerövidítését próbáljuk meg értelmezni.
Előbb-utóbb sor fog kerülni mindegyik utasításra...
4. A tologatós amőba
A játék lényege, hogy a játékosok a tábla széléről befelé töltögetik a táblát. A tábla valamelyik szélső mezőjére -kivéve a sarkokat- teszik le a golyójukat, majd ugyanabban a
lépésben egy pozícióval beljebb tolják.
|
|
Ezzel persze a már táblán lévő, a letett melletti golyó
(golyósor) is egy pozícióval beljebb kerül. A tábla széle tehát körben mindig üresen marad. Ha
egy sor megtelt, akkor abba már több (újabb golyó) nem tolható be, ilyen esetben pedig már a
szélre való lerakás is tilos. A partit az nyeri, akinek előbb jön össze nyerő a négyese
-éppúgy, mint az AMŐBA-ban-.
A lentebb mutatott két (hosszab és rövidebb) ZRF megértése betekintést ad abba,
hogyan magyarázhatjuk
meg a Zilli-nek ezeket a (lerakást is és mozgatást is tartalmazó) lépéseket.
|
Emlékeztetőül, mindkét zrf-ben megtalálható öt "alapblokk":
általános pl.: a játék neve, kétszemélyes, lépéskényszeres, játékosok sorrendje,
hanghatások, leírások, helpek, stb.
táblakép, mezőszámozás, mezők "szomszédjai"...
bábuk neve, képe, lépéslehetőségei
kezdőállás
nyerő-, ill. vesztő (döntetlen) helyzetek
Ezt az öt blokkot vezeti fel a (game
megnyitás,
az öt blokk végét pedig a megnyitott zárójel )
bezárása jelzi.
Ez ötös "főcsoport" előtt a többször használt programsorokat
(define ... )
formába zárva, az ötös egység
után pedig a változatokat jellemző eltéréseket (variant ... )
formába zárva szokás rendszerezni.
|
|
Szokás? Úgy tűnik az eddig elkészült progik többsége ezt a struktúrát követi. Egyébként
nincs sorrendi probléma! Az ábrán keretezett blokkok sorrendjét teszőlegesen összekeverve is
képes megérteni a ZRF-et feldolgozó/végrehajtó Zillions.exe progi. Ne feledjük!
A zrf logikailag nem jelenthet többet,
mint a Zillions.exe beállítási- és "input"-adatait. Az exe sok-sok alapértelmezett
(automatikusan felvett) beállítással
dolgozik, ezeket írja felül, illetve ezeket egészíti ki a zrf. Érdemibb dolog feltehetően csak akkor
indul el az exe-vel, ha már az összes ilyen beállítási "input" rendelkezésére áll, ezeket pedig sorrendiség nélkül
is értelmezni tudja. A "szokást" mégis javasolt betartani azért, hogy magunk is és mások is
könnyebben eligazodjunk egy-egy kész zrf piszkálásakor.
Ebből viszont az következik, hogy a zrf fenti szokás szerint
leírt utasításlistájának sorfolytonos értelmezése csak a Games blokkon belül követi az
információk logikusan egymásra épülő sorrendjét.
Egy ismeretlen zrf tartalmának értelmezését
a (games ... ) blokkban kell kezdeni. Az alábbi zrf-listák olvasási/értelmezési
sorrendjét a magyarázó szöveg számozása jelzi. Induljunk el
az 1. től!
A ZRF-eket is és a képeket is megtalálod a kitömörített munka 4 könyvtár-ban.
(Hálóról nem indul, de letölthető:
munka4.zip (20 kB))
|
;***********************************************
; tologatos AMŐBA: négy a nyerő 7x7
;(direkt címzésű mozgatás)
;lásd a munka4/TOL_SULI02.ZRF
;***********************************************
|
(Ide a 9-re utolsóként!!! Kezdeni az 1.től!!!)
9.. A Zillions.exe nem értelmezi a ";" után írtakat egészen az adott sor végéig.
Ennek funkciója, hogy magyarázó szövegeket írhassunk a zrf-be, netán (pl. az egyes blokkokat a
kilistázáskor szemléletesen elkülönítő jelzéseket helyezhessünk el akár az értelmezett sorok
végére, akár az értelmezett sorok közé.
|
(define def1l (verify (in-zone? keretl) ) (verify empty?) n
(if empty? s add-partial else n
(if empty? s s add-partial else n
(if empty? s s s add-partial else n
(if empty? s s s s add-partial else n
(if empty? s s s s s add-partial else n
(if empty? s s s s s s add-partial else n
(if empty? s s s s s s s add-partial ) ) ) ) ) ) )
)
(define def1f (verify (in-zone? keretf) ) (verify empty?) s
(if empty? n add-partial else s
(if empty? n n add-partial else s
(if empty? n n n add-partial else s
(if empty? n n n n add-partial else s
(if empty? n n n n n add-partial else s
(if empty? n n n n n n add-partial else s
(if empty? n n n n n n n add-partial ) ) ) ) ) ) ) )
)
(define def1b (verify (in-zone? keretb) ) (verify empty?) e
(if empty? w add-partial else e
(if empty? w w add-partial else e
(if empty? w w w add-partial else e
(if empty? w w w w add-partial else e
(if empty? w w w w w add-partial else e
(if empty? w w w w w w add-partial else e
(if empty? w w w w w w w add-partial ) ) ) ) ) ) ) )
)
(define def1j (verify (in-zone? keretj) ) (verify empty?) w
(if empty? e add-partial else w
(if empty? e e add-partial else w
(if empty? e e e add-partial else w
(if empty? e e e e add-partial else w
(if empty? e e e e e add-partial else w
(if empty? e e e e e e add-partial else w
(if empty? e e e e e e e add-partial ) ) ) ) ) ) ) )
)
|
4. "def1l", "def1f", "def1b", def1j" (láthatóan szinte ugyanolyan) négy "define", melyeket
egyenként hív meg a zrf piece blokkjának drops utasítása. Mit "ért meg" ezekből a Zilli?
Vegyük sorra pl. a "def1l" nevű utasításait!
Vizsgáld át (verify) a mezőket a táblán és a továbbiakban vesd el mindazokat,
amelyek nem a "keretl" nevű zónában vannak (in-zone?) és nem üresek (empty?)!
A megmaradó mezők közül sorra mindegyik mezőről lépj felfelé egyet (n) és mindegyik esetben
végezd el a következőket!
Ha üres (if empty?) a mező, akkor lépj vissza (s) és azt a mezőt, ahol állsz írd be azok közé
(add), amik közül az adott lépés majd szabadon kiválasztható!
Fontos megjegyzés: a "-partial" azt jelzi, hogy ennek a lépésnek megtétele után még más is
következhet, azaz a nyerőhelyzet vizsgálatát későbbre halasztja.
Ez két okból is fontos:
a./ Egyrészt nem állítja le a partit, ha egy részlépés közben nyerőhelyzetet észlel.
b./ Másrészt (és erről nem szabad megfeledkezni) az ellenlépés keresésekor, ezen részlépések
eredményének értékelő figyelembevétele is elmarad.
Mi történik tehát ezekben az "if"-sorozatokban? A tábla alsó sorának mindegyikéből
(kivéve a sarkokat) külön-külön
újra kezdve, elindul felfelé és egyenként megvizsgálja, hogy ahol áll, az üres-e.
Ha így talál egy üres mezőt, akkor visszamegy az indulási mezőre és annak pozíció-azonosítóját
hozzáadja az adott lépésben választhatók közé.
Nézzük pl. a "def1l" utolsó if-sorát! Amikor ezt vizsgálja, akkor az előző hat mezőn
a korábbi vizsgálatokkor mindig talált valamilyen bábut (az "else"-k ágán jutott ide).
Ha a hetedik üres, akkor héttel ( s s s s s s s )
visszalépve, újra az induló mezőn van, amit hozzáad a lehetséges lépésekhez. Ha a hetedik sem
üres, akkor abba az oszlopba már nem enged lerakni.
Vegyük észre azt, hogy a fentiek a tábla összes mezőjének értékelésével választják ki,
mint lépéslehetőségeket, a fenti táblakép alsó nyílsorával jelzettek közül azokat, amelyek
felett legalább egy üres hely van (ami ugye kell a betoláshoz).
|
(define def2b
( w
(if (in-zone? bal) (go from)
(while not-empty? cascade from w to) add
) )
)
(define def2j
( e
(if (in-zone? jobb) (go from)
(while not-empty? cascade from e to) add
) )
)
(define def2l
( s
(if (in-zone? fent) (go from)
(while not-empty? cascade from s to) add
) )
)
(define def2f
( n
(if (in-zone? lent) (go from)
(while not-empty? cascade from n to) add
) )
)
|
5. Itt is négy nagyon azonosnak tűnő define blokk van, amiket a piece blokk move utasítása hív be.
A lerakáskor megismertek alapján, az a várakozásunk, hogy ezeknek a kimenetén is megjelenik
a (szabályokat betartó) összes lépéslehetőség. Így igaz, de fontos észrevenni azt a különbséget,
hogy a mozgatás (move) elsődlegesen a már táblán lévő bábuhoz kapcsolható és ezért nincs
szükség a tábla összes mezőjének értékelésére. Ezt "tudja" is a Zilli, mert a move "értelmezése"
mindig a táblán lévő bábuk helyzetéből indul.
Nézzük pl. a legutolsót, a def2f-et! Mit érthet ezen a Zilli?
Vedd sorra a soron következő játékos táblán lévő bábuit és az alábbiakat mindegyikkel csináld
végig.
Lépj fel a bábuval szomszédos mezőre (n) Ha most a "lent" nevű zónán állsz,
akkor jegyezd meg mi volt ott a rálépés előtt (go from)???
Innen már gőzőm nincs, hogyan gondolkodik a Zilli...
A "cascade" utasítást kellene alaposabban megismerni, hogyan működik együtt a "while" utasítással.
A "while" az utána megadott feltétel teljesüléséig folyamatosan végrehajtja a feltétel után
megadott utasítást.
Ha már megértettem, majd igyekszem pótolni, addig is legyen elég a kísérletezéshez az, hogy:
szándék és működés szerint a def2f kiválasztja mindazokat a sortolási lehetőségeket, amelyeknél
az alsó
nyílon lévő golyó, a vele közvetlenül érintkező felette lévőket egy pozícióval eltolva, maga is
feljebb kerül.
a 6.-nál folytatódik !!!
|
(game
(title "tologatós AMŐBA: négy a nyerő 7x7")
(players White Black)
(turn-order White Black )
(pass-turn false)
(animate-drops false)
|
1.
Az általános blokk tartalmával foglalkoztunk a 2.progisuliban
.
Az itt/most még nem ismert utasítás azt tiltja meg (false=hamis), hogy a Zillions.exe
minden újonnan lerakandó bábut (az alaphelyzetében értelmezett) felülről lefelé csúsztatott
animációval hozza a táblára. Vajh, melyik
lehet?
|
(board
(image "images\Tolos\tolos7x7.bmp")
(grid
(start-rectangle 15 15 43 43 )
(dimensions
("a/b/c/d/e/f/g/h/i" (28 0) )
("9/8/7/6/5/4/3/2/1" (0 28) )
)
(directions (e 1 0) (ne 1 -1) (nw -1 -1) (s 0 1) (n 0 -1) (w -1 0) )
)
(zone (name bal) (players White Black )
(positions h2 h3 h4 h5 h6 h7 h8)
)
(zone (name jobb) (players White Black)
(positions b2 b3 b4 b5 b6 b7 b8)
)
(zone (name fent) (players White Black)
(positions b8 c8 d8 e8 f8 g8 h8)
)
(zone (name lent) (players White Black)
(positions b2 c2 d2 e2 f2 g2 h2)
)
(zone (name keretj) (players White Black )
(positions i2 i3 i4 i5 i6 i7 i8)
)
(zone (name keretb) (players White Black)
(positions a2 a3 a4 a5 a6 a7 a8)
)
(zone (name keretf) (players White Black)
(positions b9 c9 d9 e9 f9 g9 h9)
)
(zone (name keretl) (players White Black)
(positions b1 c1 d1 e1 f1 g1 h1)
)
)
|
2. A tábla képének, a mezők kiosztásának, a mezők számozásának értelmezésével részletesen foglalkoztunk
a 3. progisuliban
Ehhez azt is meg kell még adni, hogy milyen irányokra (directions...)
fogunk majd a zrf-ben hivatkozni, pontosabban: egy-egy mezőről milyen irányokban juthatunk el
egy másik mezőre. Itt, most hat irány van megadva: "n", "ne"... nevekkel és " 0 ,-1 "
, " 1 , 1 " pozíciókkal azonosítva. A Zillions.exe a tábla mezőit a sorok
és az oszlopok "grid"-ben megadott osztása szerint már ismeri. Kétdimenziós táblánál, az
egymástól zárójelezéssel elválasztott iránymeghatározásokban az elso szám pozitív értéke a
jobbra eső mezőre, a másik szám pozitív értéke a
lefelé eső mezőre mutat. (Pl.: a " 1, -1 ", "egyet jobbra, egyet fel", az adott mezőtől átlósan felfelé eső szomszédra
irányít. A könnyű megjegyezhetőség céljából, többnyire az égtájak kezdőbetűit javasolt
irányazonosítónak alkalmazni: n-nord Észak, s-süd Dél, e-east Kelet, w-west Nyugat...)
Meglehetősen hosszú a zone-azonosítók sora, de értelmezésük kézenfekvő: megadják egy-egy valamilyen
célból azonosnak tekinthető mezők pozícióit és a csoportoknak (mint zónáknak) a későbbi
hivatkozások egyértelműsítése céljából neveket adnak.
Egyszersmind arról is rendelkezik ez a zónadefiniálás, hogy az adott zóna fehér és fekete
játékosra egyaránt értelmezhető. Pl: a "bal" elnevezésű zóna a 9x9-es tábla jobb oszlopának, de a
sarkokat nem tartalmazó mezőit jelenti és az erre majd valahol megadottak mindkét
játékosra vonatkoznak.)
|
(piece (name golyo)
(image White "images\Tolos\WDisk.bmp" Black "images\Tolos\BDisk.bmp")
(drops ( (def1l)) ((def1f)) ((def1j)) ((def1b)) )
(moves (def2b)(def2j)(def2l)(def2f) )
)
|
3.
Lehetnek "golyo" nevű bábuk. Ha fehéré, akkor a megadott könytár WDisk.bmp-ben (ha feketéé, akkor
BDisk.bmp-ben) megadott képpel kerülhet a tábla valamelyik mezőjére.
Vagy lerakással (drops), vagy a táblán való elmozgatással (move) változtathatja helyét a
(még mindig a "golyo" nevű) bábu.
A lerakás is és a mozgatás is 4-4 féle, a define-k között "def1l", "def2l"... nevű utasítás-
lista szerint történhet. !!!Érdekes, hogy a dropsnál dupla zárójelezést kell alkalmazni!!!
a 4. alatt folytatódik !!!
|
(board-setup (White (golyo off 99))(Black (golyo off 99)))
|
6. Nyitáskor, mindkét játékosnak 99-99 db golyója van. (Ebben a játékban a darabszámnak nincsen
szerepe, de ha egy "lerakásosban" bármikor elfogy a golyó a Zilli lépésképtelenséget jelez.)
|
(win-condition (White Black)
(or (relative-config golyo n golyo n golyo n golyo )
(relative-config golyo e golyo e golyo e golyo)
(relative-config golyo ne golyo ne golyo ne golyo)
(relative-config golyo nw golyo nw golyo nw golyo)
)
)
|
7. Ha fehérnek vagy feketének, bármelyik befejezett lépése után (White Black),
bárhol a táblán vagy n, vagy e, vagy ne, vagy nw irányban 5 db golyója van, akkor nyert
és vége van a partinak. A relatív-config jelzi, hogy a bábuknak egymáshoz viszonyított
helyzete dönti el a partit. (Más játékokban az absolut-config arra mutat, hogy
a bábuknak a tábla valamely mezőihez viszonyított helyzete a döntő.)
|
)
|
8. Games vége (a variantok nélküli zrf vége).
|
A következő zrf-lista az előzővel teljesen azonos eredményre vezet. Ugyanarra a játékra
"tanítja meg" a Zillit, mint az előző. Rövidsége a define-k parametrizálásának köszönhető.
Miután a fentihez képest egyetlen új utasítást sem használ, nagyon jó gyakorlatnak ígérkezik,
ha a fent részletezett zrf-et próbáljuk meg saját magunk lerövidíteni !
Amit tudni kell hozzá, az kézenfekvő igényként felmerül a fenti zrf-lista ismétlődéseinél:
ha a define-k behívásakor megadhatnánk, hogy az s/n, n/s, e/w, w/e iránypárosok közül
melyik kettőt használja, akkor a zónák összevontabb kialakításával, a 4 db define helyett
elegendő lenne 1 db-ot megírni. (Ez persze később majd csak programmozói elegancia kérdése lesz, hiszen
sokkal munkásabb, mint négyszer lecopyzni és átírni a változásokat. De most a gyakorláshoz feltétlenül
nagyon hasznos.)
A Zillions.exe a "define"-ben található $1, $2, $3, ... jeleket olyan paraméter-változóknak
tekinti, amelyek a behíváskor kapnak értéket.
A CD-ről telepített Birodalomban, egyszerűsített formában, az alább listázott TOL_SULI01.ZRF,
piszkálható munkakönyvtárban, csak a működéshez
feltétlen szükséges utasításokat tartalmazza...
A zrf-listák közül nagyon ajánlom még értelmezésre Salvi Peti első progiját:
HG_Japan.zrf Angoltudás
hiányában, magam is ebből indultam el.
Sok sikert kívánok mindegyikhez... (Nagylaci)
|
;*************************************************************************************************
; tologatos AMŐBA: négy a nyerő 7x7 (direkt címzésű mozgatás) TOL_SULI01.ZRF
;*************************************************************************************************
(define lerak
(if (in-zone? keret) $1
(if ( and empty? (not-in-zone? keret )( not-in-zone? sarok)on-board?)
$2 add-partial else $1
(if ( and empty? (not-in-zone? keret )( not-in-zone? sarok)on-board?)
$2 $2 add-partial else $1
(if ( and empty? (not-in-zone? keret )( not-in-zone? sarok)on-board?)
$2 $2 $2 add-partial else $1
(if ( and empty? (not-in-zone? keret )( not-in-zone? sarok)on-board?)
$2 $2 $2 $2 add-partial else $1
(if ( and empty? (not-in-zone? keret )( not-in-zone? sarok)on-board?)
$2 $2 $2 $2 $2 add-partial else $1
(if ( and empty? (not-in-zone? keret )( not-in-zone? sarok)on-board?)
$2 $2 $2 $2 $2 $2 add-partial else $1
(if ( and empty? (not-in-zone? keret )( not-in-zone? sarok)on-board?)
$2 $2 $2 $2 $2 $2 $2 add-partial ) ) ) ) ) ) ) )
)
(define eltol ($1 $2
(if ( in-zone? keret ) $1
(if ( and ( not-in-zone? keret )on-board? (not-in-zone? sarok) (go from)
(while not-empty? cascade from $1 to) add ) ) )
)
(game
(title "tologatós AMŐBA: négy a nyerő 7x7")
(players White Black)
(turn-order White Black )
(pass-turn false)
(animate-drops false)
(board
(image "images\Tolos\tolos7x7.bmp")
(grid
(start-rectangle 15 15 43 43 )
(dimensions
("a/b/c/d/e/f/g/h/i" (28 0) )
("9/8/7/6/5/4/3/2/1" (0 28) )
)
(directions (e 1 0) (ne 1 -1) (nw -1 -1) (s 0 1) (n 0 -1) (w -1 0) )
)
(zone (name keret) (players White Black)
(positions b1 c1 d1 e1 f1 g1 h1 b9 c9 d9 e9 f9 g9 h9
a2 a3 a4 a5 a6 a7 a8 i2 i3 i4 i5 i6 i7 i8 )
)
(zone (name sarok) (players White Black)
(positions a1 a9 i9 i1)
)
)
(piece (name golyo)
(image White "images\Tolos\WDisk.bmp" Black "images\Tolos\BDisk.bmp")
(drops
((lerak n s)) ((lerak s n)) ((lerak w e)) ((lerak e w))
)
(moves
(eltol w e)(eltol e w)(eltol s n)(eltol n s)
)
)
(board-setup (White (golyo off 99))(Black (golyo off 99)))
(win-condition (White Black)
(or (relative-config golyo n golyo n golyo n golyo )
(relative-config golyo e golyo e golyo e golyo)
(relative-config golyo ne golyo ne golyo ne golyo)
(relative-config golyo nw golyo nw golyo nw golyo)
)
)
)
|
|
|