Zadaniem uczestników Coding Dojo Silesia jest zaimplentowanie konsolowego narzędzia wspomagającego prowadzenie sesji RPG opartych o system CRAM. CRAM jest to jednostronicowy dokument zawierający zbiór reguł i mechanik prostego systemu RPG. W zadaniu należy zaimplementować kompletne zasady systemu z wyłączeniem spalania punktów szczęścia (atrybut LUC) za dodatkowy rzut kością. Dostępne w programie komendy zostały zaprezentowane poniżej.
W systemie CRAM powodzenie wszystkich czynności jest zależne od rzutów standardowymi kośćmi 1d6.
Poniżej znajduje się lista komend, które Mistrz Gry będzie wprowadzał na standardowe wejście programu. Aplikacja powinna każdorazowo powiadomić użytkownika o sukcesie bądź porażce wykonania komendy za pomocą komunikatu wyświetlonego na standardowym wyjściu. Mistrz Gry może stworzyć uczestnika gry, ustawić standardowy modyfikator gry, zakupić ekwipunek uczestnikowi, wykonać atak jednego uczestnika na drugim uczestniku, a także sprawdzić czy uczestnik może wykonać pewną czynność.
Komendą tworzącą uczestnika gry (np. gracza lub potwora) jest:
add ParticipantName x PHY x MEN x VIT x LUC Skill1 Skill2
Uczestnik gry charakteryzowany jest przez 4 atrybuty: PHY, MEN, VIT oraz LUC (szerszy opis atrybutów znajdziesz w opisie systemu CRAM). Mistrz Gry przypisuje uczestnikowi 20 punktów, które rozdysponowuje pomiędzy wyżej wymienione atrybuty. Punktów nie można dzielić, a przypisana do atrybutu liczba punktów nie może być mniejsza od 1 ani większa od 15. Uczestnik otrzymuje również złoto, którego ilość zależy od atrybutu LUC. Liczba złotych monet liczona jest zgodnie z wzorem LUC * 15.
Uczestnik ma dodatkowo przypisane dwie spośród następujących umiejętności: Athletics, Lore, Martial, Medicine, Psionics, Rhetoric, Science, Subterfuge, Survival oraz Vocation (szerszy opis umiejętności znajdziesz w opisie systemu CRAM).
Przykład:
add Johan JQuery 1 PHY 2 MEN 1 VIT 15 LUC Lore Psionics
The Oracle: The being Johan JQuery has been created.
Za posiadane złoto uczestnicy mogą nabywać zdefiniowany ekwipunek.
ParticipantName buys ItemName
Ekwipunek jest podzielony na trzy kategorie: Gear, Weapons oraz Armor. Broń modyfikuje atrybut PHY (broń do walki w zwarciu) lub ma przypisaną stałą (niezależną od atrybutów i umiejętności) liczbę kostek wykorzystywaną podczas ataku (broń do walki na odległość). Pancerz redukuje obrażenia oraz zmniejsza atrybut PHY. Sprzęt jest ogólną kategorią zawierającą przedmioty o niesprecyzowanym działaniu i przeznaczeniu.
Przykład:
Johan JQuery buys ProgrammersRespect
The Oracle: Johan JQuery does not have enough gold.
Mistrz Gry ma możliwość ustalenia poziomu trudności rozgrywanej gry. Wykorzystuje do tego standardowy modyfikator gry, który wpływa na liczbę kości wykorzystywaną podczas ataku oraz sprawdzenia zdolności. Standardowe modyfikatory mają następujące nazwy i wartości:
- trivial: +5,
- easy: 0,
- moderate: -5,
- difficult: -10,
- nearly impossible: -15.
Komenda zmieniająca trudność gry ma postać:
set difficulty StandardModifier
Przykład:
set difficulty nearly impossible
The Oracle: The world is now a better place.
Uczestnicy gry mogą się atakować. Atak kończy się redukcją atrybutu VIT uczestnika atakowanego, a gdy wartość atrybutu VIT uczestnika jest mniejsza niż 1 zostaje on uznany za martwego i nie bierze udziału w dalszej grze.
AttackerName attacks PreyName
Zadane obrażenia równe są liczbie jedynek, które wypadły na rzuconych kostkach. Liczba rzucanych kostek zależy od posiadanego przez uczestników ekwipunku oraz ich atrybutów i umiejętności. Atak może być atakiem w zwarciu lub z dystansu, ocenianie są obie możliwości i wybierana jest ta, która ma większą liczbę kostek. Patrz poniższy pseudokod:
liczbaKostek :=
atrybut PHY uczestnika atakujacego
+ modyfikatory wszystkich posiadanych broni do walki wrecz
+ jezeli atakujacy posiada umiejetnosc 'Martial' dodaj 1
if (liczba kostek jest mniejsza o liczby kostek wynikajacych z posiadanych broni do walki na odleglosc) {
liczbaKostek := liczby kostek wynikajacych z posiadanych broni do walki na odległosc
}
Otrzymana liczba kostek jest modyfikowana za pomocą standardowego modyfikator gry:
liczbaKostek := liczbaKostek + standardowyModyfikator
Program wykonuje symulację rzutów kostkami i bada liczbę wyrzuconych jedynek:
wykonaj rzut kostkami wg. uzyskanej liczby kostek
liczbaJedynek := liczba wyrzucanych jedynek
Finalne obrażenia zadane uczestnikowi atakowanemu są zmniejszane o wartość redukcji obrażeń:
obrazenia := liczbaJedynek - redukcja obrazen wynikajaca z pancerzy uczestnika atakowanego
if (obrazenia > 0) {
zmniejsz atrybut VIT uczestnika atakowanego o wartosc obrazen
}
W czasie gry, Mistrz Gry może poddać próbie uczestnika za pomocą mechanizmu sprawdzenia zdolności. Mistrz Gry określa które atrybuty oraz umiejętności zostaną wzięte pod uwagę przy sprawdzeniu zdolności. Komenda sprawdzająca ma następującą formę:
check ability Name ATR1 ATR2... [Skill1 Skill2...]
Liczba kostek zależy od wartości przypisanej do podanych w komendzie atrybutów oraz posiadanych umiejęstności:
atrybut := wybierz atrybut z najmniejsza liczba przypisanych punktow z listy atrybutow przekazanych w komendzie
if (uczestnik gry posiada co najmniej jedna z umiejetnosci przekazanych w komendzie) {
liczbaKostek := clamp(pobierzPunkty(atrybut), 2, 13)
} else {
liczbaKostek := clamp(pobierzPunkty(atrybut), 1, 7)
}
Otrzymana liczba kostek jest modyfikowana za pomocą standardowego modyfikator gry:
liczbaKostek := liczbaKostek + standardowyModyfikator
Program wykonuje symulację rzutów kostkami i bada liczbę wyrzuconych oczek:
wykonaj rzut kostkami wg. uzyskanej liczby kostek i gdy wypadnie 6 oczek powtorz rzut
if (wszytkie kostki mialy wartosc 5) {
wykonanie czynnosci zakonczone krytyczną porazka
} else if (co najmniej jedna kostka miala wartosc 1) {
wykonanie czynnosci zakonczone sukcesem
} else {
wykonanie czynnosci zakonczone porazka
}
Przykład:
check ability Johan JQuery PHY Lore Medicine
The Oracle: The result: critical failure
Zadanie wzorowane jest doskonałym systemem RPG CRAM, którego autorem jest Rusty Gerard.
Repozytorium zawiera minimalistyczny starter pozwalający na szybkie rozpoczęcie implementacji zadania. W folderze src znajduje się plik prompt.php, który zawiera
niewielki fragment kodu wyświetlający wiadomość powitalną oraz prostą zachętę. Wprowadzony przez użytownika tekst przechowywany jest w zmiennej $input
.
Implementowany kod nie powinien być pozostawiony bez testów jednostkowych (!), w tym celu załączyliści Codeception, które zainstalujesz za pomocą Composera. Przykładowy test znajduje się w katalogu tests.
Aby uruchomić program należy w terminalu wpisać komendę:
php src/prompt.php
Aby uruchomić wszystkie testy należy w terminalu wpisać komendę:
vendor/bin/codecept run unit
Waszym najlepszym przyjacielem powinny być wzorce projektowe oraz mnemonik SOLID. Dobre zaprojektowanie związków w klasach jest kluczowe dla efektywnej implementacji tego zadania. Postarajcie się zainwestować odpowiednią ilość czasu na analizę i projekt kodu Waszego narzędzia.