Obliczanie wydajności dwóch walczących armii


20

Programuję strategiczną grę za pomocą Flasha. Gra działa bardzo podobnie do słynnej gry „Travian”.

Mój problem jest następujący: staram się wyliczyć liczbę żołnierzy utraconych w wyniku walki dwóch armii. Dwie armie mają różne typy jednostek. Niektóre z nich są silniejsze przeciwko innym jednostkom i słabsze przeciwko innym typom.

Jak mogę umieścić ten efekt tych różnic w równaniu walki?

Wydaje się to łatwe, jeśli mają tylko punkty att i def, ale jeśli chodzi o zależność od typu jednostek, jestem zgubiony.


6
Czy wynik twoich bitew powinien być czysto deterministyczny, czy chcesz użyć jakiejś losowości?
sum1stolemyname

4
Nie sądzę, że powinien być oznaczony jako gra wieloosobowa, ponieważ OP nie zapewnia tego - może to być człowiek kontra AI. A przez „zależność od rodzaju”, czy mówimy o klasycznej skale-> nożyce-> papier-> rodzaj skały?
Kaczka komunistyczna

Odpowiedzi:


10

Oprócz poparcia sugestii Amita, by przyjrzeć się równaniom Lanchestera, chcę tylko dodać, że jest to decyzja dotycząca projektu gry, a nie empiryczny fakt, który możemy ci dać. Jeśli chcesz wziąć pod uwagę typ jednostki, musisz zdecydować, co to oznacza. Oznacza to wybranie równania, które obejmuje wszystkie czynniki, które chcesz uwzględnić w grze. Jeśli chcesz, aby piechota była lepsza od kawalerii, musisz zdecydować, co to powinno znaczyć - np. ile kawalerii potrzebujesz, aby wyrównać 100 piechoty? I czy to ważne, kto kogo atakuje? Wydaje się, że sugerujesz, że zwykłe podawanie piechocie i kawalerii różnych wartości ataku i obrony nie jest wystarczająco dobre - dlaczego? Co jeszcze próbujesz przedstawić, czego nie mogą uchwycić tylko te wartości?

Musisz zdecydować, które czynniki chcesz wymodelować w swojej grze, ponieważ wpływają one na sposób, w jaki gracze do niej podchodzą. Mogą one obejmować rozmiar / ilość jednostek, rodzaj jednostki, doświadczenie jednostki (np. Status weterana), efekty terenu i środowiska, różnice między atakowaniem i obroną, jeśli takie istnieją, czy modelować obrażenia i zużycie, czy nie, czy modelować upływ czasu podczas walka, zdolność do wycofania się lub ucieczki (ewentualnie w tym modelowanie morale), ile losowości chcesz w równaniu i tak dalej.

Kiedy już to wszystko wiesz, możesz zastosować kilka podstawowych metod matematycznych. Mógłbyś robić system „szansa na trafienie” runda po rundzie, tak jak wiele RPG, np. system walki d20. Możesz wykonać rzut monetą ważony „atak kontra obrona” w taki sam sposób, jak w oryginalnej grze Civilization. Możesz sprawić, by każda ze stron wygenerowała wynik, dodając atrybuty do liczby losowej, a wygrywa ten, kto uzyska najwyższą wartość. Możesz zezwolić tym systemom na działanie na zasadzie rundy po rundy lub odjąć punkty wytrzymałości, punkty morale lub cokolwiek innego. Każdy system może działać, ale musisz go zrównoważyć tak, jak chcesz. Ostatecznie wybór sposobu modelowania walki jest kluczową częścią projektowania gry i nie jest czymś, co inni mogą ci tylko dać.


Masz całkowitą rację, Kylotan. Zanim zacząłem projektować grę, miałem kilka pomysłów na temat walki. Jednak zadałem to pytanie, pytając, czy istnieje lepszy sposób na zaprojektowanie go i znalezienie najlepszego sposobu na jego wdrożenie. Chyba wygrałem w obu przypadkach :) Mój przyjacielu, czy mógłbyś mi powiedzieć, gdzie mogę znaleźć więcej informacji na temat tych podejść matematycznych? Ponadto, jeśli odpowiem na wszystkie pytania dotyczące wyboru systemu, czy możesz mi doradzić, które z nich najlepiej pasuje do mojej sprawy? Dziękuję bardzo za
poświęcony

Nie mogę ci powiedzieć, który będzie najlepszy, ale prawdopodobnie powinieneś zacząć od prostego i poprawić to, jeśli potrzebujesz. Travian wydaje się mieć prosty system ataku przeciwko obronie, z 2 typami jednostek (piechota i kawaleria) i 2 punktami obrony odpowiednio na jednostkę. Łatwym sposobem rozwiązania bitwy, stosowanym w Civilization 1, jest podzielenie wyniku ataku atakujących przez sumę tego plus wynik obrony obrońcy. To daje ci procent. Teraz wybierz losową liczbę od 0 do 100 procent. Jeśli jest niższy niż wynik ataku atakującego, atakujący wygrywają. W przeciwnym razie obrońcy wygrywają.
Kylotan,

15

W przypadku Solar Realms Elite zainspirowałem się równaniami Lanchestera do modelowania działań wojennych . W każdej rundzie bitwy miałem kilka równoczesnych walk.

W pierwszej walce wszyscy zaatakowali żołnierzy. W SRE żołnierze są najlepsi przeciwko żołnierzom (to nie są papierowe nożyczki, ale piechota, atak powietrzny i kosmos). Ustawiłem siłę ataku i obrony, w której żołnierze mieli najlepszy atak:

attack_strength = 3*soldiers + 1*fighters + 2*cruisers
defense_strength = 10*soldiers

W drugiej walce wszyscy zaatakowali stacje obrony. W SRE myśliwce (powietrzne) najlepiej sprawdzają się przeciwko stacjom obrony (np. Przeciwlotniczym):

attack_strength = 1*soldiers + 4*fighters + 2*cruisers
defense_strength = 25*defense_stations

W trzeciej walce wszyscy zaatakowali ciężkie krążowniki. W SRE ciężkie krążowniki są w kosmosie i najlepiej nadają się do innych ciężkich krążowników:

attack_strength = 1*soldiers + 1*fighters + 10*cruisers
defense_strength = 15*cruisers

(Nie pamiętam, jakich stałych użyłem; to tylko przykłady.) W każdej rundzie bitwy napastnicy tracą część siły obrony, a obrońcy tracą część siły ataku. Uważam, że odpowiada to prawu kwadratowemu Lanchestera (równania tutaj ). Dodałem losowość, ale nie pamiętam dokładnie gdzie. Po każdej rundzie bitwy armie były mniejsze. Maksymalnie ograniczam liczbę rund; potem przegrywająca strona wycofałaby się.

Nie było realistyczne, aby piechota na ziemi strzelała w kosmos, ale działała lepiej ze względu na rozgrywkę, aby wszystkie jednostki mogły walczyć ze wszystkimi innymi jednostkami (ze zmniejszoną skutecznością).


12

Zazwyczaj mówię „jeśli nie możesz znaleźć jednoznacznego rozwiązania, poszukaj rozwiązania domyślnego”. Możesz symulować bitwę wewnętrznie, dopóki jedna armia nie zostanie zniszczona lub wycofa się (w zależności od możliwych wyników twojej gry).

Użyłbym czegoś takiego:

Podczas każdej iteracji bitwy wszystkie jednostki są oportunistyczne, dlatego starają się zadać jak najwięcej obrażeń, jakie mogą. Każda jednostka wybiera jednostkę wroga, którą zamierza zaatakować w tej rundzie, na podstawie znanych zalet / wad.

Następnie przeprowadzane są wszystkie walki podrzędne. Przykład:

Niech włócznicy będą skuteczni przeciwko kawalerii, kawalaje skuteczni przeciwko łucznikom i łucznicy skuteczni przeciwko włócznikom.

W walce między dwiema armiami składającymi się z obu typów tych podstawowych jednostek, wszyscy włócznicy zaatakowaliby kawalerię, wszystkie jednostki kawalerii zaatakowały łuczników, a wszyscy łucznicy zaatakowali włóczników. Gdyby na przykład jedna strona nie miała łuczników, z drugiej strony kawaleria wybrałaby kolejny najlepszy typ celu (będący jednostkami kawalerii wroga)

Każde zdarzenie jednostka-atak-jednostka jest rozpatrywane osobno, a jednostka przegrywająca zostaje uszkodzona lub oznaczona jako zniszczona.

Po rozstrzygnięciu wszystkich pojedynków usuń wszystkie jednostki, które zostały krytycznie uszkodzone lub zniszczone.

Następna iteracja rozpoczyna korzystanie ze zmniejszonych armii.


Naprawdę zgadzam się z tym postem. Lepiej iterować przez bitwę, zamiast sprowadzać ją do jednego równania. I zdecydowanie dodałbym do tego trochę przypadkowości. Zawsze powinna istnieć tak niewielka szansa, że ​​słaby obrońca rzuci się wysoko i zdobędzie krytyczne. Kolejną zaletą iteracji jest to, że możesz stworzyć narrację o wydarzeniach, aby pokazać graczowi. „Szermierze zaatakowali i wkrótce zdziesiątkowali piechurów, ale potem przybyła kalwaria i ...”
Tim Holt

Bardzo podoba mi się twoja odpowiedź i myślę, że
wykonam

3

Testuję wersję beta gry, która jest obecnie prostą wersją Solar Realms ( Star Empire Elite ), i zacząłem od użycia czegoś podobnego do równań Amita (powyżej). W szczególności spodobał mi się pomysł przeprowadzenia trzech faz bitwy, w której musisz wygrać dwie z trzech. Ale chciałem również wprowadzić element losowości do bitwy i na to wpłynęły niektóre gry stołowe.

Przetwarzanie jest problemem, jeśli gra ma być skalowana, więc nie chciałem stosować metody sugerowanej przez sum1stolemyname powyżej, chociaż jeśli twoja gra używa klienta do przetwarzania wyników, w przeciwieństwie do serwera, wydaje się, że jest to dobre podejscie.

Postanowiłem podzielić bitwę na dwie fazy (analogiczne do trzech w modelu Amita): powietrzną i naziemną. Obliczam siłę ataku i obrony, a następnie zmniejszam siłę ataku o ułamek (aby dać obrońcy przewagę). W tym momencie, jeśli siła ataku i siła obrony są równe, atak ma 50% szans na zwycięstwo. Następnie dostosowuję procent szansy na zwycięstwo w górę lub w dół na podstawie tego, o ile więcej (lub mniej) siły atakujący ma w porównaniu do obrońcy. Oto kilka uproszczonych równań dla powietrza:

air_attack_strength = 1 * soldiers + 10 * fighters
air_defence_strength = 2 * soldiers + 25 * stations

differential = (air_attack_strength - air_defence_strength) * constant

chance_of_victory = 50 - differential

Podkreślam, że szansa na zwycięstwo nigdy nie może być większa niż 80 lub mniejsza niż 5. Stamtąd generuję losową liczbę ze 100, a następnie przenoszę ten wynik do bitwy lądowej.

Jedną z rzeczy, których nie rozwiązałem w sposób satysfakcjonujący dla mnie, jest liczba ofiar. Myślę jednak, że dobrym sposobem na rozwiązanie tego problemu byłoby porównanie szansy na zwycięstwo z wygenerowaną liczbą losową i wykorzystanie jej do potraktowania ułamka sił obronnych atakujących.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.