Wprowadzenie

W niniejszym artykule spróbujemy zastanowić się nad zagadnieniami rachunku prawdopodobieństwa w RPG. Nie ma się jednak co obawiać, podejdziemy do zagadnienia wcale nieklasycznie, czyli bez wzorów, znienawidzonego powszechnie (acz niesłusznie) twierdzenia Bayesa czy rozkładu Bernoulliego. Innymi słowy, spróbujemy ugryźć rzecz doświadczanie, a nie teoretycznie. Jako laboratorium badawcze wystarczy nam zwykły Excel, ponieważ zakładam, że jest to narzędzie, które jest większości z Was dostępne. Oczywiście, jeśli ktoś lubi, może sobie wykorzystywać C++ Buildera czy Visual Studio. Dodam tylko, że zmuszony koniecznością korzystałem z polskiej wersji Excela XP (szczególnie traumatyczne są dla mnie polskie nazwy funkcji matematycznych).

Podejście doświadczalne ma tę zaletę, że nie wymaga od nas praktycznie żadnej wiedzy teoretycznej - obejdzie się więc bez wzorów. Jest to jednak równie ważna i uprawniona metoda "badawcza" (niezależnie od tego jak bardzo kręcą na nią nosem teoretycy). O jej istotności niech przekona Was następująca anegdota (podobno dotyczy jednej z bardziej znanych polskich uczelni):

Pewna studentka wykazywała zadziwiającą odporność na wiedzę z metod probabilistycznych. Profesor, który wykładał ten przedmiot, był człowiekiem spokojnym i dobrotliwym (inaczej mówiąc, nie należał do Nazguli Politechniki), więc poszedł na rękę owej dziewczynie i pozwolił jej na kolejny ustny dopyt. Po zadaniu kilku pytań, przekonał się jednak, że studentka najwyraźniej nie opanowała nawet początku pierwszego rozdziału skryptu i co chwila gubi się w "zeznaniach". W końcu zrezygnowanym ruchem przerwał nieszczęsnej podejrzane mamrotania na temat rozkładu Poissona, westchnął cicho i - litościwie patrząc na miałkość prezentowanej wiedzy - zaproponował:
- Wie pani co? Zostawmy te skomplikowane wzory, proszę mi tylko odpowiedzieć na jedno proste pytanie. Jeśli uda się pani, wstawię pani trójczynę za wytrwałość i będziemy to mieli za sobą. Pytanie jest proste: ile wynosi prawdopodobieństwo wyrzucenia jedynki na kostce do gry? (Pytanie jest oczywiście nieprecyzyjne, ale można założyć, że chodziło o D6.) ;-)
Rozkojarzona i zmęczona dwugodzinnym przesłuchaniem studentka palnęła prosto z mostu:
- Jeden.
Profesorowi pociemniało w oczach, ale że był przyzwyczajony do traumy prowadzenia wykładów na niższych latach, policzył szybko cicho do dziesięciu milionów, ochłonął i spytał ponownie:
- Jest pani tego pewna?
Wiadomo, w takich przypadkach większość zdających wietrzy straszliwy podstęp egzaminatora (i odrzuca rękę wyciągniętą na pomoc). Studentka poszła więc w zaparte:
- Oczywiście. Tak. Jeden.
Profesor wytarł spocone czoło i sięgnął do szuflady po przygotowaną do takich sytuacji d-szóstkę.
- No, dobrze - rzekł - niech pani rzuci.
Studentka posłusznie poturlała kostkę. Wypadło 1.
- Hmmm ... - mruknął profesor - a może pani jeszcze raz spróbować?
Znowu pojawiło się jedno oczko. Profesor westchnął.
- No dobra, ale zróbmy próbę jeszcze jeden raz.
Kiedy ujrzał wynik, pokręcił głową z niedowierzaniem, uśmiechnął się, po czym stwierdził, że może jednak dziewczyna ma rację i wpisał do indeksu obiecaną ocenę.

Zostawmy jednak akademickie rozważania i przejdźmy do naszego RPG. Wyobraźmy sobie, że mamy dwie postacie, które planujemy zderzyć ze sobą. Jak ocenić, która z nich ma większe szanse na zwycięstwo?

Przykład
(zastosowano mechanikę na pograniczu WFRP i WFB)

Nasz ludzki bohater, WS:4, S:3, T:5 bije się z opancerzonym Orkiem WS:3, S:4, T:6. Zakładamy roboczo, że oba charaktery są jednowoundowe i mają akurat tyle czasu, żeby wymienić po jednym ciosie. Jakie są szanse zwycięstwa? Oczywiście, można spróbować zapisać zadanie w postaci wzoru, ale po co się męczyć - lepiej wykonać jakiś tysiąc prób i zobaczyć w ilu z nich odniesiemy sukces. Nie zachęcam jednak do własnoręcznego turlania kostek - lepiej wykorzystać w tym celu nasz komputer.

Excel pozwala nam uzyskać liczbę losową z przedziału <0,1) za pomocą formuły LOS(). Jeśli chcemy uzyskać liczbę z zakresu 1-6 musimy zastosować następujący wzór: 6*LOS()+1. Najlepiej jeszcze zaokrąglić wynik do wartości całkowitych, więc ostatecznie formuła przyjmie postać =ZAOKR.W.DÓŁ(6*LOS()+1;1). Czy aby na pewno? Dlaczego jednak nie użyć formuły ZAOKR(5*LOS()+1;0)? Sprawdźmy. W tym celu oszacujemy sobie, jak dobrze nasz generator daje liczby losowe. Innymi słowy - jak "dobra" jest nasza Excelowa kostka D6.

Ocena jakości generatora losowego. Formuły tablicowe.

Rzucamy kilkadziesiąt razy kostką. Wygodnie byłoby sprawdzić, ile rzuciliśmy jedynek, dwójek itd. Można to robić na piechotę, ale Excel ma wbudowaną funkcję CZĘSTOŚĆ, która robi to wszystko za nas. Formuła ta podaje, ile było wystąpień określonych wartości w podanym zakresie. Jedyny niuans związany z jej użyciem to fakt, że jest to tzw. formuła tablicowa.

Co to jest formuła tablicowa? Jest to taka funkcja matematyczna, której wynikiem jest nie pojedyncza liczba, ale wiele liczb. Matematyk powiedziałby, że jest to odwzorowanie na obiekt wieloelementowy (dokładnie - na ciąg - nie na zbiór, bo w tym ostatnim kolejność elementów nie ma znaczenia). Jeśli się nad tym zastanowimy, to taki "wieloelementowy" wynik musi być jakoś inaczej zapisywany w Excelu - nie można po prostu wstawić formuły do kolejnych komórek - bo się naszemu arkuszowi pomyli z "normalnym trybem" wprowadzania formuł.

Porównajmy:

Formuła ŚREDNIA pobiera jeden argument typu zakres danych i wylicza (w żargonie matematyków i informatyków: "zwraca") pojedynczą liczbę. Możemy to zapisać:
ŚREDNIA(zakres) -> liczba

Formuła CZĘSTOŚĆ pobiera dwa argumenty typu zakres danych i zwraca wynik również w postaci kilku liczb (będzie ich oczywiście tyle, ile elementów liczy drugi zakres). Możemy to zapisać:
CZĘSTOŚĆ (zakres;zakres) -> zestaw liczb

W Excelu wyglądać to będzie tak:


przykład zastosowania tej samej formuły, powtórzonej w kilku komórkach,
do liczenia kilku wartości


przykład zastosowania formuły tablicowej

Żeby się Excelowi nie pomyliło, Microsoft przewiduje inny sposób wprowadzania formuł tablicowych (w ten sposób myli się użytkownikowi, a nie Excelowi). Jeśli mamy w komórkach A2:A8 zestaw danych do badania częstości, a w komórkach B2:B8 - liczby, których częstość występowania będziemy badać, to teraz zaznaczamy ("zaczerniamy") obszar, do którego będzie wprowadzany wynik (w moim przypadku C2:C8) i w pasku formuły wprowadzamy:


sposób wprowadzania formuły tablicowej

UWAGA! Na końcu linii nie naciskamy ENTER, ale SHIFT+CTRL+ENTER! W ten sposób mówimy Excelowi, że formuła ma być tablicowa, co zostanie uwidocznione przez automatyczne dołożenie po lewej i prawej stronie nawiasów klamrowych.

Teraz czas na przetestowanie naszego generatora losowego. Zajrzyjcie do załączonego arkusza Excela, na zakładkę "Przykład liczenia częstości". Jest to gotowe narzędzie badające własności naszej kostki D6. Jeżeli ustawicie się w dowolnej pustej komórce i naciśniecie klawisz "DEL", zobaczycie, jak zmienia się kolumna "rzut D6" - za każdym razem wykonywane jest 100 rzutów.

Można całkiem miło spędzić czas (znam ludzi, którzy uważają to za fascynujące...), patrząc, jak zmieniają się liczby w tabelce. Dla nas na razie najważniejsze jest:

1. Ilość wystąpień danej liczby oczek (czyli ile razy wypadły dwa, trzy oczka itp.) - pola D5:D10. Oczywiście na "dobrej" kostce, liczba rzutów powinna oscylować w granicach 20 - częste powtarzanie innych wyników świadczy, że nasza kostka ma "opiłowane ścianki". Aby jeszcze wyraźniej pokazać tę wartość spójrzmy na kolumnę "odchylenie" (F2:F10). Jest to różnica pomiędzy teoretyczną liczbą prób w których wypadła "szóstka" (albo inny wynik), a liczbą prób zanotowanych w doświadczeniu. Im więcej - tym gorzej dla kostki. Oczywiście MOŻE się zdarzyć próba, w której odchylenie wyniku jest nawet 15 - ale nie powinno się to zdarzać nagminnie. Podsumowanie "odchyleń dla wszystkich wyników" zawiera komórka F11. Im wyższa jest ta liczba, tym bardziej "niesprawiedliwy" jest nasz eksperyment stukrotnego rzutu kością.
2. wartość średnia eksperymentu - pole F13. Ta wartość w teorii wynosi oczywiście 3.5. Jeśli widzicie, że kolejne eksperymenty najczęściej są powyżej tej wartości - znaczy, że nasza kostka "przekłamuje do góry" - i odwrotnie.
3. najczęstsza wartość - zrozumiałe samo przez się. Jeśli sprawdzicie drugą formułę losowania liczby z niniejszego artykułu (patrz wyżej), ze zdziwieniem zauważycie, że najczęściej pojawiająca się liczba to prawie zawsze 2,3,4 lub 5. Inaczej mówiąc nasz "alternatywny" generator trochę oszukuje i "nie kocha" wartości skrajnych.

Symulacja walki w Excelu

Wróćmy do naszego przykładu. Przypomnijmy, że mamy dwóch bohaterów:


  WS S T W
Ork 3 4 6 1
Człowiek 4 3 5 1

W naszej sytuacji dokonamy sobie paru założeń upraszczających. Takie podejście jest znane w naukach eksperymentalnych (doświadczalnych) i jest absolutnie uprawnione, o ile przyjęte założenia nie naruszają zbytnio logiki zjawiska. Często też stosuje się metodę iteracyjną, polegającą na tym, że najpierw przyjmuje się bardzo "silne" założenia (czyli dające bardzo zgrubne przybliżenie), a potem stopniowo odrzuca się najbardziej "krępujące" z nich.

Po pierwsze, zakładamy że nasze postaci mają tylko 1 wound. Przewidujemy, że łatwość zwycięstwa w takim "równym" pojedynku będzie zbliżona do łatwości zwycięstwa postaci wielowoundowych (to tak jakby powtarzać kilkakrotnie tę samą walkę, bo liczba otrzymanych ran nie wpływa na parametry postaci).

Po drugie - uznajemy, że obie postacie atakują jednocześnie. Takie założenie to nic innego, tylko odrzucenie parametru Ini i dodatkowych atrybutów związanych z szarżą.

Po trzecie - rozgrywana jest tylko jedna runda walki. To założenie jest podobne w mechanizmie do założenia pierwszego.

Zajrzyjmy do naszego Excela, na zakładkę "Ork kontra Człowiek - I". Mamy tu przeprowadzonych 1000 symulowanych pojedynków - każda akacja na arkuszu (naciśnięcie DEL na pustej komórce) powoduje wygenerowanie nowych wyników.

Arkusz skonstruowany jest następująco:

W polach B11-B1010 znajduje się 1000 rzutów kostką D6, wygenerowanych metodą pokazaną wyżej. Ork podczas walki rzuca na trafienie ("to-hit") i na zranienie ("to-wound").

Aby trafić, musi rzucić liczbę mniejszą lub równą swojemu WS (aby ułatwić sobie pracę na arkuszu - komórki z tabeli charakterystyk postaci otrzymały własne nazwy - nie ma problemu z ich adresowaniem). Obrazuje to formuła w kolumnie F:

=JEŻELI(B11<=pWS1;"HIT";"MISS")

czyli:

jeżeli wartość z komórki B11 (rzut to-hit w pierwszej próbie orka) jest mniejszy lub równy zawartości komórki pWS1, to w polu F11 jest wstawiana wartość HIT. W przeciwnym razie - wartość MISS.

Aby zranić, Ork musi mieć za sobą zdany test na trafienie, a ponadto wyrzucić na D6 liczbę, która zsumowana z jego siłą (S) przewyższy wytrzymałość człowieka (T).

=JEŻELI(F11="HIT";JEŻELI(C11+pS1>pT2;"WOUND";"no damage");"no damage")

Jeżeli F11 zawiera informację o trafieniu, to wtedy sprawdzamy, czy C11 (rzut D6 na zranienie) dodane do siły Orka jest większe od wytrzymałości Człowieka. Jeśli tak, to wynikiem jest WOUND, a jeśli nie - "no damage". Dodajmy, że jeśli F11 NIE ZAWIERA wartości HIT, to od razu wynikiem naszej formuły jest "no damage".

W analogiczny sposób losują się testy człowieka.

W kolumnie J odbywa się podsumowanie wyniku za pomocą dwustopniowej formuły JEŻELI. Wyniki kodowane są następująco (robimy to po to, aby łatwiej je było analizować statystycznie):
1 - ork wygrał
2 - człowiek wygrał
3 - obaj walczący zadali sobie śmierć
4 - starcie nierozstrzygnięte

Formuła realizująca kodowanie wygląda następująco:

=JEŻELI(G11="WOUND";JEŻELI(I11="WOUND";4;1);JEŻELI(I11="WOUND";2;3))

JEŻELI Ork zadał ranę, to wynikiem walki jest zwycięstwo Orka (1) lub obustronna śmierć (4). Jeżeli Ork nie zadał rany, to wynikiem jest zwycięstwo Człowieka (2) lub starcie nierozstrzygnięte (3).

Na koniec odbywa się podsumowanie wyników w tabeli na górze arkusza, gdzie zlicza się liczby wyników za pomocą formuły LICZ.JEŻELI:

=LICZ.JEŻELI(J11:J1010;"=1")

Oczywiście, można też budować znacznie bardziej skomplikowane symulacje, aczkolwiek wymaga to już trochę większej pracy. Spróbujmy wyobrazić sobie pojedynek, który może trwać wiele rund, przy czym obie postacie mają zarówno wiele woundów - model takiego starcia zawiera zakładka Ork kontra Człowiek II:

Mamy dwóch bohaterów,


  WS S T W
Ork 3 4 6 10
Człowiek 4 3 5 7


Popatrzmy, jak budowana jest formuła określająca sposób walki. Jeżeli w danej rundzie liczba woundów postaci jest równa lub mniejsza 0, to postać zadaje przeciwnikowi 0 ran (bo nie żyje). Jeżeli jednak postać ma aktualny poziom woundów większy od 0, to sprawdzamy, czy trafiła i jeśli tak, to losujemy czy zadała rany (jeśli postać nie trafia, to oczywiście nie zdaje ran). Dalej, jeśli zdała rany - to określamy ich liczbę. Ufff ... w każdym razie na koniec takiej procedury wiemy już ile ran zadała postać w danej rundzie.

Do takiej formuły dodajmy jeszcze jedno JEŻELI - wszak jeśli przeciwnik już nie żyje, nasz bohater nie powinien pastwić się nad jego trupem. Ostatecznie, w każdej rundzie, liczba zadanych ran wyraża się formułą:

Dla Orka:

=JEŻELI(D7>0;JEŻELI(C7<=0;0;JEŻELI(E7>pWS1;0;JEŻELI(F7+pS1-pT2>0;F7+pS1-pT2;0)));0)

Dla człowieka:

=JEŻELI(C7>0;JEŻELI(D7<=0;0;JEŻELI(H7>pWS2;0;JEŻELI(I7+pS2-pT1>0;I7+pS2-pT1;0)));0)

W ten sposób, pozostaje nam już tylko sama przyjemność: określenie, że liczba woundów postaci to liczba z poprzedniej rundy pomniejszona o rany zadane przez przeciwnika. Żeby było elegancko, dodajmy, że jeżeli postać ma minusowe woundy, to uznajemy, że są po prostu zerowe (nikt nie jest "bardziej martwy"). Jeśli zajrzycie do arkusza, do komórek C8:C26, to zobaczycie tam jak ten mechanizm stosuje się w praktyce.

Oczywiście, ten przykład to tylko JEDNO starcie, aby przeprowadzić sensowny eksperyment, trzeba takich prób znacznie więcej - podobnie jak w poprzednim podejściu. Myślę jednak, że zarysowana metoda pozwoli Wam na samodzielne rozwiązanie tego zagadnienia (być może w lepszym narzędziu niż Excel).

Podsumowanie

Zaproponowany przeze mnie sposób to nic innego jak ocena prawdopodobieństwa na podstawie przeprowadzonych doświadczeń. Jest to metoda równie dobra jak analiza teoretyczna, pod warunkiem, że przyjęte zostaną sensowne założenia (innymi słowy: stworzymy dobry model probabilistyczny zjawiska) oraz że wykonamy wystarczająco wiele prób. Nasze doświadczenia raczej nie dadzą nam dokładnego wyniku, ale dla naszych celów wystarczy, że będziemy orientować się, że np. nasz bohater ma mniej-więcej 70% szans na przeżycie starcia. Tego typu rozważania mogą pomóc w odpowiednim balansowaniu scenariusza, ale oczywiście nie zastąpią elastycznego MG, który zawsze może przecież wyciągnąć jakiś trick z rękawa.

Gracz: "... ale przecież ...demony boją się amuletu Xinditha?!?!"
MG: "TEN najwyraźniej nie."

Miłego turlania w Excelu,
Rhah Wynn

link do pliku Excela (zip, 235 kB)