Czy twój bitewniak jest zrównoważony?

Poza tym, że rzeźbię sobie kod lubię czasami pograć w gry bitewne. Teraz mam już na to bardzo mało czasu, ale kiedyś było tego więcej. Obecnie z hobby pozostało tylko malowanie ludzików, a i to nie za często.
Niemniej jednak nadal staram się śledzić co dzieje się w świecie. Oznacza to też czytanie blogów. Ostatnio trafiłem na wpis na blogu MX Site poświęcony Prawu Kwadratów Lanchestera (PKL). Jest to chyba najprostszy model pola walki jaki istnieje. Oczywiście na poziomie intuicyjnym. Matematyka to inna inszość… co i jak w oryginalnym poście.

Mnie jednak zastanowiło czy można za pomocą tego prawa w jakiś sposób określić zrównoważenie gry bitewnej. Wszystko w dużym uproszczeniu.

Wprowadzenie teoretyczne do gry

By sprawdzić czy gra jest dobrze zrównoważona za pomocą PKL należy tak dobrać walczące strony by miały równą siłę ognia i liczebność…
Rozpatrzmy walkę dwóch oddziałów Space Marines po 10 żołnierzy w każdym. Nazwijmy je siłami Alfa i Beta. Walkę będziemy rozpatrywać na bazie reguł szóstej edycji W40k (nie mam podręcznika do 7).
Mechanika gry jest oparta o tzw. rzuty kaskadowe. Inaczej mówiąc o rezultacie starcia decyduje seria rzutów tu są to:

  • Rzut na trafienie – reprezentuje umiejętności strzelającego.
  • Rzut na zranienie – reprezentuje siłę ognia broni.
  • Rzut na pancerz – reprezentuje poziom ochrony obrońcy.

W tym modelu by rozstrzygnąć starcie atakujący wykonuje dwa rzuty, a obrońca jeden. Przykładowo Alfa strzela 10k6 (10 kości 6-ściennych), trafia 5 (na pięciu kościach uzyskał wynik większy bądź równy oczekiwanemu). Następnie rzuca na zranienie 5k6 i rani 3 (3 kości >= oczekiwany). Obrońca rzuca 3k6 na pancerz i jeden rzut jest nieudany (wyrzucił mniej oczek niż oczekiwana). Jeden model jest zdejmowany z pola bitwy.

Następnie strony zamieniają się rolami.

Innym rodzajem mechaniki jest mechanika oparta o rzuty przeciwstawne. W jej przypadku każda ze stron wykonuje jeden rzut i modyfikuje go cechami modelu. Takie rozwiązanie wymaga wprowadzenia innego niż równomierny rozkładu prawdopodobieństwa dla wyników rzutu.

Chwila analizy

Już na pierwszy rzut oka widać, że gra nie będzie zrównoważona. Strona broniąca się poniesie straty w pierwszej turze rzutów i jak stanie się stroną atakującą to będzie „na dzień dobry” miała mniejszą siłę ognia.
Dlatego PKL jest tu dobrym narzędziem 🙂 Ponieważ pozwala na porównanie czy nasz system turowy zbliża się do „świata rzeczywistego” gdzie oddziały walczą symultanicznie (wszyscy na raz strzelają).

Rezultaty

Kod możecie sobie pobrać z Githuba. Nas interesuje to rezultat końcowy.

Ogólnie przeprowadziłem 1000000 (milion) symulacji walki. Strona Alfa to atakujący, a Beta broniący. Obie strony to 10 osobowe oddziały SM. Walkę prowadzimy do ostatniego żołnierza.

PKL: ALPHA wins 566 658 times
PKL: BETA wins 433 342 times

Co oznacza, że w około 43% przypadków strona broniąca się ma szansę na zwycięstwo. W40k jest nieźle zrównoważonym systemem… no dobra, zmieńmy trochę liczebność oddziałów. Pytanie brzmi co stanie się gdy zwiększymy liczbę obrońców o 2.

Walka 10:12

PKL: ALPHA wins 277 896 times
PKL: BETA wins 722 104 times

Zatem nie opłaca się atakować przeciwnika silniejszego raptem o 20%. Kolejnym testem jest określenie jak wyposażenie wpływa na wynik walki. W tym celu wyposażę jednego z obrońców w ciężki bolter.

PKL: ALPHA wins 558 199 times
PKL: BETA wins 441 801 times

Dużo to nie dało. Jednak zawsze coś. Po dodaniu kolejnego ciężkiego boltera:

PKL: ALPHA wins 536 463 times
PKL: BETA wins 463 537 times

Co już pozwala na kombinowanie. Nie wiem jakie są obecnie limity broni ciężkiej w oddziale, ale jak podejrzewam można tu trochę ugrać. Szczególnie, że model nie uwzględnia modyfikatorów.

Wnioski

Gra okazuje się całkiem nieźle zrównoważona. Co prawda intuicja podpowiada, że strona atakująca powinna mieć znaczą przewagę, ale w praktyce okazuje się, że kaskadowe rzuty niwelują ją do rozsądnych granic. Jeżeli zatem w trakcie gry okazuje się, że wybitnie ci nie idzie… zmień kostki 😉

6 myśli na temat “Czy twój bitewniak jest zrównoważony?

  1. Fajno! Choć kodu jeszcze nie miałem czasu przeglądnąć. Co do samego eksperymentu, to tylko taka uwaga. Wybrałeś przykład, gdzie obie strony nie różnią się statsami tylko liczebnością i liczbą kostek ataku (o ile pamiętam Heavy Bolter dodaje więcej rolli z tą samą siłą i skutecznością). W związku z tym, dało się to jak najbardziej obliczyć z równań Lanchestera, gdzie siła jednego gostka to ~ prawdopodobieństwo wounda. Dużo ciekawszym przykładem, który pozwoliłby rozwinąć skrzydła symulatorowi jako modelowi quasi-stochastycznemu byłby pojedynek zupełnie różnych ekip. Sam heavy bolter to słaby special przeciw marinsom. Spróbuj z plazmą albo grav-gunem 🙂

  2. kod pisany był na szybko i jest mocno kulawy. Nie chciałem robić wyliczanek ponieważ brakuje w nich czynnika losowości, ale nie takiego matematycznego, a z życia. Zakładając, że generator losowy jest obarczony podobną wada jak kostki do gry to można się pobawić w klepanie kodu.
    Z plazmą/gravgunem sprawdzę jak wygrzebię się z chamberconfu

  3. Zajrzałem do kodu. Nie jestem programistą Javy, ale kudos za lambdę i fluentową składnię 🙂

  4. Jak chcesz zobaczyć co i jak to zapraszam na TechCampa. Będzie 14 we Wro. Trochę o funkcyjnym w Javie będzie. Jak jesteś techniczny to będzie fanie się słuchało 🙂
    Poza tym muszę w końcu poznać społeczność grającą we Wro, bo choć do Boltera zaglądam to jakoś nie mam z kim pograć.

    BTW, ty pracujesz w CounteStraiku?

  5. Z tego co widzę, to moja strona mocy będzie 15.04 🙂 Ale dzięki za zaproszenie! 🙂 Ja częściej do planszóweczki zaglądam – bliżej mam, ale też jestem raczej na bakier ze społecznością grającą.

Napisz odpowiedź

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *

To create code blocks or other preformatted text, indent by four spaces:

    This will be displayed in a monospaced font. The first four 
    spaces will be stripped off, but all other whitespace
    will be preserved.
    
    Markdown is turned off in code blocks:
     [This is not a link](http://example.com)

To create not a block, but an inline code span, use backticks:

Here is some inline `code`.

For more help see http://daringfireball.net/projects/markdown/syntax