2.4. Ágensek felépítése

2.4.1. Az AgentGame világa (BME)

A játék egy cellákból álló, 60 x 60-as méretű, falakkal határolt játéktéren zajlik. Egy játékban két, egyenként legfeljebb 5-5 fős ágenscsapat vesz részt. Az ágensek célja a pályán található ennivaló elfogyasztásával a saját energiájukat növelni úgy, hogy a játék végén a csapatuk összesített energiája szignifikánsan több legyen az ellenfélnél. A játék döntetlen, ha a második helyezett csapat energiája több mint a nyertes csapat energiájának 85%-a.

Csapatok

A játék elején mindkét csapat azonosan 20 000 egység energiával rendelkezik, mely energia a csapattagok között egyenletesen kerül elosztásra, vagyis egy kevesebb tagot számláló csapat tagjai a játék kezdetén egyenként erősebbek.

Saját ágensek

Az ágensek a következő információk birtokában működnek. Az aktuális játékban tudják a virtuális időt (az aktuális kör sorszámát). Saját magukról tudják a nevüket, a csapatukat, az energiaszintjüket, saját pozíciójukat, orientációjukat és azt, hogy éppen vízben állnak-e (a víz hatásáról lásd a 2.5. fejezetet). Ezen felül ismerik a csapattársaik nevét, tehát tudnak nekik azok helyzetétől függetlenül üzeneteket küldeni. Az ágensek érzékelik a látóterükbe kerülő más ágenseket, tudják azok távolságát, azonosító számát, csapatát, energiaszintjét, pozícióját és orientációját. A látóterükben található ennivalónak ismerik a pozícióját és értékét. Az ágensek látótávolsága 10 cella, a látótér alakját a jobb oldali ábra szemlélteti. Ezen információk alapján az ágensek az alábbi cselekvések közül választhatnak:

  • várakozás – nem kerül energiába

  • lépés tetszőleges oldalszomszédos cellára az ágens orientációjától függetlenül (átlósan, illetve ellenfél ágens által elfoglalt cellára nem lehet lépni) – 5 egység energia

  • fordulás tetszőleges irányba – 2 egység energia

  • evés – ha az ágens éppen ennivalón áll, körönként legfeljebb 200 egységet fogyaszthat, amivel közvetlenül növeli saját energiáját

  • energiaátadás – két azonos csapatba tartozó ágens azonos cellán tartózkodva 5% veszteség mellett tud egymásnak energiát átadni (tehát a fogadó ágensnél a küldő ágens energiacsökkenésének csak 95%-a íródik jóvá).

  • támadás – az ágens 300 egység energia feláldozásával megtámadhat egy másik (éppen a látóterében tartózkodó) nála gyengébb ágenst, mely ilyenkor 100 egység energiát veszít, illetve eredeti pozíciójához képest 10 egység távolságra ellökődik a támadó ágenssel ellentétes irányba. Támadás során nem lehet az ágenseket kilökni a pályáról, illetve olyan pozícióba se kerülhetnek, ahova egyébként nem léphetnének (például ellenséges ágens által elfoglalt cellára): amennyiben a lökés hatására az ágens egy ilyen tiltott cellára kerülne, akkor a tiltott cella egyik szomszédjára kerül.

A fenti cselekvésektől függetlenül az ágensek minden körben korlátlan számban küldhetnek üzeneteket egymásnak, illetve automatikusan fogadják egymás üzeneteit. A kommunikációs cselekvések mellett azonban minden körben kell szerepelnie pontosan egy cselekvésnek a fenti listából: ha az ágens az adott körben semmit nem kíván tenni, akkor a várakozás cselekvést kell végrehajtania. Az ágensek a játék kezdetén a pálya egyik sarkából indulnak. A játéknak 10 000 kör után van vége. Minden körben minden ágens köteles a fenti cselekvések közül pontosan egyet végrehajtani.

Az az ágens, amelyik bármely körben 10 másodpercen belül nem cselekszik, lefagyottnak számít, ezért az adott játék véget ér. Ha egy csapat számítási ideje (a tagjainak összeadott számítási ideje) a 180 másodpercet meghaladja a játék szintén véget ér. Ezekben az esetekben a vétkes csapat pontszáma nullázódik, míg az ellenfél aktuális pontszáma megmarad. A fenti időkeretek alatt végezhető számítások mennyisége természetesen hardverfüggő – a korlátok tekintetében referencia rendszernek a hivatalos beadó rendszer számít.

1. ábra - Saját ágensek
Saját ágensek

Ellenséges ágensek

Az ellenfél csapatába tartozó ágensek célja szintén minél több energiát gyűjteni az ennivaló elfogyasztásával. A különböző csapatba tartozó ágensek nem tartózkodhatnak azonos cellákon, így ha egy ágens egy ennivalóra ráállt és azt éppen eszi, akkor az ellenfél ágensei az ennivalóhoz csak akkor férnek hozzá, ha az éppen fogyasztó ágenst egy támadással félrelökik. Csapattagok tartózkodhatnak azonos cellán, így előfordulhat, hogy egy csapatból egyszerre több ágens is párhuzamosan fogyasztja az ennivalót. Minden megtámadott ágens a támadást követően érzékeli a támadója azonosítóját illetve pozícióját még akkor is, ha a támadó végig a látóterén kívül helyezkedett el.

A játék során bár technikailag adott a lehetőség az ellenséges ágenseknek üzenetet küldeni (célirányosan címzetten vagy broadcast címzéssel) azonban a játékban az ellenféllel minden kommunikáció tilos!

2. ábra - Ellenfél ágens
Ellenfél ágens

Az ennivaló

A pályán egyszerre 4 darab ennivaló található. Az ennivalók addig maradnak egy adott pozícióban, amíg egy ágens el nem fogyasztja őket, vagy meg nem romlanak. Az olyan ennivaló romlik magától, amin egy ágens tartózkodik: ilyenkor értéke körönként 50 egységgel csökken (természetesen azon felül, amit az adott ágensek esetleg megesznek belőle).

3. ábra - Ennivaló
Ennivaló

Az elfogyasztott vagy teljesen megromlott ennivaló helyett azonnal új ennivaló jelenik meg valahol a pályán. Az új ennivaló értéke 300 és 1200 egység között egyenletes eloszlású véletlen változóként sorsolódik. A játék indulásakor az első négy ennivaló teljesen véletlenül kerül a pályán elhelyezésre. Ezt követően minden elfogyasztott ennivaló a többi, még meglévő ennivaló értéke alapján a következő képlet alapján generálódik:

x_új=[(x_régi1+x_régi2+x_régi3)*s_x+r_x ] mod 60

A képletben az "új" ennivaló x_új koordinátája a következő módon számítódik: másik három még a pályán lévő "régi" ennivaló x_régi koordinátáinak összegét az s_x skálázó faktorral felskálázzuk, majd hozzáadunk egy véletlen r_x értéket. Az így kapott összegnek a pálya szélességével képzett maradéka lesz az új koordináta. Az s_x skálázó faktor a játék elején rögzített, egyenletes eloszlású véletlen érték 10 és 90 között. Az r_x értéke -5 és +5 közötti egyenletes eloszlású és minden ennivaló generáláskor új véletlen értéket vesz fel. Az Y koordináta számítása teljesen azonos elvek alapján történik a többi ennivaló y_régi koordinátáinak összegét felhasználva, egy szintén a játék elején generált és rögzített s_y skálázó faktor, illetve egy minden számításkor újragenerált r_y zajtényező felhasználásával.

Víz a pályán

A játék kezdetén elhelyezésre kerül a pályán 4 vízzel elöntött zóna, melyek együtt a játéktér közelítőleg 4%-át fedik le. A vizes zónák alakja téglalap, elhelyezkedésük és oldalaik mérete minden játékban más, véletlenül generált értékek függvényeként határozódik meg. A vízben tartózkodó ágens mozgása és forgása az alaphelyzeti energiához képest 15-szörös költséggel jár. A többi cselekvés költségét a víz nem befolyásolja. Az ágensek nem látják előre a látóterükben található vizet, mindössze akkor érzékelik azt, ha már vizes cellán tartózkodnak.

4. ábra - Víz a pályán
Víz a pályán

A Jason keretrendszer

Az AgentGame verseny világa a BME-MIT saját fejlesztéseként egy ágenskörnyezetként került megvalósításra a Jason nevű, Java alapú reaktív tervkészítő és ágens modellező keretrendszeren belül. A Jason a gyakorlatban egy AgentSpeak interpreter és egy környezet szimulátor együttesének tekinthető. Az AgentSpeak egy nyelv, melynek segítségével az ágensek programja tervek alakjában definiálható, míg az AgentGame a világot definiáló Java nyelvű környezet.

5. ábra - Az Jason főablaka
Az Jason főablaka

A Jason nagy előnye, hogy rugalmasan bővíthető Java nyelven, így lehetőség van tisztán AgentSpeak nyelv használatára, az AgentSpeak részleges kibővítésére Java nyelven, vagy extrém esetben igen minimális AgentSpeak használatával szinte kizárólag Java implementáció létrehozására.

A Jason a következő fájlok alapján dolgozik:

  • a szimulálandó rendszert egy .mas2j kiterjesztésű fájl definiálja

  • a .mas2j fájl hivatkozik egy környezetre ("environement"), amit Java forrásfájlok alakjában kell elérhetővé tenni

  • a .mas2j fájl felsorolja az ágenseket ("agents"), melyeknek az adott elérési úton ("aslSourcePath") .asl kiterjesztésű fájlokban, AgentSpeak nyelven kell definiálni

  • a .asl fájlok használhatnak az AgentSpeak szintaxisának megfelelően saját fejlesztésű "internal action" parancsokra, melyeknek szintén java forráskód formájában kell elérhetőnek lenniük

A Jason használata

A Jason lehetővé teszi a különböző forrásfájlok szerkesztését, illetve szükség esetén elvégzi azok fordítását is. A .mas2j fájl betöltését követően a normál futtatást az ablak jobb alsó régiójában található (az Eclipse-ből esetleg már ismert) zöld háromszög gombbal lehet elindítani (lásd a lenti ábrán a piros keret bal oldalán).

6. ábra - Futtatás és hibakeresés
Futtatás és hibakeresés

A futtatáson kívül lehetőség van a Jason-t hibakereső módban indítani. Ehhez a futtatás gombtól jobbra elhelyezkedő gombbal kell indítani a szimulációt. Ilyenkor megjelenik egy extra ablak, melyben az ágensek mentális állapotát lehet nyomon követni, illetve a szimulációt lehet körönként léptetni.

7. ábra - A Jason hibakereső támogató felülete
A Jason hibakereső támogató felülete

A Jason hibakereső felületével kapcsolatban meg kell jegyeznünk, hogy az korábban már felszínre kerültek teljesítményproblémák a debug ablakkal kapcsolatban: mivel a debug felület az ágensek állapotát visszakereshető módon rögzíti (az időben visszafelé az alsó csúszkával lehet lépkedni), ezért viszonylag kis számú számítási ciklus után is igen megnő a debug ablak memóriaigénye, és egy idő után használhatatlanul lassúvá válik. E probléma kezelésére született idén a Java bővíthetőséget is demonstráló Java mintágens (simple_debug ágens a letölthető csomagban). A simple_debug ágensben használt Java internal action egy hasonló ablakot jelenít meg, melyben az ágens egy lépéssel korábbi (tehát a legutóbbi cselekvését megelőző) mentális állapota (érzékelése és hiedelembázisa) jelenik meg.

A feladat

A verseny keretein belül az AgentGame keretrendszerben működőképes ágenscsapatot kell létrehozni: a csapat legfeljebb 5 ágensből állhat, akik hatékonyan képesek (együtt)működni az AgentGame világában. A csapatban 1 és 5 között tetszőleges számú ágens szerepelhet. Az ágensek lehetnek mind azonos architektúrájúak (lehet azonos a forráskódjuk), vagy állhat mindegyik mögött különböző implementáció is.

1. táblázat - Az ágensek érzékelése

Érzékelés

Leírás

Paraméterek

myname(N)

Az ágens neve.

N - az ágens neve a szimulációban.

myid(N)*

Az ágens azonosítója.

N - az ágens numerikus azonosítója a szimulációban.

myteam(N)*

Az ágens csapatának azonosítója.

N - az ágens csapatának numerikus azonosítója.

mypos(X,Y)

Az ágens pillanatnyi pozíciója.

X - az x koordináta Y - az y koordináta

inwater

Az ágens pillanatnyilag vízben van.

mydir(D)

Az ágens pillanatnyi látási orientációja.

D - az orientáció (0 = fel; 1 = jobbra; 2 = le; 3 = balra)

myenergy(E)

Az ágens pillanatnyi energiája

E - az ágens energiaszintje

teammates([T])

Az ágens csapatársai

T - Az ágens csapatársainak listája, a csapattársak nevei (üzenetküldéshez a címzettek)

time(T)

Az aktuális (virtuális) idő a játékon belül

T - az idő minden lépésben növekvő értéke

lastattacker([Id,X,Y])

Az ágenst legutóbb megtámadó másik ágens lekérdezése.

Id - a támadó ágens azonosítója X - a támadó x koordinátája a támadás idején Y - a támadó y koordinátája a támadás idején

food([[D,V,X,Y],...])

Az által látott ennivalók listája.

D - az adott étel távolsága az ágenstől (lépésben) V - az étel értéke X - az étel x koordinátája Y - az étel y koordinátája

agent([[D,Id,T,E,X,Y,O],...])

Az ágens által látott más ágensek listája.

D - a másik ágens távolsága Id - a másik ágens azonosítója T - a másik ágens csapat azonosítója E - a másik ágens energiája X - a másik ágens x koordinátája Y - a másik ágens y koordinátája O - a másik ágens látási orientációja

myteamtimeleft(T)

Az ágens csapata számára a 180 másodperces számítási idő keretből hátralévő idő.

T - a hátralevő idő értéke másodpercben.

teammate(Id,Name)

Az ágens minden csapattársára rendelkezik egy ilyen érzékeléssel, mely a csapattárs (érzékelésekkor és cselekvéskor használt) numerikus azonosítóját és (az üzenetküldéshez használható) nevét kapcsolja össze.

Id - a csapattárs numerikus azonosítója Name - a csapattárs neve


2. táblázat - Az ágensek lehetséges cselekvései

Cselekvés

Leírás

Költség

wait()

Várakozás, az adott körben az ágens nem tesz semmilyen külső cselekvést - számításokat természetesen végezhet ezt megelőzően.

0

turn(D)

Az ágens a D irányba fordul.

2

step(D)

Az ágens a D irányba tesz egy lépést.

5

eat()

Az ágens eszik a pillanatnyi pozícióján található ennivalóból. Körönként legfeljebb 200 egységet tud egy ágens megenni.

0

transfer(T,A)

Az ágens a vele azonos cellán tartózkodó T csapattársának átad A (5% tranzakciós veszteséggel csökkentett) energiát.

0

attack(Id)

Az ágens látóterében tartózkodó Id azonosítójú ágens megtámadása. A támadás akkor sikeres, ha a támadó látja az ellenfelet és több energiája van annál.

300

setlabel(label)

Az ágens által a grafikus felületen megjelenített szám azonosító lecserélése a label értékére. Ezáltal a grafikus felületen egyértelműen azonosíthatók az egyes különböző (forráskódú vagy funkciójú) ágensek.

0

setcolor(R,G,B)

Az ágenshez a grafikus felületen rendelt szín lecserélése az R, G és B paraméterekben adott RGB kódú színre. Az ágensek vizuális azonosíthatóságának segítésén kívül más gyakorlati hatása (a setlabel-hez hasonlóan) nincs.

0


Az ágensek elnevezése

Az ágensek csapatokba sorolása a nevük alapján történik. Az ágensek nevének két részből kell állnia, mely két részt az alulvonás ("_") karakter választja el. A név első fele a csapat neve, a második fele pedig az ágenst azonosítja. A név második fele elhagyható (ahogy például a "simple_" ágens esetében is történik), ilyenkor az ágensek egy automatikus sorszámot kapnak a nevük végére a keretrendszertől.

A megoldás menete

A minden szükséges anyag letölthető a verseny honlapjáról. Először a Jason keretrendszert kell letölteni majd ezt követően az AgentGame környezetet kell működőképes állapotba hozni (lásd a Telepítési útmutatót). Az AgentGame környezet tartalmaz mindent, ami a megoldás alapjául szolgálhat: található benne két mintapélda, és a minta ágensek a telepítést követően azonnal kipróbálhatóak.

A környezet beüzemelését követően javasolt a mintapéldákból kiindulni, és azok kódjának módosításával, kiegészítésével egyre magasabb intelligenciával rendelkező ágenseket létrehozni. A beadó rendszerben az elkészült ágensek (csak .asl vagy .asl és .java) forráskódját kell beadni. A kiértékelő rendszer a beadott csapatokat a szerveren automatizáltan minden más csapattal összepárosít és a játékok eredménye szintén a beadó rendszerben érhető el.

A szimulátor

A szimulátor futtatásához először a Jason-t kell elindítani. Ezt követően a mas2j fájl (például a keretrendszerrel együtt letöltött AgentGame.mas2j fájl) megnyitása után a szimulátort a Jason futtatás gombjával indíthatjuk.

A szimulátor főablaka

A szimulátor legfontosabb grafikus felülete a főablak. Ennek az ablaknak a jobb oldalán látható a játéktér, melyen a játék folyamán az összes fontos esemény nyomon követhető:

  • A különböző ágensek a csapatuknak megfelelő szín (piros / zöld) különböző árnyalataiban jelennek meg

  • Az ágensek előtt látható az egyes ágensek háromszög alakú látótere.

  • Az ennivaló lila színnel jelenik meg, és ahogy értéke csökken, úgy halványodik egyre inkább el.

  • A vízzel teli cellákat kék szín jelöli.

8. ábra - A szimulátor főablaka
A szimulátor főablaka

A jobb oldalon egymás alatt a következő információk láthatóak:

  • A legfelső részen az egyes ágensek energiaszintje látszik. Az oszlopok színe megegyezik a hozzájuk tartozó ágens színével a pályán.

  • Az oszlopok alatt az ágensek numerikus azonosítója szerepel: ezt a Jason generálja, amikor az ágensek futtatását indítja, de az ágens megváltoztathatja az itt látszó címkét a setlabel cselekvéssel. Az ágensek megjelölhetők a címkéjükre kattintással: ilyenkor kék árnyalatúra vált a színük mindaddig, amíg egy újabb kattintással ez a kijelölés meg nem szűnik. Maguk az ágensek megváltoztathatják saját színüket a setcolor cselekvéssel.

  • A következő blokkban a csapatok összesített energiája látszik. A két oszlopgrafikon között egy kis vízszintes vonal jelzi a játékszabályokban definiált döntetlen határát: amíg a vesztes csapat energiája a jel felett van, addig a játék eredménye döntetlen.

  • A panel alsó részén látható a játékból eltelt körök száma és grafikusan a hátralevő körök aránya.

  • A panel legalsó részén kerültek elhelyezésre a szimulációt szüneteltető, lépésenként futtató, és automatikusan futtató gombok, valamint a sebesség öt lépésben állítását lehetővé tevő csíkok.

MAS Console

A MAS Console a Jason saját ablaka, de a szimulátor is megjelenít itt üzeneteket. Az ágensek a print belső utasítással tudnak szöveges üzeneteket kiírni, ami a hibakeresésük során igen hasznos lehet.

9. ábra - A szimulátor főablaka
A szimulátor főablaka

A MAS Console ablakában lehetőség van szimuláció közben is aktiválni a debug módot, vagy megtekinteni az éppen futó ágensek forráskódját. A MAS Console bezárásakor a Jason automatikusan megszakítja a szimuláció futását.

Grafikonok ablak

Amennyiben a szimulátor konfigurációja engedélyezi a játék végén a grafikonok megjelenítését, akkor az utolsó kör után megjelenő, az alábbihoz hasonló ablakban látható az ágensek illetve a csapatok összenergiájának alakulása.

10. ábra - A grafikonok ablak
A grafikonok ablak

A szimulátor konfigurálása

A szimulátort a mas2j fájlban a GameEnvironment-nek paraméterkén átadott konfigurációs fájl segítségével lehet konfigurálni. Ez a fájl alapértelmezés szerint az AgentGame.conf fájl, mely két fő részre bontható.

A fájl első felében a szimulátor gyakorlati működését meghatározó beállítások kaptak helyet, melyeket alább részletezünk. A fájl második felében a játékkal kapcsolatos beállítások szerepelnek (például cselekvések költsége, pálya mérete, stb.), melyeket a verseny keretén belül nincs értelme módosítani, ezért jelentésükre (a fájlban elhelyezett kommenteknél bővebben) nem térünk ki.

A szimulátor fontosabb testreszabható beállításai:

  • Grafikus felület: letiltható a grafikus felület (ilyenkor a szimuláció gyorsabban fut, a futással kapcsolatos adatok pedig a különböző logfájlokból olvashatók ki - lásd később), méretezhető a főablak és beállítható az alapértelmezett futási sebesség.

  • CSV naplózás: engedélyezhető az ágensek és a csapatok energiájának bizonyos időközönként Excel-lel beolvasható .csv fájlba exportálása.

  • Játékmenet naplózása: a játék minden eseménye rögzíthető egy .log.ag fájlba, melyet a Lejátszó később vissza tud játszani az ágensek forráskódja és a Jason nélküli számítógépen is.

  • Grafikonok: kikapcsolható a játék végén a grafikonok megjelenítése vagy bekapcsolható a grafikonok automatikus fájlba mentése, illetve állítható a felbontás.

  • Eredmények naplózása: a szimulátor egy szöveges fájlban rögzíti minden játék eredményét, illetve itt kerülnek feltüntetésre az ágensek és a csapatok összesített futási idői is.

  • Watchdog: bekapcsolható az alapértelmezetten tiltott watchdog, ami a kiértékelő szerveren engedélyezett lesz. A watchdog szerepe, hogy a bizonyos ideig nem cselekvő ágensek, vagy futási idejükből kicsúszó csapatok esetén megszakítja a szimulációt és a hibázó csapatot vesztesnek nyilvánítja. Ez a funkció lefagyást okozhat, ha a Jason debug módban fut, mivel ilyenkor a watchdog nem érzékeli az ágensek futását, ezért csak normál futtatás esetén tanácsos bekapcsolni.

A konfigurációs fájl bőven kommentezett, ezért az egyes beállítások használata a fájl alapján értelemszerű.

Mintapéldák

A keretrendszerrel együtt három mintaágens érkezik, melyek a gyakorlatban alig térnek el egymástól. Az alap ágens a simple_ nevet viseli. A név utáni aláhúzás karakter a "csapatnév_ágensnév" ágens elnevezési konvenciónak megfelelően azt eredményezi, hogy a csapat neve simple lesz, az ágensek pedig simple_1, simple_2, stb. neveken jönnek létre.

A második ágens neptun néven szerepel és kódja teljesen azonos a simple ágensével. Utóbbi célja, hogy a szimulátor azonnal kipróbálható legyen két csapattal. A második csapat tagjai az elnevezési konvenció alapján neptun_1, neptun_2, stb. nevet kapnak.

A harmadik ágens a simple apró módosításával készült, és a simple_debug nevet viseli. Célja kettős: egyrészt demonstrálja az AgentSpeak Java alapú kiegészíthetőségének módját, másrészt egyszerűbb, de lefagyásra kevésbé hajlamos hibakereső felületet ad az ágensnek, mint a Jason beépített hibakereső ablaka.

A simple ágens

simple ágens koncepciója igen egyszerű, mégis viszonylag sok aspektusát lefedi a szükséges AgentSpeak programozásnak. Az ágens alapvetően a pályán bolyong: arra megy, amerre éppen néz egészen addig, amíg falnak nem megy, ahol aztán visszafordul. Ezen kívül 5% valószínűséggel menetközben is elfordul, aminek hatására mozgása tényleg barangolás jellegű.

Ha az ágens meglát egy ennivalót, akkor azt célként tűzi ki magának és odamegy megenni. Ha az ágens ennivalóra lép, akkor azt ösztönösen megeszi. Ha az ágensnek elfogy az energiája, akkor a továbbiakban a várakozás cselekvést hajtja végre.

Az ágens programja számos ponton továbbfejleszthető illetve szuboptimális, azonban célja nem is versenyképes résztvevőként szerepelni a játékban. Szerepe elsősorban egy egyszerű működőképes ágens példájául szolgálni, illetve a hallgatói fejlesztések kiindulási alapját nyújtani. Így tehát első kísérletezésként javasolt a simple ágenssel kód tekintetében teljesen azonos neptun ágenst szerkeszteni és módosítani, majd az eredményt a módosítás nélküli simple csapattal összevetni!

Az ágens programja számos megjegyzés sorral indul. Megjegyzéseket mind /* és */ karakterek közé, mind a sor elejére elhelyezett // jel mögé írhatunk.

/**************************************************************************

AgentGame v2.0.

Copyright Peter Eredics (BUTE-DMIS) 2010.

simple.asl - Simple agent running for the closest food it sees

**************************************************************************/

///////////////////////////////////////////////////////////////////////////

// INIT

///////////////////////////////////////////////////////////////////////////

// No initial beliefs yet

///////////////////////////////////////////////////////////////////////////

// Being out of energy

///////////////////////////////////////////////////////////////////////////

+time(_) : myenergy(Energy) & Energy<25 <-

wait.

Az ágens kódjának első terve arról gondoskodik, hogy amennyiben az ágensnek 25 egységnél kevesebb az energiája, akkor ne tegyen semmit, pontosabban a várakozás cselekvést hajtsa végre. A terv felépítése a következő:

  • +time(_) jelentése, hogy a tervet a time hiedelem megjelenése triggereli tetszőleges paraméterezéssel. A time hiedelmet a szimulátor minden körben érzékelésként adja át az ágensnek.

  • : myenergy(Energy) & Energy<25 jelentése, hogy az ágens saját energiáját Energy értékűnek hiszi, és ez az Energy értéke 25-nél kevesebb

  • <- wait. jelentése, hogy amennyiben az adott terv aktiválódik, és a feltételei teljesülnek (tehát ez a terv kerül végrehajtásra), akkor a wait cselekvést kell az ágensnek végrehajtania.

Mivel az ágens szinte minden cselekvését a +time(_) triggereli és mivel ez a terv szerepel először az ágens forráskódjában, ezért ez tekinthető a legmagasabb prioritású tervnek, hiszen ha a feltételei teljesülnek (az energia kevesebb mint 25), akkor mindenképpen ez hajtódik végre.

A következő blokkban az evéssel kapcsolatos tervek szerepelnek. Az első terv arról gondoskodik, hogy amennyiben az ágens eat_at_my_pos célja meghiúsul (enni szeretne ott, ahol már nincs ennivaló), akkor a Jason ne jelezzen hibát (ha az eredeti terv meghiúsult, akkor az itt visszaadott true érték miatt a Jason végül sikeresnek értékeli a cselekvést - ami az adott helyzetben (amikor tényleg nincs mit megenni az adott pozíción) elfogadható működés.

A második terv +!eat_at_my_pos bevezetője akkor aktiválódik, ha az ágens felveszi a céljai közé az eat_at_my_pos célt - lásd később a kódban, amikor az ágens ennivalót érzékel magától 0 távolságra.

///////////////////////////////////////////////////////////////////////////

// Eating related things

///////////////////////////////////////////////////////////////////////////

-!eat_at_my_pos <-

true.

+!eat_at_my_pos <- eat.

A következő részben a mozgással kapcsolatos tennivalók kaptak helyet. Először is az ágensnek néha véletlen irányba kell fordulnia, amit a .random(R) beépített cselekvéssel hajt végre, aminek következtében az R változó egy 0-1 közötti véletlen értéket kap. Ezután az R*4 értékű paraméterrel végrehajtva a turn cselekvést, pont a kívánt célt értjük el.

///////////////////////////////////////////////////////////////////////////

// Moving

///////////////////////////////////////////////////////////////////////////

// First we define what a random turn is, and how to make it:

+!randomTurn <-

.random(R);

turn(R*4).

A következő terv arról gondoskodik, hogy ha az ágens korábban úgy döntött, hogy a következő lépésben véletlenszerű irányba fordul, akkor ez történjen meg. Ezt a döntését az ágens egy hiedelem, a scheduled_random_turn felvételével jelezte a tudásbázisában. A terv törzsében először eltávolítjuk ezt a hiedelmet (hogy az ágens ne forogjon végtelen ciklusban), majd áttérünk a randomTurn terv végrehajtására.

// If a random turn was scheduled before, execute it!

+time(_) : scheduled_random_turn <-

-scheduled_random_turn;

!randomTurn.

A következő blokk arról gondoskodik, ha egy ágens valamilyen okból nem képes az általa választott irányba haladni (az ilyen külső okot a Jason a step cselekvés sikertelenségével jelzi, ami egyben a !move terv meghiúsulását is jelenti, ami a szintaxis alapján a -!move(_)triggert jelenti). Ilyenkor ha volt kinézett ennivaló cél, akkor azt az ágens elveti és véletlen irányba fordul.

// If we are unable to move (our last position is the same as our position

// now),forget the target and schedule a random turn to avoid geting

// stucked together with an agent moving from the opposite direction

-!move(_) <-

-target(_,_);

+scheduled_random_turn.

Minden egyéb esetben a mozgás nem bonyolult dolog: végre kell hajtani a megfelelő irányba a step cselekvést, és kész is:

// If we are not stucked, we just have to keep moving

+!move(Dir) <-

step(Dir).

A következő két terv az evéssel kapcsolatos. Az első terv feltétel részében az szerepel, hogy az ágens által érzékelt ennivalók (a food érzékelés paramétere, a Food lista tartalma) közül a legközelebbi (a .min beépített utasítás az első elem alapján rendezi a listaelemeket) 0 távolságra van. Ilyenkor el kell felejteni a korábbi célt ahova az ágens tartott (ami az esetek többségében egyébkén a jelenlegi pozíció), és enni kell!

///////////////////////////////////////////////////////////////////////////

// Time triggered "intelligence" of the agent

///////////////////////////////////////////////////////////////////////////

// Is there food at my position?

// - the list of food objects I see is Food

// - each food object is represented in the list in the form of

// [distance_from_me, food_value, position_x, position_y]

// - the .min internal function chooses the minimal value in Food

// - the food objects (=lists) are ordered by their first element (=distance)

// - the "[0,..." means that the distance of the closest food is zero

// If yes, let's eat it and forget about it as a target!

+time(_): food(Food) & .min(Food,[0,V,X,Y]) <-

-target(_,_);

!eat_at_my_pos.

Ezután azt a helyzetet kell kezelnünk, hogy az ágens elérte a célnak választott ennivalót (target), de ott már nincs ennivaló. Ha lenne ugyanis, akkor az eggyel ezelőtti terv lenne aktív: ez a második terv csak akkor aktiválódik, ha az előző nem tudott, vagyis az ágens a target pozíción van, de ott nem érzékel magától 0 távolságra ennivalót. Ilyenkor a célról le kell mondani és az ágens továbbhalad abba az irányba, amerre néz (a mydir érzékelés segítségével határozza meg saját nézési irányát).

// If we get at the target cell, but there is no food there anymore

// (because if there would be a food, the plan above would have been

// executed) let's sadly forget about our target.

+time(_): target(X,Y) & mypos(X,Y) & mydir(Dir) <-

-target(_,_);

!move(Dir).

A következő négy terv arról gondoskodik, hogy az ágens abba az irányba haladjon, amerre a célja van. Érdemes megjegyezni, hogy egy egyszerű saját Java cselekvés segítségével (amely a pozíció és a cél ismeretében visszaadná a szükséges irányt) ezen a ponton a négy terv helyett elég lenne egy is - tehát ez tipikusan olyan pont, ahol az AgentSpeak gyengeségét Javából lehet csökkenteni.

// If we have a target different from our current position, let's move

// towards it. (Note: if our position would be the target position, one of

// the plans above would have been selected earlier.)

+time(_): target(Fx,Fy) & mypos(Mx,My) & Fx>Mx <-

!move(1).

+time(_): target(Fx,Fy) & mypos(Mx,My) & Fx

 !move(3).

+time(_): target(Fx,Fy) & mypos(Mx,My) & Fy>My <-

!move(2).

+time(_): target(Fx,Fy) & mypos(Mx,My) & Fy

 !move(0).

Az alábbi blokk azért felelős, hogy ha az ágensnek nincs már kijelölt célja (hiszen egy korábbi terv se aktivizálódott), akkor amennyiben ennivalók vannak a látóterében, akkor a legközelebbit jelölje ki célnak (vegye fel hiedelmei közé a target(Fx,Fy)-t).

// If we see some food and we had no target before, we select the closest

// food and move towards it. (Note: if we would have a target, one of the

// plans above would fit it, thus here we are sure that we had no plans

// earlier.

+time(_): food(Food) & .min(Food,[_,_,Fx,Fy]) & mydir(D) <-

+target(Fx,Fy);

!move(D).

A forráskód utolsó blokkja felelős azért, hogy az ágens véletlenszerűen bolyongjon. Ezek a tervek ismét csak akkor aktiválódnak, ha korábban egy terv se illeszkedett, vagyis az ágens nem áll ennivalón, nincs kinézett ennivaló célja, és nem is lát potenciális célként kitűzhető ennivalót maga előtt. Ilyenkor 5% valószínűséggel véletlen irányba halad az ágens, illetve addig halad előre, amíg falnak nem ütközik, ahol aztán visszafordul.

///////////////////////////////////////////////////////////////////////////

// Time triggered random roaming of the agent

///////////////////////////////////////////////////////////////////////////

// The rules bellow are executed only, if the agent has no target and it

// can't see any food right now.

// With a 5% probability we turn into a random direction

+time(_): .random(P) & P>0.95 <-

!randomTurn.

// Otherwise we should just move forward...

+time(_): mypos(X,Y) & mydir(0) & Y>0<-

!move(0).

+time(_): mypos(X,Y) & mydir(1) & X<59 <-

!move(1).

+time(_): mypos(X,Y) & mydir(2) & Y<59 <-

!move(2).

+time(_): mypos(X,Y) & mydir(3) & X>0 <-

!move(3).

// ... and turn back when reaching the wall

+time(_): mydir(D) & D < 2 <-

turn(D+2).

+time(_): mydir(D) & D >= 2 <-

turn(D-2).

A simple_debug ágens

simple_debug ágens célja kettős: egyrészt mintául kíván szolgálni saját Java belső cselekvések készítéséhez, másrészt univerzálisan beépíthető hibakereső felületet kíván nyújtani minden hallgatói ágens számára. Az ágens AgentSpeak forráskódja szinte teljesen azonos a simple ágensével. Az egyetlen eltérés, hogy minden olyan helyen, ahol az ágens fizikai cselekvést hajt végre (például lép, fordul, eszik, stb.), szerepel egy további mentális cselekvés is, méghozzá a debug.DebugAction nevet viselő.

A debug.DebugAction

debug.DebugAction a saját fejlesztésű belső utasítások mintapéldája. Forráskódja a debug package-ben, a DebugAction.java fájlban található. A debug package név saját választás, tetszőlegesen más is lehetne. A fájlokat az src/java/[package_név] könyvtárba kell elhelyezni, vagyis jelen esetben a DebugAction.java fájl a src/java/debug könyvtárba került. Kicsit zavaró lehet, hogy a környezet forráskódja is az src/java mappában található, de ettől függetlenül tetszőleges package-t ezáltal almappát lehet ebben a könyvtárban tetszés szerint létrehozni.

A src/java/debug könyvtár két Java forrásfájlt tartalmaz. Az első a DebugAction.java, mely magát a saját belső utasítást implementálja:

// A saját definiálású package

package debug;

// Szükséges importok a Jason-ból

import jason.asSemantics.*;

import jason.asSyntax.*;

// Maga a saját osztály, a Jason DefaultInternalAction osztályából

// származtatva

public class DebugAction extends DefaultInternalAction{

// Serial a sorosíthatósághoz - nincs gyakorlati jelentősége

private static final long serialVersionUID = 4L;

// A grafikus felület (működését lásd lent)

DebugFrame debugFrame;

// A konstruktor nem tesz mást, mint inicializálja a GUI-t: a

// konstruktor csak az első hívás előtt fut le, a továbbiakban az

// objektum a memóriában marad, tehát lehet magának a belső

// cselekvésnek "állapota", az ebben az osztályban rögzített

// változók segítségével.

public DebugAction() {

debugFrame = new DebugFrame();

}

// Ezt a függvényt hívja a Jason, ha egy ágens ezt az utasítást

// hajtja végre.

public Object execute(TransitionSystem ts, final Unifier un, final

Term[] arg) throws Exception {

// Itt frissítjük a GUI-t - a ts feldolgozását lásd később.

debugFrame.add(ts);

// Ez a belső utasítás mindig sikerrel tér vissza, így nincs

// szükség hibakezelésre az ASL kódban.

return true;

}

}

A debug.DebugFrame

A grafikus felület egy egyszerű JFrame-ből származtatott ablak.

11. ábra - Az ágens grafikus felülete
Az ágens grafikus felülete

A forráskód legnagyobb része a grafikus komponensek létrehozásával és frissítésével foglalkozik. Ezen kívül mindössze két fontos részlet található a forráskódban. Az első a DebugAction által hívott debugFrame.add():

public void add(TransitionSystem ts) {

// Add current state to the history

history.add(ts.getAg().getBB().toString());

Itt történik a hívó ágens (getAg) tudásbázisának (getBB) szöveggé alakítása. Ezt a szöveget az activateStep függvény a következőképpen értelmezi:

// Load state in text format

String[] array = history.get(stepID).split("\\s");

String Result = "";

// Try to identify data in the text lines

for (int x=0; x<array.length; x++) {

Result = Result + array[x] +"\n";

// Update the GUI with the data found

if (array[x].indexOf("time")==0)

labelTime.setText(

array[x].substring(array[x].indexOf("(")+1,

array[x].indexOf(")")));

else if (array[x].indexOf("mypos")==0)

labelPos.setText(

array[x].substring(array[x].indexOf("(")+1,

array[x].indexOf(")")));

else if (array[x].indexOf("mydir")==0)

labelDir.setText(

array[x].substring(array[x].indexOf("(")+1,

array[x].indexOf(")")));

else if (array[x].indexOf("myenergy")==0)

labelEnergy.setText(

array[x].substring(array[x].indexOf("(")+1,

array[x].indexOf(")")));

}

// Load clear text belief base to the text box

textArea.setText(Result);

Néhány kitüntetett információ kiválogatása után végül a teljes szöveg is megjelenik a szöveg boxban.

AgentGame segédanyagok

Ebben a témában egy nagyon jó angol nyelvű könyv áll rendelkezésre:

Ez a könyv első ránézésre kicsit ijesztőnek tűnhet, azonban viszonylag könnyen olvasható, és minden lényeges kérdésre kitér. Az egyes felmerülő kérdések kapcsán következő fejezetek megismerése ajánlott:

  • Bevezetés és ismerkedés: 1. fejezet (Introduction), 3. fejezet (TheJason Agent Programming Language)

  • A Jason működésének mélyebb megértése: 2. fejezet (The BDI Agent Model), 4. fejezet (Jason Interpreter)

  • Ágensek közötti kommunikáció: 6. fejezet (Communication and Interaction)

  • Bővítési lehetőségek Java nyelven: 7.1. fejezet (Defining New Internal Actions)

  • Belső utasítások gyűjteménye: A.3 függelék (Standard Internal Actions)

Az 1-3 fejezetek alapján már készíthető komplex működést produkáló, a játékban sikeres csapat. Egy ilyen csapat a 6. fejezet alapján könnyen bővíthető kommunikációs képességekkel, illetve a 7.1. fejezet igen röviden bevezet a Java bővíthetőség rejtelmeibe.

Telepítés (Windows)

Győződjünk meg róla, hogy rendelkezünk legalább 1.6-os Java fejlesztő és futtatókörnyezettel. Amennyiben nem, először telepítsük ezeket innen:  http://www.oracle.com/technetwork/java/javase/downloads/index.html

Fontos: 64 bites Windows használata esetén is x86-os JDK-ra van szükség a JOGL támogatáshoz!

Töltsük le a Jason rendszer legfrissebb változatát innen:  http://sourceforge.net/projects/jason/files/

Töltsük le az AgentGame rendszert és csomagoljuk ki egy szimpatikus könyvtárba.

A szimulátor a hatékony megjelenítéshez hardveres OpenGL támogatást vesz igénybe. Ennek következtében szükség van a JOGL könyvtár telepítésére. A JOGL könyvtárhoz szükséges fájlok az AgentGame install könyvtárának jogl/win32 almappájában vannak.

Keressünk meg minden telepített JDK verziót a számítógépen (tipikusan a c:\Program Files\java\*jdk* könyvtárakat), és ezeken belül helyezzük el a kicsomagolt .dll fájlokat a \bin, a kicsomaolt jogl.jar fájlt pedig a \lib könyvtárakban.

Keressünk meg minden telepített JRE verziót a számítógépen (tipikusan a c:\Program Files\java\*jre* könyvtárakat), és ezeken belül helyezzük el a kicsomagolt .dll fájlokat a \bin, a kicsomaolt jogl.jar fájlt a \lib\ext könyvtárakban. A jdk könyvtárak is tartalmazhatnak jre alkönyvtárat, ezekbe is kerüljenek be a fájlok!

Az AgentGame az 1.10-es verziótól felfelé JFreeChart komponenseket használ a grafikonok megjelenítéséhez. Az ezekhez szükséges .két jar fájl az AgentGame-et tartalmazó tömörített fájl \install könyvtárában található. Helyezzük őket az előbbi két lépésben meghatározott \lib és \lib\ext könyvtárakba!

Ezt követően indítsuk el a szimulátort a Jason-ból. A futtatásról további információ a szimulátort bemutató fejezetben található.

Megjegyzés: Ha probléma van a pálya kirajzolásával (nem jelenik meg rendesen, exception-t dob a program, stb.), akkor érdemes megkísérelni a grafikus kártya driverének frissítését!

Telepítés (Unix)

Győződjünk meg róla, hogy rendelkezünk 1.6-os Java fejlesztő és futtatókörnyezettel. Amennyiben nem, először telepítsük ezeket: http://www.oracle.com/technetwork/java/javase/downloads/index.html

Töltsük le a Jason rendszer legfrissebb változatát innen: http://sourceforge.net/projects/jason/files/

Töltsük le az AgentGame rendszert és csomagoljuk ki egy szimpatikus könyvtárba.

A szimulátor a hatékony megjelenítéshez hardveres OpenGL támogatást vesz igénybe. Ennek következtében szükség van a JOGL könyvtár telepítésére. Az ehhez szükséges fájlok az AgentGame install könyvtárának jogl/unix almappájában vannak.

Keressünk meg minden telepített JDK verziót a számítógépen, és ezeken belül helyezzük el a jogl .so fájljait a /lib/i386/, a kicsomaolt .jar fájlt a /ext könyvtárakban.

Keressünk meg minden telepített JRE verziót a számítógépen, és ezeken belül helyezzük el a .so fájlokat a /lib/i386/, a jogl.jar fájlt a /lib/ext könyvtárakban. A jdk könyvtárak is tartalmazhatnak jre alkönyvtárat, ezekbe is kerüljenek be a fájlok!

Az AgentGame az 1.10-es verziótól felfelé JFreeChart komponenseket használ a grafikonok megjelenítéséhez. Az ezekhez szükséges .jar fájlok az AgentGame-et tartalmazó tömörített fájl \install könyvtárában találhatók. Helyezzük őket az előbbi két lépésben meghatározott \ext és \lib\ext könyvtárakba!

Ezt követően indítsuk el a szimulátort a Jason-ból. A futtatásról további információ a szimulátort bemutató fejezetben található.

Beadási tudnivalók

A versenybe benevezett csapatok beadása a Beadó rendszeren keresztül történik a verseny megfelelő fordulóját, mint feladatot kiválasztva. A beadás során egyetlen ZIP fájl feltöltését várjuk, melynek tartalmával kapcsolatban a gépi feldolgozás miatt az alábbi szigorú megkötésekkel élünk.

Specifikáció

A ZIP fájl gyökérkönyvtára csak és kizárólag az alábbi három elemet tartalmazhatja:

  1. asl könyvtár

    Ezen a könyvtáron belül kell elhelyezni az ágensek AgentSpeak forráskódját. A forráskód fájloknak csapatnev_*.asl alakúnak kell lenniük. A csapatnév a feladatot beadó hallgatóhoz rendelt alias (megtalálható belépés után a beadó rendszer moduljának fejlécében a név mellett zárójelben). Az asl könyvtár más fájlt nem tartalmazhat! A csapatnév itt és a továbbiakban mindenhol csupa kisbetűvel írandó (tehát az első betű is kisbetű)!

  2. java könyvtár (csak ha van java kiegészítés!)

    A java könyvtár lehet üres (ha nincs Java kiegészítés az ágensekhez), vagy tartalmazhat egyetlen alkönyvtárat, mely alkönyvtár neve a csapatnév ismét csak csupa kisbetűvel. Ezen a néven kell létrehozni a saját java internal action-ök számára package-t az AgentGame src/java könyvtárában. Ezt a package könyvtárat egy az egyben be lehet másolni a beküldött ZIP fájl java könyvtárába!

  3. config.txt fájl

    A config.txt egy egyszerű szöveges fájl. A két csapat config.txt-jéből, illetve a szükséges környezeti beállításokból rakja össze a kiértékelő rendszer a .mas2j fájlt. A config.txt-ben azoknak a soroknak kell szerepelniük, melyek a csapat ágenseit a .mas2j fájlban regisztrálják.

Példa

Tegyük fel, hogy a Beadó rendszerben az "Adamant" aliast kaptuk, és szeretnék beadni a Simple ágenst egy apró saját Java kiegészítéssel megspékelve. Először elkészítjük a saját csapatunkat:

  1. Lemásoljuk az AgentGame src/asl mappájában található simple_.asl fájlt, és átnevezzük adamant_.asl-re.

  2. Készítünk egy új mappát az AgentGame src/java mappájában adamant néven - ezen a néven hozunk létre saját package-t, és ide kerül majd a saját internal action-ünk.

  3. A src/java/adamant könyvtáron belül létrehozzuk a saját internal action-ünk forrásfájljait. Jelen példában egy AlwaysTrue osztálytdefiniáltunk, mely mindig igaz értékkel tér vissza. Package-nek a csapat nevét, az adamant-ot használjuk.

  4. Módosítjuk az adamant_.asl fájlt, hogy a megfelelő helyeken meghívja ezt az internal action-t:

+time(_) : myenergy(Energy) & Energy<25 & adamant.AlwaysTrue <- wait.

  1. Kipróbáljuk a módosított ágenseket a szimulátorban: ehhez az AgentGame.mas2j fájlba beszúrjuk az adamant_ [verbose=0] #5; sort, majd futtatjuk a szimulátort.

Több internal action-t is definiálhatnánk (ezeket mind a src/java/adamant könyvtáron belül), lehetne több ágensünk is (például adamant_master.asl, adamant_slave.asl stb. neveken), de maradjunk az egyszerű példánál és tegyük fel, hogy elégedettek vagyunk az ágensünk működésével. Szeretnénk beadni a megoldást. Ehhez a következőket kell tennünk:

  1. Készítsünk elő egy tetszőleges üres mappát (pl. c:\temp)!

  2. Hozzunk létre ezen belül egy asl almappát, és másoljuk ebbe bele az ágensek .asl fájljait. (Tehát lesz egy c:\temp\asl mappánk, és azon belül egy c:\temp\adamant_.asl fájlunk.)

  3. Hozzunk létre az eredeti mappán belül egy java mappát és másoljuk bele az AgentGame src/java/adamant könyvtárát! (Magát a könyvtárat is másoljuk, ne csak a tartalmát! Így tehát lesz egy c:\temp\java\adamant könyvtárunk, illetve egy c:\temp\java\adamant\AlwaysTrue.java fájlunk.)

  4. Hozzunk létre egy config.txt fájlt és másoljuk bele az AgentGame.mas2j fájlból az "adamant_ [verbose=0] #5;" sort! (Így tehát lesz egy c:\temp\config.txt fájlunk.)

  5. Tömörítsük össze a mappa tartalmát (figyelve arra, hogy a tömörített fájlba a gyökérkönyvtár ne kerüljön bele), és töltsük fel a megoldást a szerverre!

Visszajelzések a beadó rendszertől

A beadást követően a beadó rendszer feldolgozza a feltöltött fájlt. A fenti példa esetében erről a következő üzenetet kapjuk a Beadások, eredmények oldalon:

A bekuldott tomoritett fajl tartalma:

asl

config.txt

java

Az /asl mappaban az alabbi agenseket azonositottuk:

adamant_.asl

A forditas a kovetkezo osztalyokat allitotta elo:

AlwaysTrue.class

A config.txt a kovetkezo agenseket definialja:

adamant_ [verbose=0] #5;

Amennyiben a feldolgozás során hiba történik, akkor a fenti kimenetben a megfelelő helyen hibajelzést található: ilyenkor a versenyben továbbra is a legutóbb sikeresen beadott változat vesz részt (ha van már ilyen) mindaddig, amíg az új verzió beadása nem sikerül.

A csapatok teljesítményének megtekintése a Beadó rendszerben

A Beadó rendszerben tekinthető meg a verseny pillanatnyi állása:

12. ábra - A versenyben élen álló csapatok és pontszámaik
A versenyben élen álló csapatok és pontszámaik

A beadott csapatok között lejátszott játékokhoz egyenként tartozik egy részletező oldal, ahol nyomon követhető az egyes ágensek illetve csapatok pontszámának alakulása. Itt kerül feltüntetésre a szimulátor kimenete is benne az esetleges hibaüzenetekkel.

13. ábra - Egy játék részletei a beadó rendszerben
Egy játék részletei a beadó rendszerben

A játékok részletes megtekintésén kívül lehetőség nyílik továbbá a beadó rendszerben az egyes csapatok teljesítményét egyenként megjeleníteni, illetve a csapatok különböző beadott verzióit összehasonlítani is.

14. ábra - A Kingham nevű csapat részletes adatai
A Kingham nevű csapat részletes adatai

15. ábra - A Vivid és a Urchin csapatok különböző verzióinak összehasonlítása
A Vivid és a Urchin csapatok különböző verzióinak összehasonlítása

Kidolgozta: Eredics Péter, BME