poniedziałek, 8 sierpnia 2016

Przerwa w pracy.

W najbliższym czasie będę musiał pracować nad innym projektem, dlatego zdecydowałem, że tymczasowo wstrzymam prace nad Token Battle.

Aktualizacja 0.7.0

Nową wersję gry można pobrać pod tym adresem:
https://drive.google.com/open?id=0B_YKEPym2wKDVGJKZk9Vb0pPVk0

Zasady gry można znaleźć pod adresem:
http://tokenbattle.blogspot.com/2016/07/zasady-gry.html

Nowości:
- Dodano możliwość podglądu swojego zestawu żetonów w trakcie gry.
- Dodano możliwość przejrzenia historii ostatnich 5 ruchów w trakcie gry.
- Dodano 5 nowych żetonów (ich omówienie niżej).

Poprawki:
- AI stara się teraz zwracać więcej uwagi na to, czy warto stawiać żetony specjalne w zasięgu żetonu, który może co turę redukować wartość określonych żetonów.

Podglądu swojego zestawu żetonu w trakcie gry


Jeśli gracz wybiera któryś ze stworzonych przez siebie zestawów żetonów, to przeważnie wie co dokładnie się w nim znajduje. Problem pojawia się jednak wtedy, gdy gracz wybiera losowy zestaw - wtedy nie ma pewności jakie karty żetonów może otrzymywać w trakcie gry. Znajomość takich rzeczy daje graczowi pewną przewagę nad przeciwnikiem, ponieważ może lepiej zaplanować swoją taktykę. Wybranie losowego zestawu żetonów samo w sobie jest wadą, bo takie zestawy są zwykle słabsze od pozostałych, więc nie ma sensu pogłębiać tej wady nieznajomością tali - dlatego teraz w trakcie gry można sprawdzić zawartość zestawu z którego się korzysta.

A co w przypadku grania własnym zestawem żetonów? W takim przypadku gracz także będzie mógł sobie przypomnieć jego zawartość. Wolę aby gra polegała głównie na podejmowania decyzji, a nie zapamiętywania czegoś prostego, co równie dobrze można było sobie raz zapisać na kartce.

Historia ostatnich ruchów w trakcie gry


Mogło się zdarzyć, że gracz mógł z jakiejś przyczyny nie zauważyć jaki żeton został użyty przez przeciwnika. w przypadku nowych graczy problem ten był bardziej nasilony, ponieważ mogą oni nie znać niektórych żetonów/umiejętności, a więc tym bardziej mogli nie wiedzieć co się dzieje na planszy. Dodałem więc do gry możliwość przejrzenie historii ostatnich ruchów, na podstawie której gracz będzie mógł nie tylko sprawdzić jaka karta żetonu została użyta przez przeciwnika, lecz także będzie mógł przeczytać jej opis.

Omówienie nowych żetonów

Do gry zostały dodane następujące żetony:


Umiejętność oznaczona tym żółtym żetonem sprawia, że żetony o wartości mniejszej niż 3 będące jej celem zostaną przemienione w Złote Żetony, czyli żetony które podwajają przyrost ich punktacji ze wszystkich źródeł dwukrotnie. Przykładowo jeśli Złoty Żeton miałby wartość 2, to co turę generowałby 4 punkty. Co więcej: podwojenie przyrostu punktacji wpływa także na przyrost punktacji z innych źródeł, czyli jeśli w pobliżu będą stały żetony zwiększające przyrost pobliskich żetonów, to premia z tych żetonów będzie podwójna. Jeśli takich żetonów będzie wiele, to Złoty Żeton będzie generował bardzo wiele punktów. Dodatkowo żeton ten można zastosować do zmiany niezbyt korzystnego dla nas typu żetonu na inny. Przykładowo jeśli przeciwnik posiada jakiś specjalny żeton z którego czerpie duże korzyści, to możemy zmienić go w Złoty Żeton - co prawda żeton przeciwnika będzie teraz generował 2x więcej punktów, ale utraci inne swoje zalety.


Z kolei ta umiejętność sprawia, że wartość następnego postawionego przez nas żetonu wzrośnie o 1. Z jednej strony może się to wydawać niezbyt korzystne, bo zamiast tego moglibyśmy postawić jakiś żeton który od razu wynagrodzi cenę ruchu, ale z drugiej strony zwiększając wartość następnego żetonu możemy uodpornić go nieco na usunięcie przez przeciwnika, co w niektórych przypadkach zabezpieczy nasz następny żeton. Może to być przydatne gdy korzystamy z żetonów specjalnych.

wtorek, 26 lipca 2016

Aktualizacja 0.6.0

Nową wersję gry można pobrać pod tym adresem:
https://drive.google.com/open?id=0B_YKEPym2wKDVGJKZk9Vb0pPVk0

Zasady gry można znaleźć pod adresem:
http://tokenbattle.blogspot.com/2016/07/zasady-gry.html

Zmiany w balansie:
- Zmodyfikowano żeton zwiększający przyrost punktów sąsiednich wrogich żetonów (omówienie niżej).

Nowości:
- Dodano 6 nowych żetonów (ich omówienie niżej).

Poprawki:
- Zmniejszono liczbę komunikatów związanych z rozgrywką wysyłanych z hosta na klientów gry. Obecnie ma to małe znaczenie, ale jeśli w przyszłości postawię serwer, to będzie mu trochę lżej. Przepisywanie kodu zajęło mi więcej czasu niż sądziłem i dlatego dzisiejsza aktualizacja pojawiła się z opóźnieniem.
- Naprawiono szereg różnych błędów (błędy związane z LAN'em, pomniejsze błędy graficzne i AI).
- Od teraz AI tworząc/przemieszczając żetony stara się uwzględniać ich interakcje z żetonami specjalnymi.

Omówienie zmiany w balansie


Pokazany wyżej żeton dawał duży przyrost punktacji (aż 6 punktów na turę), ale w zamian zwiększał przyrost punktacji sąsiednich wrogich żetonów o 1 pkt. Stosując ten żeton trzeba dążyć do tego, by przeciwnik nie postawił koło niego wiele własnych żetonów. Nie było to trudne jeśli żeton postawiło się w samym rogu planszy - nawet jeśli przeciwnik starał się zminimalizować jego siłę otaczając ten żeton, to gracz stosujący ten żeton i tak wychodził kilka punktów na plus. Jedynym skutecznym zagraniem przeciwko temu żetonowi było wypchnięcie go poza planszę, jednak to doprowadzało do tego, że zbyt opłacalne było granie tego żetonu i/lub żetony które mogły go wypchnąć poza planszę. Wymuszenie na graczu stosowanie kilku konkretnych żetonów zmniejszało różnorodność rozgrywki, co jest cechą niepożądaną w grach.

Żeton został więc zmieniony w taki sposób, aby stawiał żetony o wartości 1 dla przeciwnika na sąsiednich polach po przekątnej. Teraz stawiając go w rogu planszy nadal będzie skuteczny, ale pod warunkiem, że na odpowiednim polu będzie znajdował się przyjazny żeton, który zablokuje umiejętność specjalną aktywowaną przez kartę tego żetonu.

Omówienie nowych żetonów


Umiejętność oznaczona tym symbolem redukuje wartość żetonów na obszarze umiejętności o wartość równą liczbie przyjaznych żetonów na obszarze umiejętności. Innymi słowy aby zredukować wartość żetonów musimy uszkodzić także swoje własne żetony, a im więcej własnych żetonów poświęcimy, tym mocniej możemy zaszkodzić przeciwnikowi.

Po ostatnich aktualizacjach coraz łatwiej jest zapełnić planszę (co przyspiesza rozgrywkę), więc warto jest zapewnić graczom coś co pozwoli ten efekt odwróci - niektórzy wolą szybsze mecze, a inni wręcz odwrotnie. Nowa umiejętność nie tylko pozwala wyczyścić część planszy (co opóźnia jej zapełnienie i koniec gry), ale także wyraźnie redukuje przyrost punktacji obu graczy, dając graczom szansę na dłuższą rozgrywkę i szansę na zwrot akcji.

Prócz tego nowa umiejętność nadaje dodatkowego znaczenia innym istniejącym już żetonom. Jeśli jeden z gracz posiada sporo żetonów o wartości 1 (co łatwo osiągnąć stosując kartę stawiającą wiele słabych żetonów na raz), to może starać się poświęcić właśnie je - nawet jeśli umiejętność zada spore obrażenia wszystkim w zasięgu, to ucierpimy niewiele. Dodatkowo w grze istnieją żetony, które po zniszczeniu zostają zastąpione żetonem o wartości 1, które także mogą być świetną dopałką do tej umiejętności.

Umiejętność przedstawiona tym pomarańczowym symbolem sprawia, że stawiany przez nas żeton zamienia się miejscem z ostatnio położonym przez gracza żetonem. W przeciwieństwie do innych umiejętności przemieszczających ta nie pozwala na wypchnięcie wrogiego żetony poza planszę, ale za to pozwala umiejscowić określony żeton na dowolnym pustym polu na całej planszy. Jest to fajny sposób na radzenie sobie z żetonami specjalnymi, których efektywność zmienia się w zależności od ich położenia, ale przestawiając wrogi żeton można jeszcze ułatwić sobie korzystanie z innych swoich umiejętności.

Żeton przedstawiony po lewej stronie pomiędzy turami redukuje wartość pierwszych napotkanych żetonów w każdym poziomym kierunku o 1 pkt. Żeton ten może częściowo przypominać wieżyczkę z gier typu tower defense, która obija wszystko to, co znajdzie się w jej zasięgu. Dzięki temu żetonowi pozycjonowanie żetonów nabiera większego znaczenia, przykładowo przeciwnik może go przesunąć w taki sposób, aby zamiast niszczyć jego żetony zaczął niszczyć nasze własne, a wtedy sami zaczniemy rozważać jego zniszczenie/przesunięcie. Z pewnością będzie on doprowadzał do wielu nietypowych i ciekawych sytuacji.

A ten żeton działa tak jak powyższy, tylko w linii pionowej.




Swoją drogą powinienem chyba ponadawać jakieś nazwy wszystkim umiejętnościom, żetonom i kartom, bo trochę głupio się je opisuje bez nazw...

niedziela, 17 lipca 2016

Aktualizacja 0.5.0

Nową wersję gry można pobrać pod tym adresem:
https://drive.google.com/open?id=0B_YKEPym2wKDVGJKZk9Vb0pPVk0

Zasady gry można znaleźć pod adresem:
http://tokenbattle.blogspot.com/2016/07/zasady-gry.html

Zmiany w balansie:
- Zmniejszono wartość żetonów przemieszczających inne żetony które miały wartość 3. Teraz mają wartość 2 i gdy zostają zniszczone, zamiast tego zostają zastąpione zwykłym żetonem o wartości 1. Omówienie zmiany niżej.

Nowości:
- Dodano 6 nowych żetonów (ich omówienie niżej).
- Od teraz po najechaniu kursorem na ikonę żetonu wyświetla się jego opis (dotychczas takie opisy były wyświetlane tylko dla typów umiejętności, a same żetony nie posiadały żadnych właściwości).
- Od teraz można wybrać do gry losowy z posiadanych zestawów żetonów, lub zestaw o losowej zawartości.
- Do ekranu gry dodano miejsce na awatar, choć na razie nie ma możliwości ustawienia żadnego avataru.
- Avatar gracza unosi się gdy zaczyna się jego tura i opada gdy zaczyna się tura przeciwnika.

Poprawki:
- Poprawiony algorytm losowości AI.
- Naprawiono błąd który sprawiał, że umiejętność tworząca żetony dla przeciwnika powodowała błędy w trybie Sandbox, w którym gracz gra bez przeciwnika.

Losowe zestawy zestawy żetonów:


Grając wielokrotnie przeciw AI stwierdziłem, że gra jest zbyt nudna, jeśli wiemy jaki zestaw żetonów posiada przeciwnik. Rozgrywka jest wtedy prostsza, ponieważ wiemy jakich ruchów możemy się spodziewać i unikamy sytuacji w których przeciwnik mógłby zyskać przewagę. Jeśli nie znamy zestawu przeciwnika gra staje się ciekawsza, ponieważ nie wiemy czego możemy się po nim spodziewać, a przynajmniej przewidzenie jego ruchów jest trudniejsze. Wadą tego rozwiązania jest niestety fakt, że biorąc dla przeciwnika losowy zestaw z listy nadal wiemy jaki z maks 5 zestawów możemy się spodziewać, a biorąc zestaw z losową zawartością decydujemy się na zestaw, który mimo swej nieprzewidywalności może się okazać po prostu słabszy.

Algorytm generowania zestawów został zaprojektowany w taki sposób, aby zawierały losową ilość kart żetonów. Im więcej jest kart na pojedynczym stosie kart, tym mniejsza jest szansa na to, że dodana zostanie kolejna karta, czyli przeważnie ka stosach będą znajdowały się po 2-3 karty, a rzadko 4-5 kart. Dodatkowo na pierwszym stosie będą się znajdowały wyłącznie te karty, które mogą być opłacalne w pierwszej turze gry (lub raczej nie są nieopłacalne), dzięki czemu gracz może mieć pewność, że nie będzie miał fatalnego startu.


Omówienie zmian w balansie:

Żetony przedstawione w górnym wierszu zostały zmienione na odpowiedniki z niższego wiersza.

Żetony które zmieniają pozycje żetonów w orientacji nie-skośnej (poziomej lub pionowej) były w stanie wypchnąć poza planszę żetony znajdujące się na 12 różnych polach (zakładając, że nic nie blokowało im drogi), podczas gdy żetony zmieniające pozycje żetonów po skosie potrafiły wypchnąć poza planszę żetony znajdujące się na 18 różnych polach, czyli wypchnięcie żetonów było w ich przypadku znacznie łatwiejsze. Dodatkowo w niektórych sytuacjach potrafiły wypchnąć jednocześnie 2 żetony poza plansze. Początkowo ten brak równowagi żetony o orientacji nie-skośnej nadrabiały wyższą wartością punktową niż ich skośne odpowiedniki, jednak sprawiła ona, że żetony początkowo słabe stały się statystycznie silne na tle innych żetonów. Wymusiło to szukanie jakiegoś pośredniego rozwiązania. Zmniejszyłem więc wartość punktową tych żetonów i dodałem żetonom specjalną właściwość: gdy zostają zniszczone, zamiast tego zostają zastąpione zwykłym żetonem o wartości 1. Sprawia to, że pozbycie się tych żetonów z planszy jest równie trudne co dotychczas, ale generują one mniejszą wartość punktów niż dotychczas (kolejno 2, 1, 1 pkt. zamiast 3, 2, 1 pkt. w zależności od stopnia uszkodzenia).

Omówienie nowych żetonów:


Żeton ten zwiększa przyrost punktacji wszystkich pobliskich przyjaznych żetonów o 1. Jest to premia która utrzymuje się tak długo jak długo utrzymuje się żeton, czyli w przeciwieństwie do dotychczas istniejących żetonów ten żeton wpływa też na żetony stawiane w przyszłości. Działa to też w drugą stroną - jeśli żeton zostanie zniszczony, stracimy premię którą nam dawał. Żeton ten zachęca więc obu graczy do zwracania większej ilości uwagi na konkretne żetony i wzmaga rywalizację w poszczególnych miejscach planszy. Prócz tego żeton ten daje graczom nowy sposób na wykorzystanie żetonów przemieszczających - przeciwnik może przesunąć też żeton w miejsce oddalone od naszych żetonów aby zminimalizować jego premię, a my możemy starać się przemieszczać go w bardziej korzystne lokacje.

Kolejne 2 typy żetonów niewiele się różnią od omówionego żetonu, różnica polega na tym, że żółty żeton wzmacnia także przyrost punktacji żetonów przeciwnika, a żółto-czerwony wpływa tylko na żetony przeciwnika. Częściowo zmienia się też ich zastosowanie praktyczne - żółty żeton mimo obusiecznego efektu posiada większą wartość punktową, dzięki czemu jest trudniejszy do zniszczenia, dzięki czemu łatwiej jest nam go bronić przed przeciwnikiem. Żółto-czerwony żeton z kolei daje nam bardzo dużo punktów, ale musimy starać się, aby przeciwnik nie postawił w jego pobliżu zbyt wiele żetonów.

 Prócz nowych typów żetonów doszły też nowe umiejętności. Umiejętność po lewej sprawia, że jeśli cały obszar umiejętności jest pokryty żetonami, otrzymujemy dodatkową turę. W praktyce wymaga to od nas doprowadzenia do sytuacji, w której  żetony mogą być pokryte przez wszystkie 4 pola umiejętności, a zyskamy żeton o wartości 1 nie tracąc naszego ruchu.

Kolejną umiejętnością jest umiejętność dająca bonusową turę przeciwnikowi. Przede wszystkim żeton z tą umiejętnością generuje dla nas bardzo dużo punktów i daje nam tymczasową przewagę nad przeciwnikiem, ale pozwala przeciwnikowi wykonać 2 ruchy pod rząd, które w połączeniu mogą być dla nas dotkliwe. Przykładowo przeciwnik może użyć 2 żetonów z umiejętnością przemieszczającą, aby wyrzucić poza planszę żeton, który nawet nie był blisko jej krawędzi. Sam żeton można jeszcze wykorzystać do stworzenia przeciwnikowi przewagi liczebnej, dzięki czemu umiejętności obszarowe mogą być dla niego bardziej dotkliwe.

niedziela, 10 lipca 2016

Aktualizacja 0.4.0

Nową wersję gry można pobrać pod tym adresem:
https://drive.google.com/open?id=0B_YKEPym2wKDVGJKZk9Vb0pPVk0

Zasady gry można znaleźć pod adresem:
http://tokenbattle.blogspot.com/2016/07/zasady-gry.html

Nowości:
- Dodano nowe żetony (ich omówienie niżej).
- Od teraz po najechaniu kursorem na ikonę umiejętności żetonu wyświetla się jej opis.
- Od teraz w edytorze zestawów żetonów można przeciągać karty żetonów z kolekcji do zestawu (dotychczas można było tego dokonać tylko klikając na kartę w kolekcji i na pole w zestawie).

Poprawki:
- Od teraz AI lepiej szacuje użyteczność żetonów które przerzucają pobliskie żetony na pole symetryczne względem stawianego żetonu.

Omówienie nowych żetonów



Umiejętność oznaczona tym symbolem sprawia, że na pustych polach objętych działaniem umiejętności pojawiają się przyjazne żetony o wartości 1.

Dodane zostały 4 różne żetony z tą umiejętnością, które różnią się tylko obszarem jej działania. Żetony te powodują wystawienie do 3 żetonów (włącznie z sobą), których łączna wartość jest równa 4. W tej grze gracze zazwyczaj dążą do tego, by jednym ruchem zyskać więcej niż 4 punkty turowej przewagi nad przeciwnikiem (np. wystawiając inny żeton o wartości 3, jednocześnie redukując wartość wrogich żetonów o 2, co daje łącznie 5 pkt. przewagi), a nowe żetony z zielonym symbolem tego nie oferują, przez co mogą się wydawać pozornie słabe. Mimo to posiadają szereg zalet, których nie posiadają dotychczas istniejące żetony:
- Mogą doprowadzić do szybkiego rozstrzygnięcia meczu przez zapełnienie planszy. Jeśli jeden z graczy zyska przewagę nad drugim graczem, może próbować przyspieszyć w ten sposób grę aby ją zakończyć nim przeciwnik odzyska przewagę.
- W przeciwieństwie do innych żetonów jego siła nie polega na redukcji przyrostu punktów przeciwnika, a całkowicie skupia się na zwiększeniu własnego przyrostu punktów. Jeśli przyrost punktacji obu graczy ciągle wzrasta, to limit punktów jest osiągany szybciej niż zwykle, co także można wykorzystać w celu szybszego zakończenia meczu przez gracza wygrywającego.
- Jednoczesne ułożenie na planszy 3 żetonów sprawia, że utrudnione zostaje wypchnięcie wartościowych żetonów poza planszę,

Żetony te wprowadziłem głównie po to, aby zmniejszyć skuteczność taktyki opierającej się na wypychaniu wrogich żetonów poza planszę. Zwykle to ten styl gry dominował wśród graczy i sprawiał, że rozgrywka stawała się zbyt schematyczna.

 Umiejętność oznaczona tym symbolem różni się od poprzedniej tylko przynależnością stawianych żetonów - są one przyznawane przeciwnikowi.

Sam żeton ma największą wartość spośród wszystkich dotychczas istniejących, bo jego wartość wynosi aż 5 punktów, ale z drugiej strony może wystawić do 8 żetonów dla przeciwnika, co dla niego oznacza do 8 dodatkowych punktów na turę. Jest to negatywna umiejętność, której aktywację można uniknąć stawiając żeton na polu który nie sąsiaduje z żadnym pustym polem - w takim przypadku przyrost punktów przeciwnika nie zwiększy się. Żeton ten zachęca więc gracza do postawieniu go na krawędzi planszy, czego dotychczas gracze unikali z obawy o to, że ich żeton zostanie wypchnięty.

Zasady gry


W Token Battle naprzeciw siebie staje dwóch graczy, którzy naprzemiennie kładą żetony planszy składającej się z 36 pól.
Każdy z graczy dysponuje 4 stosami kart, które reprezentują różne żetony. W trakcie swojej tury gracz musi wybrać jedną z kart znajdujących się na szczytach stosów i postawić jej odpowiadający jej żeton na wybranym pustym polu. Gdy karta zostanie użyta, zostaje umieszczona na spodzie stosu, odsłaniając następną kartę ze swego stosu. Po wykonaniu ruchu obaj gracze zyskują punkty równe sumie wartości ich żetonów znajdujących się na planszy.


Karty


Każda karta żetonu zawiera o nim 4 podstawowe informacje:
- wartość żetonu,
- typ umiejętności,
- obszar działania umiejętności,
- typ żetonu.


Liczba znajdująca się w lewym górnym rogu karty oznacza wartość żetonu, czyli liczbę punktów którą gracz otrzymuje co turę po jego wystawieniu. Symbol w prawym górnym rogu oznacza typ umiejętności którą posiada żeton, zaś kwadraty wokół koła pokazują na które z sąsiednich pól wpłynie umiejętność gdy żeton zostanie umieszczony na planszy. Symbol koła oznacza tutaj typ żetonu.


Typy umiejętności


Na chwilę obecną w grze istnieje 5 typów umiejętności, ale liczba ta będzie stale wzrastać.


Redukuje wartość żetonów będących celem o 1 pkt.


Odpycha żetony będące celem od stawianego żetonu.


Przemieszcza żetony będące celem na pola symetryczne względem stawianego żetonu.


Tworzy przyjazne żetony o wartości 1 na pustych polach będących celem umiejętności.


 Tworzy wrogie żetony o wartości 1 na pustych polach będących celem umiejętności.


Jeśli obszar umiejętności jest kompletnie pokryty żetonami, zyskujesz dodatkową turę.


Przeciwnik zyskuje dodatkową turę.


Redukuje wartość żetonów będących celem umiejętności o wartość równą liczbie przyjaznych żetonów na obszarze umiejętności.


Zamienia miejscami stawiany żeton z ostatnio zagranym żetonem.



Zamienia żetony o wartości mniejszej niż 3 będące celem umiejętności w Złote Żetony (podwajają swój przyrost punktacji ze wszystkich źródeł dwukrotnie).

Zwiększa wartość następnego zagranego przez ciebie żetonu o 1.

Typy żetonów


Żeton bez efektów specjalnych.


Jeśli żeton zostaje zniszczony, zamiast tego staje się zwykłym żetonem o wartości 1.


Zwiększa przyrost punktacji wszystkich pobliskich przyjaznych żetonów o 1.


Zwiększa przyrost punktacji wszystkich pobliskich żetonów o 1.


Zwiększa przyrost punktacji wszystkich pobliskich przyjaznych żetonów o 1.


Pomiędzy turami redukuje wartość pierwszych napotkanych żetonów w każdym poziomym kierunku o 1 pkt.


Pomiędzy turami redukuje wartość pierwszych napotkanych żetonów w każdym pionowym kierunku o 1 pkt.


Podwaja swój przyrost punktacji ze wszystkich źródeł dwukrotnie.

Cele wygranej


Rozgrywka zostaje zakończona gdy jeden z graczy osiągnie 1000 punktów, lub gdy wszystkie pola na planszy zostaną zapełnione. Wygrywa ten gracz, który na koniec meczu posiada najwięcej punktów.


Zestawy żetonów


Każdy z graczy może stworzyć swoje własne zestawy żetonów, które potem będzie wykorzystywał w grze.



Aby utworzyć swój własny zestaw należy wejść w edytor zestawów żetonów, a następnie przenieść wybrane karty z kolekcji kart do swojego zestawu. Każdy z 4 pasów znajdujących się po lewej stronie edytora oznacza inny stos kart w grze, a na każdym z nich musi znajdować się od 2 do 5 kart. Od kolejności kart na stosach będzie zależeć dostęp do nich w trakcie gry - te na górze będą dla gracza dostępne na początku partii, a dopiero po ich zużyciu gracz zyska dostęp do kolejnych kart.

niedziela, 3 lipca 2016

Aktualizacja 0.3.0

Dzisiejsza aktualizacja wprowadza niewiele, ale zawsze to kroczek do przodu. Nową wersję gry można pobrać pod tym adresem:
https://drive.google.com/open?id=0B_YKEPym2wKDVGJKZk9Vb0pPVk0

Nowości:
- Od teraz przed rozpoczęciem gry można wybrać dla siebie zestaw żetonów (dotychczas zestaw domyślny trzeba było wybieracz w edytorze zestawów). Dodatkowo w trybie Hotseat i w grze przeciwko AI można wybrać dla przeciwnika dowolny z posiadanych zestawów.
- Od teraz za pomocą klawiszy 1-4 można wybierać z którego stosu kart będą wybierane karty.
- Od teraz animacje wystawiania żetonów będą uruchamiane dopiero po zakończeniu poprzednich animacji żetonów. Dzięki temu wykonanie ruchów wyprzedzających animacje będzie wywoływało mniejszy chaos na planszy.
- Zmieniono ilustracje obszaru działania umiejętności żetonów. Od teraz pokazuje ona obszar 3x3 zamiast obszaru 5x5 (zdecydowałem, że w przyszłości nie będą wprowadzane żetony które wpływają na żetony oddalone o dalej niż 1 pole, więc zmieniłem grafikę na czytelniejszą).

Zmiany i poprawki:
- Naprawiono błąd który sprawiał, że szybkie ponowne wykonanie ruchu w grze przeciwko AI powodowało wykonanie rozkazu w imieniu AI (innymi słowy nie można już wykonywać ruchów zamiast AI).
- Naprawiono błąd który sprawiał, że edytowanie zestawów mogło działać niepoprawnie w trybie LAN jeśli nie było się hostem.
- Naprawiono błąd który sprawiał, że nie dało się zrezygnować z rozpoczętej rozgrywki w trybie Sandbox, przez co nie można było rozpocząć innej gry do momentu rozstrzygnięcia gry we wspomnianym trybie.

sobota, 18 czerwca 2016

Aktualizacja 0.2.0

Zbliża się sesja, dlatego ostatnio byłem mało aktywny, ale po upływie około dwóch tygodni będę mógł powrócić do regularnego aktualizowania tego bloga oraz gry.

Nową wersję gry można pobrać pod tym adresem:
https://drive.google.com/open?id=0B_YKEPym2wKDVGJKZk9Vb0pPVk0
Poprawiłem link w taki sposób, aby nie wymagał już logowania na konto google.

Wprowadzone zmiany:

Od teraz efekty umiejętności są podświetlane na szaro, jeśli nie mogą wpłynąć na pole.

Dotychczas gracze na początku gry aby poznać zasady działania umiejętności musieli testować je metodą prób i błędów. Teraz wystarczy sprawdzić które efekty umiejętności podświetlają się kolorem, aby wiedzieć na jakie pola zadziała umiejętność.

Przedtem:

Teraz: 

Efekty umiejętności przemieszczających żetony pokazują teraz z którego miejsca na które przeniesie się żeton:

Przedtem:


Teraz:

 Dodatkowo jak widać umiejętność przerzucająca żetony może teraz zamieniać miejscami dwa przeciwległe żetony.

 Dodano możliwość zapisu na koncie kilku różnych zestawów żetonów:


Dodatkowo jak widać zmieniono też ikony umiejętności żetonów na nieco bardziej wyraźnie.


Zmian niewiele, ale w ze względu na nadciągającą sesję miałem sporo do roboty.

wtorek, 31 maja 2016

Stan obecny gry i plany na przyszłość

Dzisiaj osiągnąłem już stan gry który uważam za grywalny. Mimo iż grę mogę już prezentować, to pozostawia wiele do życzenia i nadal potrzebuje ona dużego nakładu pracy. Można ją pobrać pod tym adresem:
https://drive.google.com/open?id=0B_YKEPym2wKDVGJKZk9Vb0pPVk0

Kod na gicie:
https://github.com/AwareOwl/TokenBattle

Obecnie gra działa tylko na LANie i przechowuje dane na komputerze który pełni rolę hosta. W grze dostępne są następujące tryby gry:
- Easy AI
- Normal AI
- LAN (umożliwia grę pomiędzy każdą uruchomioną grą w sieci LAN),
- Hotseat (gracze wykonują swoją turę naprzemiennie),
- Sandbox (gra bez przeciwnika).

Gracze mają dostęp do 20 żetonów, z których mogą składać zestawy żetonów. Na chwilę obecną istnieją 3 rodzaje umiejętności żetonów:
- Redukcja wartości - redukuje wartość żetonów objętych działaniem umiejętności,
- Odepchnięcie - żeton odpycha od siebie żetony objęte działaniem umiejętności (może spowodować wypchnięcie żetonu poza planszę).
- Przerzucający - przerzuca żetony objęte działaniem umiejętności na pole symetryczne względem żetonu (może spowodować wypchnięcie żetonu poza planszę).

W planach między innymi:
- Dodanie nowych poziomów AI.
- Możliwość zapisu wielu zestawów żetonów.
- Możliwość wybrania zestawu żetonów dla AI oraz przeciwnika w trybie hotseat.
- Dodanie nowych rodzai żetonów.
- Dodanie nowych rodzai umiejętności.
- Wprowadzenie samouczka.
- Dodanie nowej szaty graficznej.
- Dodanie opcji zmiany tempa rozgrywki.
- Dodanie dźwięków.
Oraz wiele innych zmian.

Prosiłbym o zgłaszanie błędów i sugestii.

niedziela, 29 maja 2016

Równowaga w grze.

W Token Battle elementami gry z których korzysta gracz są żetony. Każdy żeton ma swoje właściwości i parametry, które sprawiają, że jest w pewnym sensie unikalny na tle innych żetonów. Równowaga w grze panuje, gdy każdy z jej elementów ma w sobie coś, co w jakiejś sytuacji może uczynić go lepszym od innych elementów gry i vice versa. Jeśli gracz zastanawiając się nad siłą jakiegoś elementu stwierdzi, że jest on lepszy od innych elementów w każdej sytuacji, to wtedy ten element jest zbyt silny i zaburza równowagę gry.

Dlaczego warto utrzymywać równowagę w grze?

Jeśli jakiś element gry jest zbyt silny, to stopniowo zaczynają korzystać z niego wszyscy gracze. Doprowadza to do powtarzalności w grze - ten sam element jest widziany w każdej grze, a więc każdy się go spodziewa. Jeśli jakaś sytuacja powtarza się w każdej grze, to gracze szybko znajdują najlepszy schemat reakcji na tą sytuację i każda kolejna gra staje się jedynie odtwarzaniem poprzedniej gry. Tego typu schematyczność można omijać na wiele sposobów, np. dodając do gry element losowości, albo narzucać limity na te same zagrania, ale to jedynie ukrywa problem.

Zupełnie inaczej wygląda sytuacja zbyt słabych elementów w grze - są one zwykle przez graczy zupełnie ignorowane, a więc nie mają wpływu na grę. Nie wydają się one być ani szkodliwe, ani pożyteczne. Tworzenie takich elementów jest tylko marnowaniem zasobów, które można by przeznaczyć na coś innego.

W jaki sposób zachować równowagę w grze?

Najbardziej oczywistym sposobem na równoważenie gry jest modyfikowanie ich cech. Tutaj pojawia się jednak problem - czasem minimalna modyfikacja elementu sprawi, że z elementu zbyt silnego zmieni się w element zbyt słaby i na odwrót. Im więcej cech ma element, tym łatwiej go zrównoważyć, ponieważ można go modyfikować na więcej sposób - być może któryś z tych sposobów zmieni siłę elementu w sposób minimalny, dzięki czemu uda się zachować idealną równowagę.

Innym rozwiązaniem może być wprowadzanie synergii między elementami. Jeśli uznamy, że jakiś element jest zbyt słaby, to możemy dodać do gry element uważany za mocny ale tylko wtedy, gdy zagra się go razem ze wspomnianym słabym elementem. Takie rozwiązanie z pewnością może sprawić, że każdy element w grze będzie warty uwagi, ale nieodpowiednio zaimplementowane może doprowadzić do tego, że gra zacznie się sprowadzać do sztucznego podziału elementów na grupy, których gracze nie będą chcieli ze sobą mieszać. Jeśli w trakcie gry zobaczymy element z jakiejś "grupy synergii", to od razu będziemy się spodziewali pozostałych elementów z tej grupy, a więc gra byłaby mniej emocjonująca.

Kolejnym rozwiązaniem może być wprowadzenie do gry elementu papier-kamień-nożyce. Jeśli będziemy postępowali zgodnie z tym założeniem, to w grze każdy element będzie miał jakąś znaczącą wadę, którą przeciwnik może łatwo wykorzystać. Załóżmy, że jakieś taktyki A pokonują 90% innych taktyk (które nazwiemy taktykami B), co doprowadza do jej wysokiej popularności. W takiej sytuacji opłacalne byłoby stosowanie tych 10% taktyk, które nie byłyby wrażliwe na taktykę A (takie taktyki nazwiemy taktykami C). Jeśli taktyki C staną się popularne, to nieopłacalne stanie się stosowanie taktyk A, a to z kolei znowu pozwoli graczom na korzystanie z taktyk B i koło się zamyka. Schemat papier-kamień-nożyce sprawia więc, że opłacalność taktyk jest w pełni zależna od graczy i żadna z taktyk nie może być górująca tak długo jak posiada co najmniej jedną wadę.


Czym będę się kierować równoważąc Token Battle?

Token Battle będzie przede wszystkim opierało się na dostosowywaniu się sytuacji w grze. Każdy z graczy będzie miał dostęp do swojego zestawu żetonów, składającego się z kilku stosów żetonów i do każdego z tych żetonów będzie miał cykliczny dostęp. Każdy żeton będzie się sprawdzał w innych sytuacjach, a więc gracz będzie musiał dobierać żetony w taki sposób, aby się uzupełniały. Rozbieżność siły żetonów w zależności od sytuacji będzie różna, ale gracz będzie miał dostęp do wielu żetonów, więc opłacalność żetonów nie będzie zbyt zależna od stopnia jego ryzyka. 

środa, 25 maja 2016

Aktualizacja danych

W trakcie tworzenie gry może się zdarzyć, że chcemy dodać do programu funkcjonalność której przedtem nie przewidzieliśmy. Zazwyczaj nie sprawia to kłopotów, ale schody zaczynają się wtedy, gdy ta funkcjonalność wymaga innego sposobu zapisu danych o użytkownikach. Z taką sytuacją spotkałem się gdy chciałem, aby gracz miał możliwość nazywania swoich zestawów żetonów. Dotychczas dane każdego zestawu żetonów zawierały tylko 5 linijek danych - numer zestawu oraz 4 stosy kart żetonów (gdzie każdy numer karty był oddzielony spacją) i miały taki format:

set 0
0 1
2 3
4 5 8
6 7 9

Teraz natomiast zależy mi na formacie danych, który zawierałby także informacje o nazwie zestawu, którą nadał jemu graczu:

set 0
Deck 1
0 1
2 3
4 5 8
6 7 9

Zapis danych w nowym formacie nie powinien być problemem, podobnie jak dostosowanie kodu w taki sposób, aby poprawnie ten zapis odczytywał. Problem polega jednak na tym, że po dostosowaniu kodu do nowego formatu danych nie będzie on już w stanie odczytywać dotychczasowych danych użytkowników. Trzeba więc dodać do programu funkcjonalność, która zamieni dane w starym formacie na dane w nowym formacie. Tutaj pojawia się kolejny problem: jeśli aktualizacja danych będzie polegała na dodaniu do pliku paru linijek tekstu, to po kolejnym uruchomieniu skryptu nowe linijki danych powielą się, tworząc coś takiego:

set 0
Deck 1
Deck 1
0 1
2 3
4 5 8
6 7 9

Trzeba więc dodać do skryptu coś, co pozwoli rozpoznać obecną wersję danych.

Porządkowanie danych

Aby gra była w stanie rozpoznać wersję danych, należy dodać na serwer plik przechowujący informację o wersji danych - jeśli według nowej wersji gry dane użytkowników będą przestarzałe, to wszystkie dane zostaną poprawione, a numer wersji uaktualniony. Pojawia się tutaj drobny problem: jeśli informacja o wersji będzie znajdowała się w tym samym folderze co dane użytkowników, to program mógłby mylić ze sobą te pliki. Dlatego więc utwórzmy nowy folder i dodajmy do niego plik tekstowy:

 if (!Directory.Exists (@"C:/TokenBattle/Version")) {
  Directory.CreateDirectory (@"C:/TokenBattle/Version");
  File.WriteAllText (@"C:/TokenBattle/Version/version.txt", "v0.01");
 }

Od teraz przy uruchomieniu gry na serwerze będziemy mogli sprawdzić wersję danych i na jej podstawie określić, czy potrzebne są aktualizacje.

Dla porządku wypadałoby też stworzyć specjalny folder dla danych o użytkownikach:

 Directory.CreateDirectory (@"C:/TokenBattle/Users");

Do tego folderu przeniesiemy wszystkie dane użytkowników. Aby łatwo operować na plikach, potrzebne są nam ich nazwy, a można je pozyskać funkcją Directory.GetFiles (), która zwraca tablicę stringów zawierających ścieżki plików zawartych w folderze którego ścieżkę podamy w argumencie, np.:

 string [] FileNames = Directory.GetFiles (@"C:/TokenBattle");

Jeśli plik użytkownika nazywałby się user1.txt, to ścieżka tego pliku miałaby format C:/TokenBattle\user1.txt. Zależy nam, aby po modyfikacji ścieżka tego pliku brzmiała: C:/TokenBattle/Users\user1.txt, a skoro początek ścieżki zawsze będzie zaczynał się tak samo, to potrzebujemy tylko końcówki tej ścieżki, będącej nazwą pliku. Musimy więc wyciąć ze stringa wszystko co znajduje się przed znakiem \ i dla każdego pliku musimy to wykonać osobno, czyli musimy to wykonać dla wszystkich stringów w tablicy stringów:

 foreach (string fileName in FileNames) {
  string fName = fileName.Remove (0, fileName.IndexOf ("\\") + 1);
 }

Funkcja Remove przyjmuje 2 parametry: pierwszym parametrem jest index znaku od którego chcemy kasować tekst (włącznie), a drugim parametrem jest liczba znaków które chcemy skasować. Pierwszym argumentem będzie więc 0, a drugim argumentem powinna być liczba znaków do znaku \ (włącznie), czyli 21. Teoretycznie moglibyśmy tu podstawić stałą wartość, jednak jest to niewygodne, chociażby dlatego, że możemy się pomylić. Bezpieczniej jest więc użyć funkcji IndexOf, która zwróci indeks wystąpienia wybranego przez nas znaku, którym jest znak \. Znak ten jest na swój sposób wyjątkowy, ponieważ w programowaniu oznacza on rozpoczęcie różnych specjalnych operacji (np. \r\n powoduje utworzenie nowej linii), dlatego ustalono, że jeśli ktoś chce wstawić ten znak jako znak tekstowy, musi go napisać dwukrotnie.

Skoro mamy już wyodrębnioną nazwę pliku, możemy przenieść plik z jednego folderu do drugiego korzystając z funkcji Move:

 File.Move (@"C:/TokenBattle/" + fName, @"C:/TokenBattle/Users/" + fName);

Pierwszym argumentem tej funkcji jest ścieżka pliku który chcemy przenieść, a drugim argumentem jest ścieżka pliku którą chcemy uzyskać.

Modyfikacja danych o użytkownikach

Teraz pozostaje nam tylko zmodyfikować pliki. Aby to zrobić, musimy najpierw wczytać ich zawartość:

 List <string> Lines = new List <string> (File.ReadAllLines (@"C:/TokenBattle/Users/" + fName));

Funkcja File.ReadAllLines zwraca tablicę stringów, które są zawartością pliku o ścieżce podanej w argumencie. Jednak tablice mają pewną wadę: nie można na nich wykonywać wielu złożonych informacji, takich jak np. dodanie stringa w środku tablicy - można go dodać tylko na jej końcu. Skorzystamy więc z list, które oferują większe możliwości niż zwykłe tablice. Użytkownik może mieć zapisane na koncie wiele zestawów żetonów, więc program powinien odnaleźć wszystkie z nich.

 int HandsetNumber = 0;
 while (Lines.IndexOf ("set " + HandsetNumber.ToString ()) != -1) {
  Lines.Insert (Lines.IndexOf ("set " + HandsetNumber.ToString ()) + 1, "Deck " + (HandsetNumber + 1).ToString ());
  HandsetNumber++;
}

Na początku tworzymy tu zmienną, która będzie zapamiętywała numer aktualnie przeglądanego zestawu żetonów. Jeśli w danym pliku znajduje się zestaw z tym numerem, to znaczy że musimy go zmodyfikować, dodając nazwę tego zestawu, a następnie musimy zwiększyć zmienną z numerem i wszystko zapętlamy do momentu, aż w pliku skończą się zestawy. Funkcja IndexOf zwraca na wyjście -1, jeśli w liście nie znajduje się element równy temu podanemu w argumencie, co w naszym przypadku spowoduje przerwanie pętli. Funkcja Insert przyjmuje 2 argumenty - pierwszym argumentem jest numer indeksu na który chcemy dodać nowy element listy (następne elementy listy zostaną odpowiednio przesunięte), a drugim argumentem jest wartość tego elementu listy, czyli w naszym przypadku string. W programowaniu panuje zwyczaj numerowania rzeczy od 0, ale nazwa zestawów żetonów będzie widoczna w grze dla użytkowników, czyli nazwy zestawów wypadałoby numerować od 1. Prócz tego nazwa zestawu w przeciwieństwie do jego poprzedniego numeru będzie mogła być modyfikowana przez użytkowników.

Następnie pozostaje tylko zapisać zmiany:

 File.WriteAllLines (@"C:/TokenBattle/Users/" + fName, Lines.ToArray());

Odpowiednie złożenie tego wszystkiego w całość i dodanie do kodu sprawi, że nasz program będzie mógł zmodyfikować dane, jeśli okażą się nieaktualne.

sobota, 21 maja 2016

Sztuczna inteligencja

Póki co gra posiada LAN dzięki któremu można grać z drugim graczem, ale pojawia się problem, gdy drugiego gracza nie ma. Trochę głupio byłoby grać samemu ze sobą. Warto jest więc dodać do gry sztuczną inteligencję, tym bardziej że większość gier takową posiada. Samo dodanie sztucznej inteligencji nie powinno być trudne, skoro gra posiada już mechanizmy umożliwiające grę obu graczom.

Na jakiej zasadzie będzie działała sztuczna inteligencja (AI)?

AI będzie sprawdzało, jaki wpływ na przyrost punktacji obu graczy będzie miało postawienie żetonu na wybranym polu planszy, oraz będzie sprawdzało kombinacje każdego dostępnego żetonu z każdym dostępnym polem. Jeśli mamy więc planszę o wymiarach 6x6, oraz 4 żetony na ręce, to AI sprawdzi 144 różnych kombinacji ruchów i na podstawie wyników testu ustali jaki żeton użyć na jakim polu. Mimo tak obszernych danych AI nadal będzie posiadało wiele wad, oto kilka sytuacji, których AI nie będzie sprawdzało:
- jaki wpływ na nasze kolejne tury będzie miał wystawiany żeton,
- czy wykonanie ruchu spowoduje utratę szansy na tymczasową premię (którą zamiast nas otrzymałby przeciwnik wykonując inny ruch),
- czy wykonanie innego ruchu nie doprowadziłoby do natychmiastowej wygranej (jeśli do wygranej brakuje nam niewiele punktów),
- czy wykonanie innego ruchu nie uniemożliwiłoby przeciwnikowi natychmiastowej wygranej (jeśli do wygranej brakuje jemu niewielu punktów),
- jakie ruchy u(nie)możliwi użycie żetonu (przykładowo usunięcie jakiegoś żetonu z planszy może pozwolić przeciwnikowi wykonać bardziej korzystny ruch).

Pełna lista takich sytuacji jest oczywiście większa i dodatkowo będzie rosła wraz z każdym nowym rodzajem żetonu lub umiejętności. Wady AI sprawiają, że żywy gracz jest w stanie wygrać z komputerem, a dostrzegając błędy AI sam będzie mógł szybciej nauczyć się unikać. Oczywiście AI można rozbudowywać w taki sposób, aby popełniało coraz mniej błędów i dzięki temu moglibyśmy stworzyć nawet kilka poziomów AI, dzięki czemu gracz będzie mógł wybrać godnego sobie przeciwnika bez względu na swój poziom.

Warto jednak zauważyć, że im więcej sytuacji będzie sprawdzało AI, tym więcej operacji będzie musiał wykonać serwer. Jeśli założymy, że sprawdzenie ruchu wymaga wykonanie n operacji, to sprawdzenie wszystkich możliwych turów w jednej turze wymagałoby zaledwie 144 * n operacji, co zajmie sprzętowi malutki ułamek sekundy. Problem pojawia się wtedy, gdy chcemy uwzględnić znacznie większą liczbę tur i np. wybrać ruch który byłby najlepszy przewidując jego wpływ na tą turę oraz 3 kolejne, wtedy liczba operacji wzrosłaby do 144^4 * n, co prawdopodobnie zajęłoby przeciętnemu sprzętowi co najmniej kilkadziesiąt minut. Oczywiście są pewne metody, które pozwalają tą liczbę zminimalizować, ale póki co się tym nie zajmujemy - na razie chcemy mieć jakiegokolwiek przeciwnika, czyli jakiekolwiek AI.

Przy programowaniu AI zachodzi jeszcze jeden drobny problem - zawsze działa zgodnie z algorytmem, co prowadzi do dużej przewidywalności. Gdy gramy z jakimś graczem kilka razy pod rząd, to zwykle staramy się unikać błędów które ostatnio wykorzystał przeciwnik. Nasz styl gry zmienia się też w zależności od jego taktyki. Sprawia to, że jeśli gramy z żywym nawet kilka razy pod rząd, to za każdym razem rozgrywka jest na swój sposób unikatowa. Jeśli AI nie będzie posiadało tego typu unikalności, to stanie się zbyt przewidywalne i nudne. Aby tego uniknąć, można zastosować 2 rozwiązania:
- Zaprogramowanie kilku zupełnie innych stylów gry które będą zmieniały się z każdym kolejnym meczem lub w trakcie meczu.
- Zaprogramowanie AI tak, aby jego zachowanie było częściowo losowe.
Postawię na drugą opcję, choć może w przyszłości nawet połączę obie.

Skrypt

W skrypcie AI pierwszą wykonaną rzeczą będzie uporządkowanie pól na planszy i kart w losowej kolejności, co sprawi, że AI będzie zachowywało się nieschematycznie. Jeśli jakaś opcja będzie najbardziej opłacalna, to oczywiście zostanie wybrana, ale jeśli będzie remisowała opłacalnością, to będzie wybierana ta z największym losowym numerem.

Najpierw inicjalizuję zmienne:

 int MaxC = GameData.HandSize;
 int SizeX = GameData.MapSizeX;
 int SizeY = GameData.MapSizeY;
 int SizePow = SizeX * SizeY;
 int [] RNG = new int [SizePow];
 int [,] RNGOrder = new int [SizeX, SizeY];
 int [] RNGCardOrder = new int [MaxC];

Zmienne te będą przechowywać nieco skracać nasze funkcje, oraz będą zawierały informacje o tym w jakiej kolejności mają być przeglądane pola/karty. Przypisanie tablicą losowych wartości z jakiegoś zakresu bez powtórzeń jest proste - wystarczy wszystkim elementom tablicy przypisać kolejne liczby, a następnie wystarczy użyć wbudowanej funkcji sortującej:

 for (int x = 0; x < SizePow; x++) {
  RNG [x] = x;
 }
 Array.Sort (RNG);
 for (int x = 0; x < MaxC; x++) {
  RNGCardOrder [x] = x;
 }

 Array.Sort (RNGCardOrder);

Warto tu jednak zauważyć, że tablica z rozmiarem planszy jest przedstawiona jako tablica jednowymiarowa, a do zapisu planszy wszędzie używałem tablicy dwuwymiarowej. Dlatego uzyskane wartości wystarczy przepisać do dwuwymiarowej tablicy.

 for (int x = 0; x < SizeX; x++) {
  for (int y = 0; y < SizeY; y++) {
   RNGOrder [x, y] = RNG [x * SizeY + y];
  }

 }

Teraz deklarujemy zestaw zmiennych do przechowywania informacji o dotychczas najlepszym ruchu.

 int BestValue = -100;
 int BestC = 0;
 int BestX = 0;

 int BestY = 0;

I przechodzimy do analizy każdej kombinacji pól:

for (int c = 0; c < MaxC; c++) { // Sprawdzenie każdej karty
 int Card = RNGCardOrder [c]; // Aby skrócić zapis
 for (int x = 0; x < SizeX; x++) { // Sprawdzenie każdej kolumny planszy
  for (int y = 0; y < SizeY; y++) { // Sprawdzenie każdego wiersza planszy
   if (!SGetTokenExist (x, y)) { // Sprawdzenie, czy pole jest wolne
    int TempValue = TokenValue (Card, PNumber); // Wartość ruchu
    // Uwzględnienie siły umiejętności
    for (int z = 0; z < AbilitySize (Card, PNumber); z++) { // Sprawdzenie każdego pola na które wpływa umiejętność
     int cx = x + AbilityX (Card, z, PNumber);
     int cy = y + AbilityY (Card, z, PNumber);
     if (CheckWithMap (cx, cy)) { // Sprawdzenie czy nie wyszliśmy poza planszę
      switch (AbilityType (Card, PNumber)) { // Wybranie metody sprawdzania efektu umiejętności na podstawie jej rodzaju
       case 1: // Umiejętność typu 1
        if (SGetTokenExist (cx,cy)) { // Sprawdzenie czy na polu objętym umiejętnością jest jakiś żeton
         if (SGetTokenPlayer (cx, cy) == PNumber) { // Sprawdzenie czy żeton należy do nas
          TempValue -= 1;
         } else {
          TempValue += 1;
         }
        }
       break;
     }
   }
   if (TempValue > BestValue || (TempValue == BestValue && RNGOrder [x, y] > RNGOrder [BestX, BestY])) { // Sprawdzenie, czy jest to opcja z najwyższym numerem spośród najlepszych opcji
     BestValue = TempValue;
     BestC = Card;
     BestX = x;
     BestY = y;
     }
    }
   }
  }

 }

W tej grze będzie wiele rodzai umiejętności, a więc każdy żeton będzie sprawdzany inaczej. Fragment kodu można podzielić na wiele części i do każdej części dodać osobny warunek if, który będzie sprawdzał, czy ten fragment kodu powinien być realizowany w danej chwili. Jednak pisanie wielu niemal identycznych ifów może być z czasem irytujące, więc w takich sytuacjach warto jest korzystać z przełącznika switch, który realizuje inny fragment kodu, w zależności od wprowadzonego parametru.

Na podstawie indeksów które otrzymaliśmy w wyniku testu używamy określonej karty żetonu na określonym polu, do czego posłużyłaby ta sama funkcja, z której normalnie korzysta gracz.

Na co trzeba jeszcze zwrócić uwagę:
- Gra operuje na systemie kont, a więc powinien on być dostosowany w taki sposób, aby mogło z niego korzystać także AI i było ono możliwe do rozpoznania,
- Gra powinna pomijać tworzenie elementów graficznych dla AI (plansza, żetony, efekty itd.),- Podłączenie się AI do gry nie powinno zapisywać na kliencie informacji o jego koncie (co mogłoby spowodować np. uznanie gracza za AI),
- AI powinno wykonać ruch po każdym ruchu gracza - tutaj warto dodać jakiś warunek który sprawi, że AI nie będzie wykonywało ruchu po samym sobie.
- Ruch AI powinien być opóźniony, aby sytuacja na planszy była dla gracza bardziej czytelna.

W przyszłości AI będzie rozbudowywane i będą dodawane nowe poziomy trudności.