Potrzeba przewidywalnego generatora losowego

Jestem programistą gier internetowych i mam problem z przypadkowymi liczbami. Powiedzmy, że gracz ma 20% szans na trafienie krytyczne swoim mieczem. Oznacza to, że 1 na 5 trafień powinno być krytyczne. Problem w tym, że mam bardzo złe wyniki w realu-czasami gracze dostają 3 Kryty w 5 trafieniach, czasami żaden w 15 trafieniach. Bitwy są dość krótkie (3-10 trafień), więc ważne jest, aby uzyskać dobry rozkład losowy.

Obecnie używam PHP mt_rand(), ale właśnie przenosimy nasz kod do C++, więc chcę Rozwiąż ten problem w nowym silniku naszej gry.

Nie wiem, czy rozwiązaniem jest jakiś równomierny generator losowy, czy może zapamiętanie poprzednich stanów losowych, aby wymusić prawidłowy rozkład.

Author: Thinker, 2009-05-26

30 answers

Zgadzam się z wcześniejszymi odpowiedziami, że prawdziwa losowość w małych seriach niektórych gier jest niepożądana-wydaje się zbyt niesprawiedliwa dla niektórych przypadków użycia.

Napisałem prosty worek Shuffle jak implementacja w Rubim i zrobiłem kilka testów. Implementacja zrobiła tak:

  • jeśli nadal wydaje się sprawiedliwe lub nie osiągnęliśmy progu minimalnego rzutu, zwraca uczciwe trafienie w oparciu o normalne prawdopodobieństwo.
  • Jeśli zaobserwowane Prawdopodobieństwo z poprzednich rolek sprawia, że wydaje się niesprawiedliwe, to zwraca trafienie "fair-ifying".

Jest to uważane za niesprawiedliwe na podstawie prawdopodobieństwa granic. Na przykład, dla prawdopodobieństwa 20%, można ustawić 10% jako granicę dolną i 40% jako granicę górną.

Używając tych ograniczeń, odkryłem, że z przebiegami 10 trafień, 14,2% czasu prawdziwa pseudorandomowa implementacja przyniosła wyniki, które były poza tymi granicami. Około 11% przypadków, 0 trafień krytycznych zostało zdobytych w 10 próbach. 3,3% czasu, 5 lub więcej trafień krytycznych było wylądował na 10. Oczywiście, używając tego algorytmu (przy minimalnej liczbie rzutów wynoszącej 5), znacznie mniejsza ilość (0,03%) przebiegów" Fairish " była poza granicami. Nawet jeśli poniższa implementacja jest nieodpowiednia (z pewnością można zrobić więcej sprytnych rzeczy), warto zauważyć, że zauważalnie często użytkownicy będą mieli wrażenie, że to niesprawiedliwe z prawdziwym pseudorandomowym rozwiązaniem.

Oto moje mięso FairishBag napisane w Ruby. Cała implementacja i szybka symulacja Monte Carlo jest dostępna tutaj (gist) .

def fire!
  hit = if @rolls >= @min_rolls && observed_probability > @unfair_high
    false
  elsif @rolls >= @min_rolls && observed_probability < @unfair_low
    true
  else
    rand <= @probability
  end
  @hits += 1 if hit
  @rolls += 1
  return hit
end

def observed_probability
  @hits.to_f / @rolls
end

Update: użycie tej metody zwiększa ogólne prawdopodobieństwo otrzymania trafienia krytycznego, do około 22% przy użyciu powyższych ograniczeń. Można to zrównoważyć, ustawiając jego" rzeczywiste " prawdopodobieństwo nieco niższe. Prawdopodobieństwo 17,5% przy fairish modification daje obserwowane długoterminowe prawdopodobieństwo około 20% , i utrzymuje krótkoterminowe biegi uczucie sprawiedliwe.

 39
Author: Ian Terrell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-30 21:40:46

Oznacza to, że 1 z 5 trafień powinno być krytyczne. Problem w tym, że mam bardzo złe wyniki w realu-czasami gracze dostają 3 Kryty w 5 trafieniach, czasami żaden w 15 trafieniach.

Potrzebujesz torby shuffle . Rozwiązuje problem prawdziwego losowego bycia zbyt losowym dla gier.

Algorytm jest o tak: umieścić 1 krytyczne i 4 niekrytyczne trafienia w worku. Następnie losujesz ich kolejność w torbie i wybierasz je pojedynczo. Gdy torba jest pusty, wypełniasz go ponownie tymi samymi wartościami i randomizujesz. W ten sposób otrzymasz średnio 1 trafienie krytyczne na 5 trafień, a co najwyżej 2 trafienia krytyczne i 8 trafień niekrytycznych z rzędu. Zwiększ liczbę przedmiotów w torbie, aby uzyskać więcej losowości.

Oto przykładimplementacji (w Javie) ijej przypadków testowych , które napisałem jakiś czas temu.

 222
Author: Esko Luontola,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-09 18:30:35

Masz niezrozumienie co oznacza los.

Która z nich jest bardziej przypadkowa?

Tutaj wpisz opis obrazka Tutaj wpisz opis obrazka

Podczas gdy drugi wykres wygląda bardziej równomiernie, tym bardziej losowy jest rzeczywiście pierwszy wykres. Ludzki umysł często widzi wzorce w przypadkowości, więc kępy na pierwszym wykresie widzimy jako wzorce, ale nie są one-są tylko częścią losowo wybranej próbki.

 113
Author: ceejayoz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-14 19:18:31

Biorąc pod uwagę zachowanie, o które prosisz, myślę, że randomizujesz złą zmienną.

Zamiast randomizować, czy to trafienie będzie krytyczne, spróbuj randomizować liczbę obrotów, aż do następnego trafienia krytycznego. Na przykład, po prostu wybierz liczbę między 2 i 9 za każdym razem, gdy gracz dostaje krytyczne, a następnie dać im kolejne krytyczne po tym wiele rund minęło. Możesz również użyć metod dice, aby zbliżyć się do rozkładu normalnego-na przykład, będziesz zdobądź kolejne krytyczne w 2D4 zakrętach.

Wierzę, że ta technika jest używana w RPG, które mają losowe spotkania w overworld, jak również -- losowo licznik kroków, a po wielu krokach, można dostać ponownie. Wydaje się to o wiele bardziej sprawiedliwe, ponieważ prawie nigdy nie trafiają dwa spotkania z rzędu . jeśli zdarza się to nawet raz, gracze stają się rozdrażnieni.

 88
Author: AHelps,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-26 11:45:40

Najpierw zdefiniuj "właściwą" dystrybucję. Liczby losowe są, cóż, losowe - wyniki, które widzisz, są całkowicie zgodne z (pseudo) losowością.

Rozszerzając to, zakładam, że chcesz mieć poczucie "uczciwości", więc użytkownik nie może przejść 100 obrotów bez sukcesu. Jeśli tak, śledziłbym liczbę porażek od ostatniego sukcesu i ważył wygenerowany wynik. Załóżmy, że chcesz 1 na 5 rolek, aby "odnieść sukces". Więc losowo generujesz liczbę od 1 do 5, a jeśli jest 5, świetnie.

Jeśli nie, zanotuj błąd i następnym razem Wygeneruj liczbę od 1 do 5, ale dodaj na przykład floor (numFailures / 2). Więc tym razem, znowu, mają szansę 1: 5. Jeśli przegrają, następnym razem zwycięska interwał wynosi 4 i 5; szansa na sukces 2 na 5. Dzięki tym wyborom, po 8 porażkach, są pewni sukcesu.

 53
Author: Adam Wright,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-26 11:42:57

Może zastąpienie mt_rand () czymś takim?

Xkcd (RFC 1149.5 określa 4 jako standardową liczbę losową sprawdzoną przez IEEE.)

(RFC 1149.5 określa 4 jako standardową liczbę losową sprawdzoną przez IEEE.)

Z XKCD.

 35
Author: Colin Pickard,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-08 14:07:57

Mam nadzieję, że ten artykuł ci pomoże: http://web.archive.org/web/20090103063439/http://www.gamedev.net:80/reference/design/features/randomness/

Ta metoda generowania 'liczb losowych' jest powszechna w grach rpg/mmorpg.

Problem, który rozwiązuje jest taki (ekstrakt):

Pająk z ostrzem jest przy Twoim gardle. Uderza i spudłujesz. Znowu uderza i znowu chybiasz. I znowu i znowu, dopóki nie zostanie z Ciebie nic do uderzenia. Jesteś martwy i jest dwie tony pajęczynówki napawają się Twoim ciałem. Niemożliwe? Nie. Nieprawdopodobne? Tak. Ale biorąc pod uwagę wystarczającą liczbę graczy i wystarczająco dużo czasu, nieprawdopodobne staje się prawie pewne. To nie było tak, że pająk ostrza był twardy, to był tylko pech. To frustrujące. To wystarczy, aby gracz chciał zrezygnować.

 34
Author: CiscoIPPhone,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-26 02:02:00

To, czego chcesz, nie są przypadkowe liczby, ale liczby, które wydają się przypadkowe dla człowieka. Inni już zasugerowali Indywidualne algorytmy, które mogą Ci pomóc, takie jak Shuffle Bad.

Aby uzyskać dokładną i obszerną analizę tej dziedziny, Zobacz AI Game Programming Wisdom 2 . Cała książka jest warta przeczytania dla każdego twórcy gry, idea "pozornie przypadkowych liczb" jest omówiona w rozdziale:

Filtrowana losowość dla decyzji SI i gry Logika :

Streszczenie: konwencjonalna mądrość sugeruje, że im lepszy generator liczb losowych, tym bardziej nieprzewidywalna będzie Twoja gra. Jednak zgodnie z badaniami psychologicznymi, prawdziwa przypadkowość w krótkim okresie często wydaje się zdecydowanie nierandom dla ludzi. Ten artykuł pokazuje, jak podejmować losowe decyzje AI i logika gry wyglądają bardziej losowo dla graczy, przy jednoczesnym zachowaniu silnej losowości statystycznej.

Możesz również znaleźć inny rozdział ciekawe:

Statystyki liczb losowych

Streszczenie: liczby losowe są najczęściej wykorzystywane przez sztuczną inteligencję i ogólnie gry. Ignorowanie ich potencjału to uczynienie gry przewidywalną i nudną. Używanie ich nieprawidłowo może być tak samo złe,jak ich ignorowanie. Zrozumienie sposobu generowania liczb losowych, ich ograniczeń i możliwości może usunąć wiele trudności z ich wykorzystaniem w grze. Ten artykuł oferuje wgląd w liczby losowe, ich generowanie i metody oddzielania dobrych od złych.

 19
Author: Suma,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-27 07:40:59

Na pewno dowolne generowanie liczb losowych ma szansę wytworzyć takie przebiegi? Nie dostaniesz wystarczająco dużej próbki w 3-10 rolkach, aby zobaczyć odpowiednie procenty.

Może to, czego chcesz, to próg Miłosierdzia ... pamiętaj o ostatnich 10 rolkach, a jeśli nie mieli trafienia krytycznego, daj im gratis. Wygładzić zawiesia i strzały przypadkowości.

 8
Author: James,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-26 11:37:20

Najlepszym rozwiązaniem może być testowanie gry z wieloma różnymi schematami Nie i wybranie tego, który sprawi, że gracze będą najszczęśliwsi.

Można również spróbować Zasady odwrotu dla tej samej liczby w danym spotkaniu, np. jeśli gracz rzuca 1 w pierwszej turze. Aby uzyskać kolejny 1 muszą rzucić 2 1s pod rząd. Aby uzyskać trzeci 1 potrzebują 3 w rzędzie, ad infinitum.

 8
Author: Hank Gay,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-26 12:05:52

Niestety to, o co prosisz, jest w rzeczywistości nie-losowym generatorem liczb - ponieważ chcesz, aby poprzednie wyniki były brane pod uwagę przy określaniu następnej liczby. Obawiam się, że nie tak działają generatory liczb losowych.

Jeśli chcesz, aby 1 z każdego 5 trafień było krytyczne, po prostu wybierz liczbę z zakresu od 1 do 5 i powiedz, że to trafienie będzie krytyczne.

 7
Author: samjudson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-26 11:36:11

Mt_rand() opiera się na implementacji Mersenne Twister, co oznacza, że daje jedną z najlepszych dystrybucji losowych, jakie można uzyskać.

Najwyraźniej to, czego chcesz, nie jest przypadkowością, więc powinieneś zacząć dokładnie określać, czego chcesz. Prawdopodobnie zdasz sobie sprawę, że masz sprzeczne oczekiwania - że wyniki powinny być naprawdę losowe i nie przewidywalne, ale jednocześnie nie powinny wykazywać lokalnych różnic od podanego prawdopodobieństwa - ale wtedy to staje się przewidywalne. Jeśli ustawisz maksymalnie 10 niekrytów z rzędu, to właśnie powiedziałeś graczom "jeśli miałeś 9 niekrytów z rzędu, następny będzie krytyczny ze 100% pewnością" - równie dobrze możesz w ogóle nie przejmować się losowością.

 7
Author: Michael Borgwardt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-27 14:07:47

Przy tak małej liczbie testów należy oczekiwać takich wyników:

Prawdziwa losowość jest przewidywalna tylko przy ogromnych rozmiarach zestawu, tak że całkiem możliwe jest rzucenie monetą i zdobycie Orłów 3 razy z rzędu za pierwszym razem, jednak ponad kilka milionów rzutów skończy się z proporcjonalnie 50-50.

 6
Author: Ed James,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-26 11:38:04

Widzę wiele odpowiedzi sugerujących, aby śledzić wcześniej wygenerowane liczby lub przetasować wszystkie możliwe wartości.

Osobiście nie zgadzam się, że 3 kryty pod rząd to źle. Nie zgadzam się też, że 15 non-crits pod rząd jest złe.

Rozwiązałbym ten problem, modyfikując krytyczne szanse na to samo, po każdej liczbie. Przykład (aby zademonstrować pomysł):

int base_chance = 20;
int current_chance = base_chance;

int hit = generate_random_number(0, 100) + 1; // anything from 1 to 100
if(hit < current_chance)//Or whatever method you use to check
{
    //crit!
    if(current_chance > base_chance)
        current_chance = base_chance; // reset the chance.
    else
        current_chance *= 0.8; // decrease the crit chance for the NEXT hit.
}
else
{
    //no crit.
    if(current_chance < base_chance)
        current_chance = base_chance; // reset the chance.
    else
        current_chance *= 1.1; // increase the crit chance for the NEXT hit.
    //raise the current_chance
}

Im dłużej nie otrzymujesz kryt - tym większa szansa na następną akcję. Reset I dołączony jest całkowicie opcjonalny i wymaga testów, aby stwierdzić, czy jest potrzebny, czy nie. Może, ale nie musi być pożądane, aby dać większe prawdopodobieństwo kryt dla więcej niż jednej akcji z rzędu, po długim łańcuchu działań niekrytycznych.

Dorzuciłem moje 2 centy...
 6
Author: Paulius,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-26 14:31:18

Kilka najważniejszych odpowiedzi to świetne wyjaśnienia, więc skupię się na algorytmie, który daje Ci kontrolę nad prawdopodobieństwem "złych smug", podczas gdy nigdy nie staje się deterministyczny. Oto, co myślę, że powinieneś zrobić:

Zamiast określać p, parametr rozkładu Bernoulliego, który jest prawdopodobieństwem krytycznego trafienia, podaj a i b , parametry rozkładu beta, "sprzężony przeor" rozkładu Bernoulliego. Ty trzeba śledzić A i B , liczbę trafień krytycznych i niekrytycznych do tej pory.

Teraz, aby określić a i b , Upewnij się, że A/(A+b) = P, szansa na trafienie krytyczne. Najważniejsze jest to, że (a+b) określa, jak blisko ma być A/(A+B) do p w ogóle.

Samplujesz Tak:

Niech {[1] } będzie funkcją gęstości prawdopodobieństwa rozkładu beta. Jest dostępny w wielu miejscach, ale można go znaleźć w GSL jako gsl_ran_beta_pdf.

S = A+B+1
p_1 = p((A+1)/S)
p_2 = p(A/S)

Wybierz trafienie krytyczne, pobierając próbki z rozkładu Bernoulliego z prawdopodobieństwem p_1 / (p_1 + p_2)

Jeśli okaże się, że liczby losowe mają zbyt wiele "złych smug", skaluj w górę a i b , ale w limicie, ponieważ a i b pójdą w nieskończoność, będziesz miał podejście shuffle bag opisane wcześniej.

Jeśli to zaimplementujesz, daj mi znać, jak to idzie!

 5
Author: Neil G,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-27 05:36:58

Jeśli chcesz dystrybucji, która zniechęca do powtarzania wartości, możesz użyć prostego algorytmu odrzucania powtarzania.

Np.

int GetRand(int nSize)
{
    return 1 + (::rand() % nSize);
}
int GetDice()
{
    static int nPrevious=-1;
    while (1) {
        int nValue = GetRand(6);
        // only allow repeat 5% of the time
        if (nValue==nPrevious && GetRand(100)<95)
            continue;
        nPrevious = nValue;
        return nValue;
    }
}

Ten kod odrzuca wartości powtórzeń 95% czasu, co sprawia, że powtórzenia są mało prawdopodobne, ale nie niemożliwe. Statystycznie jest trochę brzydki, ale prawdopodobnie przyniesie oczekiwane wyniki. Oczywiście nie zapobiegnie to dystrybucji typu "5 4 5 4 5". Można dostać więcej i odrzucić drugi ostatni (powiedzieć) 60% czasu i trzeci ostatni (powiedzieć) 30%.

Nie polecam tego jako dobrego projektu gry. Po prostu sugerując, jak osiągnąć to, co chcesz.
 5
Author: Michael J,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-27 09:05:56

Nie jest do końca jasne, czego chcesz. Możliwe jest utworzenie takiej funkcji, że po pierwszym wywołaniu 5 razy zwraca ona liczby 1-5 w losowej kolejności.

Ale to nie jest przypadkowe. Gracz będzie wiedział, że dostanie dokładnie jeden 5 w następnych 5 atakach. Może to być to, czego chcesz, a w takim przypadku po prostu musisz sam to zakodować. (Utwórz tablicę zawierającą Liczby i przetasuj je)

Obecne podejście i załóżmy, że Twoje bieżące wyniki są spowodowane złym generatorem losowym. Pamiętaj, że nic nie może być nie tak z Twoimi bieżącymi numerami. Losowe wartości są losowe. czasami dostajesz 2, 3 lub 8 tej samej wartości w rzędzie. Bo są przypadkowe. Dobry generator losowy gwarantuje, że średnio wszystkie liczby będą zwracane równie często.

Oczywiście, jeśli używałeś złego generatora losowego, który mógł wypaczać Twoje wyniki, a jeśli tak, po prostu przełącz się na lepszy generator losowy powinien rozwiązać problem. (Sprawdź Boost.Biblioteka losowa dla lepszych generatorów)

Alternatywnie możesz zapamiętać Ostatnie n wartości zwracane przez funkcję losową i zważyć wynik przez te. (prostym przykładem może być: "dla każdego wystąpienia nowego wyniku istnieje 50% szans na odrzucenie wartości i uzyskanie nowego wyniku"

Gdybym miał zgadywać, powiedziałbym, że trzymanie się" rzeczywistej " przypadkowości jest najlepszym rozwiązaniem. Upewnij się, że używasz dobrego losowego generator, a potem rób tak, jak teraz.

 4
Author: jalf,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-26 11:44:29

Możesz utworzyć listę zawierającą liczby od 1 do 5 i posortować je według losowości. Następnie przejrzyj utworzoną listę. Masz gwarancję, że trafisz na każdy numer przynajmniej raz... Kiedy skończysz z pierwszymi 5, po prostu utwórz kolejne 5 liczb...

 4
Author: Arjan Einbu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-26 12:03:59

Polecam progresywny system procentowy jak Blizzard: http://www.shacknews.com/onearticle.x/57886

Zazwyczaj rzucasz RNG, a następnie porównujesz go z wartością, aby określić, czy się uda, czy nie. To może wyglądać tak:

if ( randNumber <= .2 ) {
   //Critical
} else {
   //Normal
}

Wszystko, co musisz zrobić, to dodać progresywny wzrost szansy bazowej...

if (randNumber <= .2 + progressiveChance ) {
   progressiveChance = 0;
   //Critical
} else {
   progressiveChance += CHANCE_MODIFIER;
   //Normal hit
}

Jeśli chcesz, aby było bardziej wyszukane, to dość łatwo dodać więcej. Możesz ograniczyć kwotę, którą progressiveChance może uzyskać, aby uniknąć 100% szansy krytycznej lub Resetuj go przy określonych zdarzeniach. Możesz również mieć wzrost progresywności w mniejszych ilościach każdy boost z czymś w rodzaju progresywności + = (1-progresywność) * skala gdzie skala

 4
Author: JonBWalsh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-27 19:11:02

Cóż, jeśli interesujesz się trochę matematyką, prawdopodobnie możesz spróbować rozkładu wykładniczego

Na przykład, jeśli lambda = 0.5, wartość oczekiwana wynosi 2 (przeczytaj ten artykuł!), czyli najprawdopodobniej trafisz / crit / cokolwiek co 2 turę (jak 50%, co?). Ale z takim rozkładem prawdopodobieństwa, będziesz definitevely miss (lub zrobić odwrotnie do cokolwiek) w 0 tury (ten, w którym zdarzenie miało już miejsce i turn_counter został zresetowany), mają jak 40% szans na trafienie następnej tury, około 65% szansa, aby to zrobić 2nd (następny po następnym) turn, około 80% trafić 3rd i tak dalej.

Cały cel tej dystrybucji jest taki, że jeśli ktoś ma 50% szansy na trafienie i nie trafi 3 razy z rzędu, będzie shurely( no cóż, ponad 80% szansy i zwiększa się w każdej następnej turze) hit. Prowadzi to do bardziej "uczciwych" wyników, zachowując ogólne 50% szans bez zmian.

Biorąc 20% szansę na crit, masz

  • 17% do crit 1. turn
  • 32% do 2. tury kryt, jeśli we wszystkich poprzednie.
  • 45% do crit 3rd turn, jeśli nie występuje crit we wszystkich poprzednich.
  • 54% do crit 4.turn, jeśli nie ma crit we wszystkich poprzednich.
  • ...
  • 80% do crit 8th turn, jeśli nie występuje crit we wszystkich poprzednich.

To wciąż około 0.2% (w porównaniu z tymi 5%) szansami na 3 kryty + 2 nie-Kryty w 5 kolejnych kolejkach. I jest 14% szansa na 4 wynikające non-crits, 5% z 5, 1.5% dla 6, 0.3% dla 7, 0.07% dla 8 wynikające non-crits. Założę się, że to " więcej fair " niż 41%, 32%, 26%,21% i 16%.

Mam nadzieję, że nadal nie nudzisz się na śmierć.

 4
Author: Dark,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-17 13:25:32

A co z uzależnieniem szansy na krytyczny atak od ostatnich ataków N? Jednym z prostych schematów jest jakiś łańcuch Markowa: http://en.wikipedia.org/wiki/Markov_chain ale kod i tak jest bardzo prosty.


IF turns_since_last_critical < M THEN 
   critial = false
   turns_since_last_critical++;
ELSE
   critial = IsCritical(chance);
   IF Critial THEN
       turns_since_last_critica = 0;
   ELSE
       turns_since_last_critica++;
   END IF;
END IF;

Oczywiście musisz zrobić swoją matematykę, ponieważ szansa na krytyczny jest mniejsza niż szansa na krytyczny, gdy wiesz, że to było wystarczająco dużo obrotów od ostatniego

 3
Author: borjab,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-28 09:35:48

OP,

W zasadzie, jeśli chcesz, aby to było sprawiedliwe, to nie będzie przypadkowe.

Problemem Twojej gry jest rzeczywista długość meczu. Im dłuższy mecz, tym mniej losowości zobaczysz (kryty będą miały tendencję do 20%) i zbliżą się do zamierzonych wartości.

Masz dwie opcje, wstępnie Oblicz ataki na podstawie poprzednich rolek. Który otrzymasz jeden kryt co 5 ataków( w oparciu o Twoje 20%), ale możesz wykonać rozkaz, który występuje przypadkowe.

ListOfFollowingAttacks = {Hit, Hit,Hit,Miss, Crit};

Taki wzór chcesz. Więc niech wybierze losowo z tej listy, dopóki nie będzie pusta, odtworzą ją.

To wzór, który stworzyłem dla mojej gry, działa całkiem dobrze, na to, co chcę, aby robił.

Twoją drugą opcją byłoby zwiększenie szansy na kryt, prawdopodobnie zobaczysz bardziej parzystą liczbę pod koniec wszystkich ataków (zakładając, że Twoje mecze kończą się dość szybko). Im mniej % chance, im więcej dostajesz.

 2
Author: 2 revsRodrigo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-26 13:36:12

Patrzysz na rozkład liniowy, kiedy prawdopodobnie chcesz rozkładu normalnego.

Jeśli pamiętasz, jak w młodości grałeś w D&D, poproszono Cię o wyrzucenie wielu N-stronnych matryc, a następnie zsumowanie wyników.

Na przykład, rzucanie kostką 4 x 6-stronną różni się od rzucania kostką 1 x 24-stronną.

 2
Author: dar7yl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-27 21:41:27

City of Heroes posiada mechanikę o nazwie "streakbreaker", która rozwiązuje dokładnie ten problem. Sposób, w jaki to działa, polega na tym, że po ciągu chybień o długości związanej z NAJNIŻSZYM prawdopodobieństwem trafienia w ciągu, następny atak jest gwarantowany jako trafienie. Na przykład, jeśli przegapisz atak z ponad 90% trafienia szansy, twój następny atak będzie automatycznie trafiony, ale jeśli Twoja szansa na trafienie jest niższa niż 60%, będziesz musiał mieć kilka kolejnych chybień, aby wywołać" streakbreaker " (i nie znam dokładnych liczb)

 2
Author: Alex319,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-27 18:12:00

alt text

Ten jest naprawdę przewidywalny... ale nigdy nie możesz być pewien.

 2
Author: 太極者無極而生,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-19 20:24:14

A co z ważeniem wartości?

Na przykład, jeśli masz 20% szans na trafienie krytyczne, Wygeneruj liczbę od 1 do 5 z jedną liczbą reprezentującą trafienie krytyczne lub liczbę od 1 do 100 z 20 liczbami będącymi trafieniem krytycznym.

Ale tak długo, jak pracujesz z losowymi lub pseudorandomowymi liczbami, nie ma sposobu, aby potencjalnie uniknąć wyników, które obecnie widzisz. To natura przypadkowości.

 0
Author: Thomas Owens,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-26 11:34:45

Reakcja na: "Problem w tym, że mam bardzo złe wyniki w prawdziwym życiu - czasami gracze dostają 3 Kryty w 5 trafieniach, czasami żaden w 15 trafieniach."

Masz szansę gdzieś między 3 A 4% dostać nic w 15 trafień...

 0
Author: Fortega,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-26 12:40:11

Proponuję następujący "losowo opóźniony putback die":

  • utrzymuj dwie tablice, jedna (in-array) początkowo wypełniona wartościami od 0 do n-1, Druga (out-array) pusta
  • gdy żądany jest wynik:
    • zwraca losową wartość ze wszystkich zdefiniowanych wartości w in-array
    • przenieś tę wartość z in-array do out-array
    • przesuń o jeden losowy (ponad wszystkie elementy, łącznie z undefined!) element z out-array z powrotem do in-array

Ma to właściwość, że będzie "reagować" wolniej im większy n jest. Na przykład, jeśli chcesz mieć 20% szans, ustawienie n na 5 i trafienie na 0 jest "mniej losowe" niż ustawienie n na 10 i trafienie na 0 LUB 1, i uczynienie go od 0 do 199 na 1000 będzie prawie nieodróżnialne od prawdziwej losowości w małej próbce. Będziesz musiał dostosować N do rozmiaru próbki.

 0
Author: Svante,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-26 13:00:16

Wstępnie Oblicz losowe trafienie krytyczne dla każdego gracza .

// OBJECT
//...
// OnAttack()
//...
c_h = c_h -1;
if ( c_h == 0 ) {
 // Yes, critical hit!
 c_h = random(5) + 1 // for the next time
 // ...
}
 0
Author: Nick Dandoulakis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-26 13:07:04

Myślę, że może używasz niewłaściwej funkcji rozkładu losowego. Prawdopodobnie nie chcesz równomiernego rozkładu liczb. Zamiast tego spróbuj użyć rozkładu normalnego, aby trafienia krytyczne stały się bardziej rzadkie niż "zwykłe" trafienia.

Pracuję z Javą, więc nie jestem pewien, gdzie można znaleźć coś do C++, co daje losowe liczby z rozkładem normalnym, ale musi coś tam być.

 0
Author: Alex,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-27 09:34:12