I'm working on modernizing Rosetta Code's infrastructure. Starting with communications. Please accept this time-limited open invite to RC's Slack.. --Michael Mol (talk) 20:59, 30 May 2020 (UTC)

CLI-based maze-game

From Rosetta Code
CLI-based maze-game is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

Task: Create a complete but CLI-controlled maze-game![edit]

Use the CLI interface only. The symbols:

1. The hero: @

2. Strong monsters: * (they can kill you).

3. Weak monsters: . (You can kill them).

4. Treasure: $

5. Wall: X

6. Bomb: b

7. Revolving door: -o-

and:

|
o
|

(the monsters are stupid, they can't use these doors)

Monsters must be moved by the computer, automatically. Use for this subtask a fork()-ed part of your program.

The maze must be generated randomly, at each start of the game.

Note: I apologize of my bad English, I'm very sorry...

Furor[edit]

 
###sysinclude terminal.uh
###sysinclude into.uh
###sysinclude math.uh
 
###define VÁRAKOZIK 40000
// Minél nagyobb a fenti szám, annál lassabban mozognak a szörnyek.
###define MERETX 69
// A labirintus oszlopainak számozása 0 és MERETX-1 közt történik.
// MERETX muszáj hogy páratlan szám legyen.
###define MERETY 31
// A labirintus sorainak számozása 0 és MERETY-1 közt történik.
// MERETY muszáj hogy páratlan szám legyen.
###define TREASURE '$
###define TREASUREDB 3
// A treasuredb jelenti, hány $ jel lesz elhelyezve
###define WAY 32
###define FAL 'X
###define wayszín 0
###define wayháttérszín 0
// Az alábbi doors az ajtók számát jelzi a labirintus falaiban.
###define doors 20
###define AJTÓKÖZEPE 'o
###define AJTÓSZÁRNYFÜGGŐLEGES '|
###define AJTÓSZÁRNYVÍZSZINTES '-
###define AJTÓszín $e
###define AJTÓháttérszín 0
###define FALszín $1b
###define FALháttérszín FALszín
###define HŐS '@
###define HALOTTHŐS '+
###define HŐSszín 9
###define HŐSháttérszín 0
###define kincsszín $b
###define kincsháttérszín 0
// Ennyi bombát lehet találni a labirintusban:
###define bombákszáma 5
###define bomba 'b
###define bombaszín $a6
###define bombaháttérszín 0
 
###define szörnyekszáma 20
###define szörny '*
###define szörnyszín $d
###define szörnyháttérszín 0
###define gyengeszörny '.
###define gyengeszörnyszín $cd
###define gyengeszörnyháttérszín 0
###define szörnygyengülvalószínűség 25
// A fenti szám minél magasabb, annál kisebb az esélye hogy egy erős szörny gyengévé válik.
###define szörnyerősödikvalószínűség 5
// A fenti szám minél magasabb, annál kisebb az esélye annak, hogy egy gyenge szörny megerősödik.
 
argc 2 > {
."Labirintusjáték. Készítette: Viola Zoltán alias Harold King alias Fossil Codger.\n"
."([email protected])\n"
."A program a Furor programnyelven íródott, azt a programnyelvet is én, Viola Zoltán írtam.\n"
."A játék célja: az összes kincs megszerzése. A kincs jelképe a $ jel.\n"
."Kilépés: az Esc 2-szer lenyomva, vagy a q.\n"
."A b lenyomásával robbanthatsz, de csak amíg maradt bombád.\n"
."Egy bomba minden falat lerombol a játékos körül (a labirintus legszélső, keretező"
." falait kivéve), de a szörnyeket nem öli meg.\n"
."A bomba átlósan se rombol, csak függőlegesen és vízszintesen!\n"
."A bomba nem pusztítja el az ajtókat, és a kincset se.\n"
."Bombákat találhatsz is a labirintusban, ezeket a b betű jelképezi. Ha rájuk lépsz,\n"
."azzal megszerezted a bombát, azaz a bombáid száma növekszik, később ezeket\n"
."felhasználhatod.\n"
."A játék akkor ér véget, ha az összes kincset megszerezted.\n"
."A labirintusban nem csak falak, de forgóajtók is vannak.\n"
."A forgóajtó ha vízszintes, így néz ki: -o-\n"
."Ha meg függőleges akkor így:\n"
."|\n"
."o\n"
."|\n"
."A forgóajtó közepét az o karakter, a szárnyait a vonal jelképezi.\n"
."A forgóajtó elfordítható, ha a szárnyának a megfelelő irányból nekimész a karaktereddel,\n"
."és ha semmi se áll az elforgatás útjában.\n"
."A játékost a @ jelképezi a játékban, s kiindulási helye mindig a bal alsó sarokban van.\n"
."Van a játékban kis csalásra is lehetőség: a B (nagy bé betű) minden lenyomása eggyel\n"
."megnöveli a bombáid mennyiségét.\n"
 
end
}
 
3 sto bombs // A bombák száma.
randinit // A véletlenszámgenerátor inicializálása
pálya MERETY MERETX createsharedscreen
100 shared sto messagestring // kommunikációs terület a forkolt programrészeknek
szörnyekszáma shared sto sxkoord
szörnyekszáma shared sto sykoord
üres() // Ez elkészíti az üres területet, falakkal körülhatárolva
generatemaze() // Ez legenerálja véletlenszerűen a labirintust
// ********************************************************
//
// Ki- és bejáratok generálása, ha szükséges:
//
MERETY 2 - dup sto y sto newy 0 dup sto x sto newx
pálya @y @x HŐS [[^]] // A hős karakterének letevése
// ********************************************************
 
cursoroff
cls
§kirajzol fork sto kirajzoló
§szörnymozgat fork sto szörnymozgató
 
kirajzolni:
@newy sto y @newx sto x
kirajzol2:
@messagestring 6 [] then §meghaltahős
@messagestring 1 @bombs [^]
@messagestring 2 @kincsszámláló [^]
@kincsszámláló TREASUREDB #g == {
100000 usleep
@messagestring 5 1 [^] // Üzenetküldés a szörnymozgatás leállítására
@messagestring 0 1 [^] // üzenetküldés a kirajzolónak hogy álljon le
@szörnymozgató wait
@kirajzoló wait
."YOU WON! Congratulations!\n"
goto §vége
}
pálya @y @x [[]] HALOTTHŐS == {
100000 usleep
meghaltahős:
@messagestring 5 1 [^] // Üzenetküldés a szörnymozgatás leállítására
@messagestring 0 1 [^] // üzenetküldés a kirajzolónak hogy álljon le
@szörnymozgató wait
@kirajzoló wait
."YOU PERISHED! :(\n"
goto §vége
}
// Billentyűzetinput
newinputchar: #g 11 into sto kar
@kar $ffffffffffffffff == then §kirajzol2
@kar 128 < { @kar 27 == then §vége2
@kar 'q == then §vége2
@kar 'B == { inc bombs goto §kirajzol2 }
@kar 'b == { @bombs else §newinputchar // Ha elfogyott a bomba, hiába minden...
dec bombs
@x 1 > { pálya @y @x -- [[]] FAL == { pálya @y @x -- WAY [[^]] } }
@y 1 > { @x { pálya @y -- @x [[]] FAL == { pálya @y -- @x WAY [[^]] } } }
@x MERETX 2 - < { pálya @y @x ++ [[]] FAL == { pálya @y @x ++ WAY [[^]] } }
@y MERETY 2 - < { @x { pálya @y ++ @x [[]] FAL == { pálya @y ++ @x WAY [[^]] } } }
goto §kirajzol2
}
goto §newinputchar }
@kar $ff & sto k
@x sto newx @y sto newy
@k 1 == { // kurzorfel
dec newy @newy else §newinputchar
@x else §lépés
@y 1 == §newinputchar
// -o-
// @
pálya @newy @newx [[]] AJTÓSZÁRNYVÍZSZINTES ==
pálya @newy @newx ++ [[]] AJTÓKÖZEPE ==
pálya @newy -- @newx [[]] WAY ==
pálya @newy -- @newx ++ [[]] WAY ==
pálya @newy ++ @newx 2 + [[]] WAY ==
pálya @newy ++ @newx ++ [[]] WAY ==
& & & & & {
pálya @newy @newx WAY [[^]]
pálya @newy @newx 2 + WAY [[^]]
pálya @newy -- @newx ++ AJTÓSZÁRNYFÜGGŐLEGES [[^]]
pálya @newy ++ @newx ++ AJTÓSZÁRNYFÜGGŐLEGES [[^]]
goto §lépés
}
// -o-
// @
pálya @newy @newx [[]] AJTÓSZÁRNYVÍZSZINTES ==
pálya @newy @newx -- [[]] AJTÓKÖZEPE ==
pálya @newy -- @newx [[]] WAY ==
pálya @newy -- @newx -- [[]] WAY ==
pálya @newy ++ @newx 2 - [[]] WAY ==
pálya @newy ++ @newx -- [[]] WAY ==
& & & & & {
pálya @newy @newx WAY [[^]]
pálya @newy @newx 2 - WAY [[^]]
pálya @newy -- @newx -- AJTÓSZÁRNYFÜGGŐLEGES [[^]]
pálya @newy ++ @newx -- AJTÓSZÁRNYFÜGGŐLEGES [[^]]
goto §lépés
}
goto §lépés
} // kurzorfel vége
@k 2 == { // kurzorle
inc newy @newy MERETY -- >= then §newinputchar
@x else §lépés
// @
// -o-
pálya @newy @newx [[]] AJTÓSZÁRNYVÍZSZINTES ==
pálya @newy @newx ++ [[]] AJTÓKÖZEPE ==
pálya @newy ++ @newx [[]] WAY ==
pálya @newy ++ @newx ++ [[]] WAY ==
pálya @newy -- @newx 2 + [[]] WAY ==
pálya @newy -- @newx ++ [[]] WAY ==
& & & & & {
pálya @newy @newx WAY [[^]]
pálya @newy @newx 2 + WAY [[^]]
pálya @newy -- @newx ++ AJTÓSZÁRNYFÜGGŐLEGES [[^]]
pálya @newy ++ @newx ++ AJTÓSZÁRNYFÜGGŐLEGES [[^]]
goto §lépés
}
// @
// -o-
pálya @newy @newx [[]] AJTÓSZÁRNYVÍZSZINTES ==
pálya @newy @newx -- [[]] AJTÓKÖZEPE ==
pálya @newy ++ @newx [[]] WAY ==
pálya @newy ++ @newx -- [[]] WAY ==
pálya @newy -- @newx 2 - [[]] WAY ==
pálya @newy -- @newx -- [[]] WAY ==
& & & & & {
pálya @newy @newx WAY [[^]]
pálya @newy @newx 2 - WAY [[^]]
pálya @newy -- @newx -- AJTÓSZÁRNYFÜGGŐLEGES [[^]]
pálya @newy ++ @newx -- AJTÓSZÁRNYFÜGGŐLEGES [[^]]
goto §lépés
}
goto §lépés
} // kurzorle vége
@k 3 == { // kurzorjobbra
inc newx @newx MERETX >= then §newinputchar
@x MERETX -- == then §newinputchar
@x else §lépés
// @|
// o
// |
//@newy 2 + MERETY >= then §lépés
pálya @newy @newx [[]] AJTÓSZÁRNYFÜGGŐLEGES ==
pálya @newy ++ @newx [[]] AJTÓKÖZEPE == & else §jobbra2
pálya @newy @newx ++ [[]] WAY ==
pálya @newy ++ @newx ++ [[]] WAY ==
pálya @newy ++ @newx -- [[]] WAY ==
pálya @newy 2 + @newx -- [[]] WAY ==
& & & {
pálya @newy @newx WAY [[^]]
pálya @newy 2 + @newx WAY [[^]]
pálya @newy ++ @newx -- AJTÓSZÁRNYVÍZSZINTES [[^]]
pálya @newy ++ @newx ++ AJTÓSZÁRNYVÍZSZINTES [[^]]
goto §lépés
}
// |
// o
// @|
jobbra2:
@newy -- else §lépés
pálya @newy @newx [[]] AJTÓSZÁRNYFÜGGŐLEGES ==
pálya @newy -- @newx [[]] AJTÓKÖZEPE ==
pálya @newy @newx ++ [[]] WAY ==
pálya @newy -- @newx ++ [[]] WAY ==
pálya @newy -- @newx -- [[]] WAY ==
pálya @newy 2 - @newx -- [[]] WAY ==
& & & & & {
pálya @newy @newx WAY [[^]]
pálya @newy 2 - @newx WAY [[^]]
pálya @newy -- @newx -- AJTÓSZÁRNYVÍZSZINTES [[^]]
pálya @newy -- @newx ++ AJTÓSZÁRNYVÍZSZINTES [[^]]
goto §lépés
}
goto §lépés
} // kurzorjobbra vége
@k 4 == { // kurzorbalra
@x else §newinputchar
dec newx @newx else §newinputchar
// |@
// o
// |
//@newy 2 + MERETY >= then §lépés
pálya @newy @newx [[]] AJTÓSZÁRNYFÜGGŐLEGES ==
pálya @newy ++ @newx [[]] AJTÓKÖZEPE == & else §balra2
pálya @newy @newx -- [[]] WAY ==
pálya @newy ++ @newx -- [[]] WAY ==
pálya @newy ++ @newx ++ [[]] WAY ==
pálya @newy 2 + @newx ++ [[]] WAY ==
& & & {
pálya @newy @newx WAY [[^]]
pálya @newy 2 + @newx WAY [[^]]
pálya @newy ++ @newx -- AJTÓSZÁRNYVÍZSZINTES [[^]]
pálya @newy ++ @newx ++ AJTÓSZÁRNYVÍZSZINTES [[^]]
goto §lépés
}
// |
// o
// |@
balra2:
//@newy -- else §lépés
pálya @newy @newx [[]] AJTÓSZÁRNYFÜGGŐLEGES ==
pálya @newy -- @newx [[]] AJTÓKÖZEPE == & else §lépés
pálya @newy @newx -- [[]] WAY ==
pálya @newy -- @newx ++ [[]] WAY ==
pálya @newy -- @newx -- [[]] WAY ==
pálya @newy 2 - @newx ++ [[]] WAY ==
& & & {
pálya @newy @newx WAY [[^]]
pálya @newy 2 - @newx WAY [[^]]
pálya @newy -- @newx -- AJTÓSZÁRNYVÍZSZINTES [[^]]
pálya @newy -- @newx ++ AJTÓSZÁRNYVÍZSZINTES [[^]]
goto §lépés
}
goto §lépés
 
} // kurzorbalra vége
goto §newinputchar
// =========================================================
// =========================================================
lépés:
pálya @newy @newx [[]] FAL == then §newinputchar
pálya @newy @newx [[]] AJTÓKÖZEPE == then §newinputchar
pálya @newy @newx [[]] AJTÓSZÁRNYVÍZSZINTES == then §newinputchar
pálya @newy @newx [[]] AJTÓSZÁRNYFÜGGŐLEGES == then §newinputchar
pálya @newy @newx [[]] TREASURE == { inc kincsszámláló }
pálya @newy @newx [[]] bomba == { inc bombs }
pálya @newy @newx [[]] szörny == { pálya @y @x WAY [[^]]
pálya @newy @newx HALOTTHŐS [[^]]
goto §kirajzolni }
pálya @y @x WAY [[^]]
pálya @newy @newx HŐS [[^]]
goto §kirajzolni
 
// *******************************************************
vége2:
// üzenetküldés a child processeknek hogy álljanak le
@messagestring 0 1 [^]
@messagestring 5 1 [^]
// Várakozás a child processek befejeződésére:
@szörnymozgató wait
@kirajzoló wait
vége:
@messagestring free
@sxkoord free
@sykoord free
pálya eraseshared
,,, cursoron
end
// ********************************************************
 
kirajzol:
closestdin // Nem várunk semmi billentyűzetinputot
{... // végtelenciklus
// .......................................................
@messagestring 0 [] { end } // Parancs érkezett szeppuku elkövetésére...
// .......................................................
topleft
#k MERETY yloop: {| MERETX {|
pálya {}§yloop {} [[]] WAY == { wayszín tint wayháttérszín !tint pálya {}§yloop {} [[]] print {<} }
pálya {}§yloop {} [[]] FAL == { FALszín tint FALháttérszín !tint pálya {}§yloop {} [[]] print {<} }
pálya {}§yloop {} [[]] AJTÓSZÁRNYFÜGGŐLEGES == { AJTÓszín tint AJTÓháttérszín  !tint pálya {}§yloop {} [[]] print {<} }
pálya {}§yloop {} [[]] AJTÓSZÁRNYVÍZSZINTES == { AJTÓszín tint AJTÓháttérszín  !tint pálya {}§yloop {} [[]] print {<} }
pálya {}§yloop {} [[]] AJTÓKÖZEPE == { AJTÓszín tint AJTÓháttérszín  !tint pálya {}§yloop {} [[]] print {<} }
pálya {}§yloop {} [[]] bomba == { bombaszín tint bombaháttérszín !tint pálya {}§yloop {} [[]] print {<} }
pálya {}§yloop {} [[]] szörny == { szörnyszín tint szörnyháttérszín !tint pálya {}§yloop {} [[]] print {<} }
pálya {}§yloop {} [[]] gyengeszörny == {
gyengeszörnyszín tint gyengeszörnyháttérszín !tint pálya {}§yloop {} [[]] print {<} }
pálya {}§yloop {} [[]] HŐS == { HŐSszín tint HŐSháttérszín !tint pálya {}§yloop {} [[]] print {<} }
pálya {}§yloop {} [[]] HALOTTHŐS == { HŐSszín tint HŐSháttérszín !tint pálya {}§yloop {} [[]] print {<} }
pálya {}§yloop {} [[]] 'a >= pálya {}§yloop {} [[]] 'z <= &
{ kincsszín tint kincsháttérszín !tint pálya {}§yloop {} [[]] print {<} }
,,, pálya {}§yloop {} [[]] print
|} ,,, NL |} NL
."Collected treasure = " #g @messagestring 2 [] print ." Bombs = " @messagestring 1 [] printnl
VÁRAKOZIK usleep
...}
// ********************************************************
szörnymozgat:
closestdin closestdout closestderr // Nem várunk semmi billentyűzetinputot és nem is írunk sehova
randinit
{... // végtelenciklus
6000 usleep
// .......................................................
@messagestring 5 [] { end } // Parancs érkezett szeppuku elkövetésére...
// .......................................................
szörnyekszáma random sto akts
@sxkoord @akts [] sto! sx @sykoord @akts [] sto! sy #g | !{ {.<.} }
pálya @sy @sx [[]] szörny == {
szörnygyengülvalószínűség random 1 == { pálya @sy @sx gyengeszörny [[^]] {.<.} }
sbr §szörnylépéskeres
#g
@szörnyy @szörnyx | !{ {.<.} } // Ha nem talált helyet ahova mozoghatna
pálya @szörnyy @szörnyx [[]] HŐS == { pálya @szörnyy @szörnyx HALOTTHŐS [[^]] @messagestring 6 1 [^] 1000 usleep {.<.} }
pálya @sy @sx WAY [[^]] pálya @szörnyy @szörnyx szörny [[^]]
@sxkoord @akts @szörnyx [^] @sykoord @akts @szörnyy [^]
{.<.}
}
pálya @sy @sx [[]] gyengeszörny == {
szörnyerősödikvalószínűség random 1 == { pálya @sy @sx szörny [[^]] {.<.} }
sbr §szörnylépéskeres
#g
@szörnyy @szörnyx | !{ {.<.} } // Ha nem talált helyet ahova mozoghatna
pálya @sy @sx WAY [[^]]
pálya @szörnyy @szörnyx [[]] HŐS != { // Ha gyenge szörny találkozik a hőssel, a szörnynek vége, nem rajzoljuk ki
pálya @szörnyy @szörnyx gyengeszörny [[^]]
}{ zero szörnyx zero szörnyy }
@sxkoord @akts @szörnyx [^] @sykoord @akts @szörnyy [^]
{.<.}
}
 
...}
// .......................................................
szörnylépéskeres:
zero szörnyy zero szörnyx
24 random sto kvartett // Választunk egy iránykvartettet
#g 4 {|
@kvartett 4 * {} + §irányok[] sto sirány
@sirány 0 == { // fel
@sy !{ {<} }
pálya @sy -- @sx [[]] WAY ==
pálya @sy -- @sx [[]] HŐS == | { @sy -- sto szörnyy @sx sto szörnyx rts }
{<}
} // fel vége
@sirány 1 == { // le
@sy ++ MERETY -- >= { {<} }
pálya @sy ++ @sx [[]] WAY ==
pálya @sy ++ @sx [[]] HŐS == | { @sy ++ sto szörnyy @sx sto szörnyx rts }
{<}
} // le vége
@sirány 2 == { // balra
@sx !{ {<} }
pálya @sy @sx -- [[]] WAY ==
pálya @sy @sx -- [[]] HŐS == | { @sy sto szörnyy @sx -- sto szörnyx rts }
{<}
} // balra vége
@sirány 3 == { // jobbra
@sx ++ MERETX -- >= { {<} }
pálya @sy @sx ++ [[]] WAY ==
pálya @sy @sx ++ [[]] HŐS == | { @sy sto szörnyy @sx ++ sto szörnyx rts }
{<}
} // jobbra vége
|}
rts
irányok:
0 1 2 3 0 1 3 2 0 2 1 3 0 2 3 1 0 3 1 2 0 3 2 1
1 0 2 3 1 0 3 2 1 2 0 3 1 2 3 0 1 3 0 2 1 3 2 0
2 1 0 3 2 1 3 0 2 0 1 3 2 0 3 1 2 3 1 0 2 3 0 1
3 1 2 0 3 1 0 2 3 2 1 0 3 2 0 1 3 0 1 2 3 0 2 1
// ********************************************************************
{ „k” }
{ „x” }
{ „y” }
{ „sx” }
{ „sy” }
{ „kar” }
{ „newx” }
{ „newy” }
{ „akts” }
{ „bombs” }
{ „pálya” }
{ „sirány” }
{ „sxkoord” }
{ „sykoord” }
{ „szörnyx” }
{ „szörnyy” }
{ „kvartett” }
{ „kirajzoló” }
{ „messagestring” }
{ „szörnymozgató” }
{ „kincsszámláló” }
{ „myerrorhandler” // A hibakezelő rutin. Igazság szerint abszolút nincs szükség rá,
// de itt illik legyen a helye ha egy komolyabb progi része lenne
// ez a labirintusrajzoló.
#g sto hibakód sto hívórutin sto hívóneve
."Hiba történt ebben a névtérben: " @hívóneve sprintnl
."Ezt a hibakódot kaptam: " @hibakód printnl
end
{ „hibakód” }
{ „hívórutin” }
{ „hívóneve” }
}
// ---------------------------------------------
{ „üres” __usebigbossnamespace
// Kitölti úttal az egész pályát, de a széleit falakkal
MERETY yciklus: {| MERETX {|
pálya {}§yciklus {} WAY [[^]]
|} |}
MERETY {| pálya {} 0 FAL [[^]] pálya {} MERETX -- FAL [[^]] |}
MERETX {| pálya 0 {} FAL [[^]] pálya MERETY -- {} FAL [[^]] |}
end
}
// ---------------------------------------------
{ „generatemaze” __usebigbossnamespace
###sysinclude math.uh
// Az alábbi sorban beállítjuk az errorhandler függvényt a megfelelőképpen:
@initflag !{ one initflag myerrorhandler §myerrorhandlerlabel set errorhandler }
 
#g // Végig egész számokkal dolgozunk
// Az alábbi 2 sorban memóriát foglalunk 2 stringnek, amik
// segédváltozókként funkcionálnak majd, flagek tárolását végzik:
MERETX mem !maximize sto oszlopflag
MERETY mem !maximize sto sorflag
// ***********************************************************
// Az oszlopok és sorok első és utolsó pozícióit bejelöljük,
// mondván hogy ott már van fal.
//
@oszlopflag 0 1 [^]
@oszlopflag @oszlopflag~ -- 1 [^]
@sorflag 0 1 [^]
@sorflag @sorflag~ -- 1 [^]
// ***********************************************************
// Az alábbi 2 ciklusban az oszlopok és sorok flagjait tároló
// stringek minden páratlanadik pozícióját bejelöljük, ez jelzi
// később, hogy azokkal a sorokkal illetve oszlopokkal nem kell
// törődnie. Fal ugyanis csak páros indexű helyeken építhető.
//
MERETX -- {| {} 2 !/ then{<} @oszlopflag {+} 1 [^] |}
MERETY -- {| {} 2 !/ then{<} @sorflag {+} 1 [^] |}
// ***********************************************************
nextrandom:
// ...............................................
// E két ciklus csekkolja le, van-e még olyan
// sor illetve oszlop, amit nem vizsgáltunk végig.
@oszlopflag {~ @@ !{ goto §kell } |}
@sorflag {~ @@ !{ goto §kell } |}
// ...............................................
// Elhelyezzük a forgóajtókat:
 
doors {|
newrandomneed:
MERETX random sto x
MERETY random sto y pálya @y @x [[]] WAY == then §newrandomneed
// Most már biztos hogy itt fal van.
@x 2 < then §newrandomneed @y 2 < then §newrandomneed
@x MERETX 3 - > then §newrandomneed @y MERETY 3 - > then §newrandomneed
// Megnézzük, függőleges ajtót betehetünk-e.
pálya @y -- @x [[]] FAL == // Ha az aktuális pozíció fölött is fal van
pálya @y ++ @x [[]] FAL == // Ha az aktuális pozíció alatt is fal van
pálya @y -- @x -- [[]] WAY == // balfelső sarok szabad
pálya @y -- @x ++ [[]] WAY == // jobbfelső sarok szabad
pálya @y ++ @x -- [[]] WAY == // balalsó sarok szabad
pálya @y ++ @x ++ [[]] WAY == // jobbalsó sarok szabad
pálya @y @x -- [[]] WAY == // bal szomszéd szabad
pálya @y @x ++ [[]] WAY == // jobb szomszéd szabad
& & & & & & & else §vízszintesteszt
pálya @y @x AJTÓKÖZEPE [[^]]
pálya @y -- @x AJTÓSZÁRNYFÜGGŐLEGES [[^]]
pálya @y ++ @x AJTÓSZÁRNYFÜGGŐLEGES [[^]]
{<}
vízszintesteszt:
// Megnézzük, vízszintes ajtót betehetünk-e.
pálya @y @x -- [[]] FAL == // Ha az aktuális pozíció mellett balra is fal van
pálya @y @x ++ [[]] FAL == // Ha az aktuális pozíció mellett jobbra is fal van
pálya @y -- @x -- [[]] WAY == // balfelső sarok szabad
pálya @y -- @x ++ [[]] WAY == // jobbfelső sarok szabad
pálya @y ++ @x -- [[]] WAY == // balalsó sarok szabad
pálya @y ++ @x ++ [[]] WAY == // jobbalsó sarok szabad
pálya @y ++ @x [[]] WAY == // fent szabad
pálya @y -- @x [[]] WAY == // lent szabad
& & & & & & & else §newrandomneed
pálya @y @x AJTÓKÖZEPE [[^]]
pálya @y @x -- AJTÓSZÁRNYVÍZSZINTES [[^]]
pálya @y @x ++ AJTÓSZÁRNYVÍZSZINTES [[^]]
|}
// Elhelyezzük a kincseket.
TREASUREDB {| sbr §newrandomnumber pálya @y @x TREASURE [[^]] |}
// Elhelyezzük a bombákat.
bombákszáma {| sbr §newrandomnumber pálya @y @x bomba [[^]] |}
// Elhelyezzük a szörnyeket. Kezdetben mind gyengék.
szörnyekszáma {| sbr §newrandomnumber pálya @y @x gyengeszörny [[^]]
@sxkoord {} @x [^] @sykoord {} @y [^]
|}
// ...............................................
@oszlopflag free @sorflag free // Az ideiglenes változók
// memóriaterületének felszabadítása
end
kell:
4 random // Választunk egy irányt véletlenszerűen
§jumpingtable[] [goto] // és elugrunk a megfelelő rutinra
bal: // balról jobbra
MERETY random 2 / 2 * sto aktrand // így biztos páros szám
@sorflag @aktrand [] !{
MERETX -- {|
pálya @aktrand {} [[]] FAL == { {<} }
pálya @aktrand {+} [[]] FAL == { {<} }
pálya @aktrand {} FAL [[^]]
|}
@sorflag @aktrand 1 [^]
}
goto §nextrandom
 
jobb: // jobbról balra
MERETY random 2 / 2 * sto aktrand
@sorflag @aktrand [] !{
MERETX -- {|
pálya @aktrand {-} [[]] FAL == { {<} }
pálya @aktrand {--} [[]] FAL == { {<} }
pálya @aktrand {-} FAL [[^]]
|}
@sorflag @aktrand 1 [^]
}
goto §nextrandom
 
lent: // Lentről fel
MERETX random 2 / 2 * sto aktrand
@oszlopflag @aktrand [] !{
MERETY -- {|
pálya {-} @aktrand [[]] FAL == { {<} }
pálya {--} @aktrand [[]] FAL == { {<} }
pálya {-} @aktrand FAL [[^]]
|}
@oszlopflag @aktrand 1 [^]
}
goto §nextrandom
 
fent: // Fentről le
MERETX random 2 / 2 * sto aktrand
@oszlopflag @aktrand [] !{
MERETY -- {|
pálya {} @aktrand [[]] FAL == { {<} }
pálya {+} @aktrand [[]] FAL == { {<} }
pálya {} @aktrand FAL [[^]]
|}
@oszlopflag @aktrand 1 [^]
}
goto §nextrandom
newrandomnumber:
MERETX random sto x MERETY random sto y pálya @y @x [[]] WAY != then §newrandomnumber
rts
// ..........................................................
myerrorhandlerlabel: fail
{ „x” } { „y” }
{ „initflag” }
{ „oszlopflag” }
{ „sorflag” }
{ „aktrand” }
jumpingtable: §bal §jobb §lent §fent
}
// ---------------------------------------------------------
 
Output:
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
X             X       | X   X X X  .  X       X   X X X     X       X
X XXXXX XXX X X XXXXX o XXX X X XXX X XXXXX XbXXX X X X-o-X XXXXXXX*X
X X X . X   X X X   X | X   X X X   | X X   X X   X X X   X X     * X
X X XXX XXX X X X X X X XXX X X X X o | XXX X XXX X*X XXX X X XXXXX X
X X     X   X   X X     X   X |   X | o     X .   X X X       X     X
X X XXXXX XXX XXXXXXXXXXX XXX o XXXXX | XXXXXXXXXXX X X XXXXXXXXXXXXX
X X     X   X X     * X X   X | X   X X       X   X X X     X       X
X X XXXXX XXX X X XXXXX X XXX X X XXX X XXXXX X XXX X X XXXXX -o-XXXX
X X   @ X   X * X       X   X       X       X                $      X
X XX-o-XXXXXX XXXXXXXXXXX XXX XXXXXXX X-o-XXXXXXXXXXXXXXXXXXXXXXXXXXX
X           X X       X X   X X X   X X       X   X X X     X       X
X   XXXXX XXX X X XXXXX$X XXX X X XXX | XXXXX X XXXbX X*XXXXX X-o-XXX
X-o-    X   X X X .   X X   X X X   X o     X X . X X X     X       X
X   XXXXX XXX X X XXXXX X XXX X X X X | XXXXX X XXX X X XXXXX XX-o-XX
X X     X   X*  X       X  bX     X X       X                       X
X XXXXXXXXXXX XXXXXXXXXXX XXX XXXXXXX XXX-o-XXXXXXXXXXXXXXXXXXXXXXXXX
X   X       X X .   X X X   X X X   X X X     X   X X X   X X       X
X X.X XXX XXX X X X X X X XXX X X X X X X XXX X XXX X X XXX X XXXXXXX
X X     X   X   X X     X  .X     X X       X                       X
X XXX-o-XXXXXXXXXXXXXXXXX XXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX-o-XX
X   X         X     X X X   X X X     X X X   X   X X X   X X     * X
X X XXX XXX X X X X X X XXX X X X X X X X X X XXX X X XXX X X XXXXX X
X |     X   X * X X     X   X X   X X X     X     X X X       X     X
X o -o-XX XXX XXXXXXXXXXX XXX X XXXXX X XXXXXXXXXXX X X XXXXXXXXXXXXX
X |     X   X           X   X       X                               X
XXXXXXXXXXX XXX-o-XXXXX XXX XXXXXXX XXXXXXX-o-XXXXXXXXXXXXXXXXXXXXX X
X   X       X X     X X X   X X X   X X X     X   X XbX     X       X
X X XXX XXX X X XXX X X XXX X X X X X X XXX X XXX X X XXXXX X-o-XXX X
  X     X   X   X                 X X       X      *b    *        * X
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Collected treasure = 1    Bombs = 3

Phix[edit]

-- demo/rosetta/CLI_maze.exw
constant W = platform()=WINDOWS,
UP = iff(W?328:259),
DOWN = iff(W?336:258),
LEFT = iff(W?331:260),
RGHT = iff(W?333:261),
ESC = #1B,
 
MX = 69, -- No of columns (1..MX), must be odd.
MY = 31, -- No of rows (1..MY), must be odd.
TREASURE = '$',
TREASUREDB = 3, -- treasuredb means how many $ signs will be placed
WAY = ' ',
WALL = 'X',
DOORS = 20, -- No of doors
DOOR_CENTER = 'o',
DOOR_WING_VERTICAL = '|',
DOOR_WING_HORIZONTAL = '-',
HERO = '@',
DEAD_HERO = '+',
NUMBER_OF_BOMBS = 5,
BOMB = 'b',
NUMBER_OF_MONSTERS = 20,
MONSTER = '*',
WEAK_MONSTER = '.',
MONSTER_WEAKNESS_PROBABILITY = 25,
-- The higher the above number, the lower the chance that a strong monster will become weak.
MONSTER_INTENSIFIES_PROBABILITY = 5,
-- The higher the number above, the lower the chance that a weak monster will get stronger.
 
help_text = """
Maze game.
 
The object of the game is to get all the treasures. The symbol of the treasure is the $ sign.
Help (display this text): press ? or h
Exit: press Esc or q
You can detonate a bomb by pressing b, but only as long as your bomb remains.
A bomb destroys every wall around the player (the outermost, framing of the maze
except for its walls), but it won't kill monsters.
The bomb does not destroy diagonally, only vertically and horizontally.
The bomb will not destroy the doors or the treasure.
You can also find bombs in the maze, represented by the letter b. If you step on them,
you got the bomb with it, that is, the number of your bombs increases, for later use.
The game ends when you have acquired all the treasures.
The maze has not only walls but also revolving doors.
The revolving door, if horizontal, looks like this: -o-
If vertical, like this:
|
o
|
The center of the revolving door is represented by the character o, the wings by the line.
The revolving door can be rotated if you take your wing in the right direction with your character,
and if nothing stands in the way of rotation.
The player is represented by @ in the game, and his starting point is always in the lower left corner.
There is a possibility of a little cheating in the game: each press of the letter c is one increases
the amount of your bombs.
"""
 
integer bombs = 3,
treasure_counter = 0
 
sequence tb = repeat(WALL,MX),
in = WALL&repeat(WAY,MX-2)&WALL,
grid = {tb}&repeat(in,MY-2)&{tb},
sxkoord = repeat(0,NUMBER_OF_MONSTERS),
sykoord = repeat(0,NUMBER_OF_MONSTERS)
 
function gen_flags(integer l)
sequence res = repeat(false,l)
for i=1 to l by 2 do res[i] = true end for
return res
end function
 
procedure generatemaze()
sequence colflag = gen_flags(MX),
rowflag = gen_flags(MY)
while find(true,colflag)
or find(true,rowflag) do
integer direction = rand(4),
j = floor(rand(iff(direction<=2?MY:MX))/2)*2+1
switch direction do
case 1: -- left
if rowflag[j] then
for r=1 to MX-1 do
if grid[j][r]!=WALL
and grid[j][r+1]!=WALL then
grid[j][r] = WALL
end if
end for
rowflag[j] = false
end if
case 2: -- right
if rowflag[j] then
for r=MX to 3 by -1 do
if grid[j][r-1]!=WALL
and grid[j][r-2]!=WALL then
grid[j][r-1] = WALL
end if
end for
rowflag[j] = false
end if
case 3: -- up
if colflag[j] then
for c=MY to 3 by -1 do
if grid[c-1][j]!=WALL
and grid[c-2][j]!=WALL then
grid[c-1][j] = WALL
end if
end for
colflag[j] = false
end if
case 4: -- down
if colflag[j] then
for c=1 to MY-1 do
if grid[c][j]!=WALL
and grid[c+1][j]!=WALL then
grid[c][j] = WALL
end if
end for
colflag[j] = false
end if
end switch
end while
 
integer doors_placed = 0, x, y
while doors_placed<DOORS do
x = rand(MX-4)+2
y = rand(MY-4)+2
if grid[y ][x ] != WAY
and grid[y-1][x-1] == WAY -- top left corner free
and grid[y-1][x+1] == WAY -- top right corner free
and grid[y+1][x-1] == WAY -- left corner free
and grid[y+1][x+1] == WAY then -- right corner free
-- Let's see if we can put a vertical door.
if grid[y-1][x ] == WALL -- wall above the current position
and grid[y-2][x ] == WALL -- wall above the current position
and grid[y+1][x ] == WALL -- wall below the current position
and grid[y+2][x ] == WALL -- wall below the current position
and grid[y ][x-1] == WAY -- left neighbor free
and grid[y ][x+1] == WAY then -- right neighbor free
grid[y ][x] = DOOR_CENTER
grid[y-1][x] = DOOR_WING_VERTICAL
grid[y+1][x] = DOOR_WING_VERTICAL
doors_placed += 1
-- Let's see if we can put a horizontal door.
elsif grid[y ][x-1] == WALL -- wall left of the current position
and grid[y ][x-2] == WALL -- wall left of the current position
and grid[y ][x+1] == WALL -- wall right of the current position
and grid[y ][x+2] == WALL -- wall right of the current position
and grid[y+1][x ] == WAY -- above neighbor free
and grid[y-1][x ] == WAY then -- below neighbor free
grid[y][x ] = DOOR_CENTER
grid[y][x-1] = DOOR_WING_HORIZONTAL
grid[y][x+1] = DOOR_WING_HORIZONTAL
doors_placed += 1
end if
end if
end while
 
sequence stuff = {{TREASUREDB, TREASURE},
{NUMBER_OF_BOMBS, BOMB},
{NUMBER_OF_MONSTERS, WEAK_MONSTER}} -- At first, all monsters are weak.
 
for i=1 to length(stuff) do
integer {n, what} = stuff[i],
iter = 1
while n do
x = rand(MX)
y = rand(MY)
if grid[y][x]==WAY then
grid[y][x] = what
if what=WEAK_MONSTER then
sxkoord[n] = x
sykoord[n] = y
end if
n -= 1
end if
iter += 1
if iter>10000 then ?9/0 end if -- (sanity check)
end while
end for
end procedure
 
integer terminate = false,
showhelp = false
 
procedure draw()
cursor(NO_CURSOR)
while true do
if showhelp then
clear_screen()
puts(1,help_text)
{} = wait_key()
clear_screen()
showhelp = false
end if
position(1,1)
puts(1,join(grid,"\n")&"\n\n")
printf(1,"Collected treasure = %d Bombs = %d\n",{treasure_counter,bombs})
if terminate then exit end if
task_yield()
end while
end procedure
 
constant dy = {-1,+1, 0, 0},
dx = { 0, 0,-1,+1},
HV = {DOOR_WING_HORIZONTAL,DOOR_WING_VERTICAL}
 
procedure rotate_door(integer ny,nx)
for i=1 to 4 do
integer wy = dy[i],
wx = dx[i],
cy = ny+wy,
cx = nx+wx
if grid[cy,cx]=DOOR_CENTER then
if grid[cy-1][cx-1]=WAY
and grid[cy-1][cx+1]=WAY
and grid[cy+1][cx-1]=WAY
and grid[cy+1][cx+1]=WAY then -- four corners empty
integer py = dy[-i],
px = dx[-i]
if grid[cy+py][cx+px]=WAY
and grid[cy-py][cx-px]=WAY then -- swung door empty
integer door = grid[ny][nx],
flip = HV[-find(door,HV)]
grid[cy+py][cx+px] = flip
grid[cy-py][cx-px] = flip
grid[cy+wy][cx+wx] = WAY
grid[cy-wy][cx-wx] = WAY
end if
end if
exit
end if
end for
end procedure
 
integer x = 1,
y = MY-2
 
procedure keyboard()
integer ny,nx
while not terminate do
integer ch = lower(get_key())
if ch=-1 then task_yield()
elsif ch=ESC or ch='q' then exit
elsif ch='b' and bombs!=0 then
bombs -= 1
for i=1 to 4 do
ny = y+dy[i]
nx = x+dx[i]
if ny>1 and ny<MY
and nx>1 and nx<MX
and grid[ny][nx]=WALL then
grid[ny][nx]=WAY
end if
end for
elsif ch='c' then
bombs += 1
elsif ch='?' or ch='h' then
showhelp = true
else
ch = find(ch,{UP,DOWN,LEFT,RGHT})
if ch then
ny = y+dy[ch]
nx = x+dx[ch]
if ny>1 and ny<MY
and nx>1 and nx<MX then
ch = grid[ny][nx]
if ch=DOOR_WING_VERTICAL
or ch=DOOR_WING_HORIZONTAL then
grid[y][x] = WAY -- (temp. "ghost" him)
rotate_door(ny,nx)
grid[y][x] = HERO
ch = grid[ny][nx] -- (maybe unaltered)
elsif ch=MONSTER then
grid[y][x] = WAY
grid[ny][nx] = DEAD_HERO
y = ny
x = nx
exit
elsif ch=TREASURE then
treasure_counter += 1
if treasure_counter=TREASUREDB then
terminate = true
end if
ch = WAY
elsif ch=BOMB then
bombs += 1
ch = WAY
end if
if ch=WAY
or ch=WEAK_MONSTER then
grid[y][x] = WAY
grid[ny][nx] = HERO
y = ny
x = nx
end if
end if
end if
end if
end while
terminate = true
while get_key()!=-1 do end while -- (purge kbd buffer)
end procedure
 
integer sy, sx, monster_y, monster_x
 
function monster_step_finder()
monster_y = 0
monster_x = 0
sequence m = shuffle(tagset(4))
for i=1 to length(m) do
integer ny = sy+dy[i],
nx = sx+dx[i]
if ny>=1 and ny<=MY
and nx>=1 and nx<=MX
and find(grid[ny][nx],{WAY,HERO}) then
monster_y = ny
monster_x = nx
return true
end if
end for
return false
end function
 
procedure monster_move()
while not terminate do
integer active = rand(NUMBER_OF_MONSTERS)
sx = sxkoord[active]
sy = sykoord[active]
if sx then
integer ch = grid[sy][sx]
if ch=MONSTER then
if rand(MONSTER_WEAKNESS_PROBABILITY)=1 then
grid[sy][sx] = WEAK_MONSTER
elsif monster_step_finder() then
if grid[monster_y][monster_x]=HERO then
grid[monster_y][monster_x]=DEAD_HERO
terminate = true
exit
end if
grid[sy][sx] = WAY
grid[monster_y][monster_x] = MONSTER
sxkoord[active] = monster_x
sykoord[active] = monster_y
end if
elsif ch=WEAK_MONSTER then
if rand(MONSTER_INTENSIFIES_PROBABILITY)=1 then
grid[sy][sx] = MONSTER
elsif monster_step_finder() then
grid[sy][sx] = WAY
if grid[monster_y][monster_x]!=HERO then
grid[monster_y][monster_x]=WEAK_MONSTER
sxkoord[active] = monster_x
sykoord[active] = monster_y
else
sxkoord[active] = 0
sykoord[active] = 0
end if
end if
end if
end if
task_yield()
end while
end procedure
 
generatemaze()
grid[y][x] = HERO
integer draw_id = task_create(draw,{}),
mstr_id = task_create(monster_move,{})
task_schedule(draw_id,{0.2,0.2})
task_schedule(mstr_id,{0.1,0.1})
 
keyboard()
 
if treasure_counter=TREASUREDB then
puts(1,"YOU WON! Congratulations!\n")
{} = wait_key()
elsif grid[y][x]=DEAD_HERO then
puts(1,"YOU PERISHED!\n")
{} = wait_key()
end if