Náš tím mal na starosti vylepšovanie nižších vrstiev ako plánovač, highskilly, lowskilly a anotácie.
Návrh architektúry spočíval v navrhnutí strategickej a taktickej vrstvy za využitia situácií, podľa ktorých budeme vedieť lepšie riadiť hráčov na ihrisku a rozdeliť rozhodovaciu logiku do viacero úrovní spolu s odstránením množstva rozhodovacích stromov z kódu. Pôvodné plány, ktoré sa svojím zameraním blížili taktikám boli odstránené a nahradené vrstvou taktík.
Agent na ihrisku je riadený kódom, ktorý sa skladá z viacerých modulov navzájom prepojených. Moduly sú v hierarchií a každý má inú funkcionalitu.
Selector má na starosti vyberanie vhodných stratégií a taktík na základe daných situácií na ihrisku. Trieda SelectorObserver implementuje rozhranie ParsedDataObserver. Triedy, ktoré implementujú toto rozhranie vždy po sparsovaní novej správy zo servera sú notifikované. Selector teda vyberá taktiky vždy s príchodom novej správy zo servera. Metóda controlTactic v triede SelectorController preveruje, či aktuálna taktika stále spĺňa kritéria pre vykonávanie. Tj, či neexistuje taktika s oveľa väčšou fitness, alebo taktika nie je ukončená. Metóda controlStrategy v triede SelectorController preveruje, či aktuálna stratégia stále spĺňa kritéria pre vykonávanie. (Neexistuje stratégie s väčšou fitness)
Stratégie predstavujú niečo, čo je dohodnuté pre celý zápas, alebo polčas. V reálnom futbale sa zvyčajne stratégie menia cez pauzu alebo koncom zápasu - ak je nepriaznivé skóre, alebo naopak, ak je skóre veľmi priaznivé. Stratégie teda môžu byť napríklad stratégie udržania skóre (obranná), alebo stratégia útočná, v ktorej budeme viac riskovať aby sme dokázali streliť gól. Nad vrstvou stratégii je implementovaný vyberač vhodných stratégií - trieda Selector v balíku sk.fiit.jim.decision. Stratégie sa vyberajú na základe vhodnosti - tzv fitness. Výpočet fitness spočíva v porovnávaní aktuálnej situácie s predpripravenými situáciami tzv šablónami. Keďže sa nemusí podariť mať ošetrené všetky možné kombinácie situácií, v prípade nezhody berieme najlepšie vyhovujúcu situáciu.
Vrstva taktík predstavuje správanie, ktoré sa mení počas hry. Taktika môže byť napríklad útok po ľavom krídle, kedy si agent naplánuje, že chce útočiť po ľavom krídle, prejsť s loptou pred bránou a tam sa taktika na základe danej situácie ďalej preplánuje. Taktika sa opäť vyberá v triede Selector, na základe porovnávania s danými situáciami.
Trieda Taktika obsahuje metódy: getInitCondition(List<String> currentSituations) - metóda kontroluje, či táto taktika spĺňa predpodmienky a či teda môže byť aplikovateľná na základe aktuálnych situácií
getProgressCondition - kontroluje, či taktika ešte stále môže byť vykonávateľná, či sa situácia na ihrisku výrazne nezmenila.
Plánovač oproti pôvodnému riešeniu používa inú štruktúru na rad highskillov pre vykonávania - ArrayList sme vymenili za obojsmerný rad - LinkedBlockingDeque. Umožnilo nám to pridávať požiadavky ako na začiatok radu, tak i na koniec radu. Obrovskou výhodou je, že highskilly ako GetUp vieme zaradiť na začiatok radu - aby sa vykonávali prioritne. V plánovači pribudli metódy na ukončenie aktuálne vykonávaného highskillu a logovanie informácii o aktuálne vykonávaných highskilloch v plánovači. Plánovač bol presunutý do balíka sk.fiit.jim.agent.highskill.runner
Trieda situácie reprezentuje jednotlivé situácie, ktoré môžu počas hry nastať. Sú to situácie napríklad: - loptu má protihráč a som v prvom kvadrante a lopta je v treťom kvadrante - lopta je v druhom kvadrante, som v prvom kvadrante a nikto nemá loptu V projekte je vytvorených veľa situácií, nachádzajú sa v balíku sk.fiit.jim.decision.situation. Ihrisko pre situácie bolo rozdelené do viacerých oktánov
V našom novom riešení má agent zadefinovaný konečný zoznam pohybov, ktoré vie vykonávať. Z tohto preddefinovaného zoznamu pohybov si vyberá najvhodnejší pohyb na základe atribútov poskytnutých z taktiky a na základe anotácií (štatistík) jednotlivých pohybov. Pri výbere pohybu sa vyhodnocuje vhodnosť všetkých dostupných pohybov a na základe výsledkov sa vyberá pohyb, ktorý dosiahol najvyšší výsledok.
Všetky z preddefinovaných pohybov zo zoznamu majú spoločnú rodičovskú triedu, v ktorej sú zadefinované spoločné atribúty a metódy. Táto rodičovská trieda implementuje rozhranie, ktoré definuje správanie každého vyššieho pohybu. V tejto triede je taktiež implementovaná všeobecná metóda na výber nižšej schopnosti, ktorá je použiteľná pre všetkých potomkov. Následne v jednotlivých triedach pohybov je dôležité zadefinovať názov pohybu, slúžiaci pri vyhľadávaní anotácií a nižších pohybov. V každej triede je následné možné preťažiť metódu výberu pohybov a zadefinovať vlastné vhodnejšie správanie.
Do anotácií boli pridané nasledujúce parametre:
Okrem uvedených parametrov je pre kopy dôležitý aj parameter fall. Následkom pridania nových parametrov do anotácií bolo potrebné upraviť triedy Annotation, XMLParser, XMLCreator, pridať triedu AgentPosition všetko v rámci balíku annotation.data. Ďalej bolo nutné modifikovať definičný súbor pre XML anotácie. Staré a neaktuálne anotácie boli presunuté do súboru annotationOld, pre prípad možného využitia v budúcnosti.