Ehtimal və Oyunlar: Zərər rulonları

Dungeons & Dragons kimi kağız-zar rolu oynayan oyunlar hücum ziyanını hesablamaq üçün istifadə edirlər [1]. Bu, zar üzərində qurulmuş bir oyun üçün məntiqlidir. Bir çox kompüter RPG bənzər bir sistemlə zərərləri və digər xüsusiyyətləri (güc, sehrli nöqtələr, çeviklik və s.) Hesablayır.

Tipik olaraq təsadüfi () zəng etmək üçün bir kod yazacaqsınız. Oyunda istədiyiniz davranışı əldə etmək üçün rəqəmləri düzəldəcək və nəticələrini düzəldəcəksiniz. Bu təlim üç mövzunu əhatə edəcək:

    - orta dəyər və dispersiya
  1. Asimmetriya əlavə etmək - zərlərin təqdim etməsi ilə məhdudlaşmayan təsadüfi nömrələrin dizaynında zar rulonlarının düşməsi və ya kritik hitlərin əlavə edilməsi.

Əsaslar #

Bu məqalə üçün təsadüfi tam ədədi 0-dan N-1-ə qaytaran təsadüfi ( N ) funksiyanız olduğunu düşünürəm . Python-da random.randrange ( N ) istifadə edin ; Javascriptdə Math.floor ( N * Math.random ()) istifadə edin; C-də, standart kitabxanada rand ()% N var, lakin zəif davranır, buna görə fərqli bir təsadüfi say generatoru istifadə edin; C ++ dilində, bir təsadüfi ədəd yaradan obyektə uniform_int_distribution (0, N -1) əlavə edin [2]; Java-da, yeni Random () ilə təsadüfi bir rəqəm yaradan obyekt düzəldin və sonra .nextInt ( N ) -ə zəng edin . Bir çox dildə standart kitabxanalarda böyük təsadüfi say generatorları yoxdur, lakin C və C ++ üçün PCG [3] kimi üçüncü tərəf kitabxanalar çoxdur.

Bircə ölümlə başlayaq. Bu histoqram tək bir 12 tərəfli qəlibin yuvarlanmasının nəticələrini göstərir: 1 + təsadüfi (12). Təsadüfi (12) 0-dan 11-ə qədər bir rəqəm qaytardığından və 1-dən 12-ə qədər bir rəqəm istədiyimizə, 1-i əlavə edirik. X oxu zərərdir; y oxu bu zərərin nə qədər baş verdiyini göstərir. Tək bir matkapla, 2 və ya 12-lik bir zərər rulosu, 7-lik bir rulonla eyni dərəcədədir.

Çox zar rulonlarda üçün, zar oyun notation bir az istifadə etmək yardım edəcəyik: Nd Svasitə bir gəzmək Sdie qat Ndəfə. Tək 12 tərəfli qəlibin yuxarıda yuvarlanması 1d12 yazılacaq; 3d4 [4] 4 tərəfli ölümü üç dəfə yuvarlamaq deməkdir; bunu 3 + təsadüfi (4) + təsadüfi (4) + təsadüfi (4) kimi kodlaşdırardıq.

( D) tərəfli zarları yuvarlayaq və nəticələri əlavə edək :

Nəticələr () - () arasında ola bilər. Yuvarlanmaq ehtimalı və ya.

Zarların sayını artırsaq, ancaq ölçülərini azaltsaq nə olar? 12-yə qədər təsadüfi rəqəmlər yaratmaq üçün bu yolları sınayın:

Əsas təsiri paylama gedir ki, geniş üçün dar . Pikin sağa keçdiyi ikinci bir təsir də var . Əvvəlcə növbələrin istifadəsini araşdıraq.

Daimi növbələr

Dungeons & Dragons'dakı bəzi silahlar bonus ziyan verir. +1 bonus ziyanını göstərmək üçün 2d6 + 1 yaza bilərik. Bəzi oyunlarda zireh və ya qalxan bəzi zərərləri ləğv edir. 3 zərər nöqtəsinin bloklandığını bildirmək üçün 2d6-3 yaza bilərik; Bu nümunədə minimum zərərin 0 olduğunu düşünəcəyəm.

Zərərin pozuntusunu (zərər mükafatı üçün) və ya mənfi (zərərin qarşısını almaq üçün) dəyişdirməyə çalışın:

Bonus ziyanının əlavə edilməsi və ya bloklanmış zərərin çıxarılması sadəcə bütün paylamanı sola və ya sağa keçir.

Dağıtım fərqi

Biz paylanması 6d2 üçün 2d6 hərəkət, həm də var dar və keçdikdə sağ. Əvvəlki hissədə gördüyümüz kimi, sürüşmə yalnız bir ofsetdir. Dağılım dispersiyasına baxaq.

N-i təkrarən təsadüfi rulonlarda ( S + 1 ) 0-dan N * S- yə qaytaran bir funksiya təyin edək :

Zar istifadə edərək 0-dan 24-ə qədər təsadüfi rəqəmlər yaratmaq bu nəticələrin paylanmasına səbəb olur:

Dağılımınnecə təsir etdiyini görmək üçün zar sayını dəyişdirməyə çalışın. Rulo sayı artdıqca, 0 ilə N * S aralığını sabit tutarkən , paylama daralır (aşağı dispersiya). Nəticələrin daha çoxu sıra mərkəzinə yaxın olacaqdır.

Yan qeyd: S tərəflərinin sayını artırsanız (aşağıdakı oyun meydançasına baxın), cəmi S-yə bölərkən paylama normal paylanmaya yaxınlaşacaq [5]. Normal paylanmadan təsadüfi seçməyin daha sadə yolu Box-Muller çevrilməsidir [6].

Asimmetriya #

RollDice üçün paylamalar ( N , S ) simmetrikdir . Orta dəyərlərdən daha aşağı, orta dəyərlərdən daha yüksəkdir. Oyun üçün istədiyin budurmu? Əks təqdirdə, asimmetriya yaratmaq üçün bir neçə texnika var.

Ruloların atılması və ya təkrarlanması

Fərz edək ki, ortalamadan yüksək dəyərlərin ortalamadan aşağıdan daha çox yayılmış olmasını istərdiniz. Bu zərər üçün daha az yaygındır, lakin güc, zəka və s. Kimi xüsusiyyətlər üçün istifadə edilə bilər. Bunun bir yolu bir neçə dəfə yuvarlanmaq və ən yaxşı rulonu seçməkdir.

RollDice (,) -i iki dəfə və daha yüksək rulonu seçək:

RollDice (2, 12) və rollDice (2, 12) arasından daha yüksəkini seçdiyimizdə 0-dan 24-ə qədər bir rəqəmlə sona çatırıq. 0-dan 24-ə qədər bir rəqəm əldə etməyin başqa bir yolu rollDice (1, 12) istifadə etməkdir. üç dəfə və üçün ən yaxşı ikisini seçin. Forma, iki rulondan daha yaxşısını seçməkdən daha asimmetrikdir (2, 12):

Başqa bir yanaşma ən aşağı nəticəni təkrarlamaq olacaq. Forma ümumilikdə əvvəlki yanaşmalara bənzəyir, lakin detallarına görə bir qədər fərqlidir:

Bu yanaşmalardan hər hansı biri asimmetriyanı tərs etmək üçün istifadə oluna bilər, ortalamadan aşağı dəyərlər ortalamadan yüksəkdən daha yüksəkdir. Buna fərqli bir baxış yolu, bu paylanmanın bəzən yüksək dəyərlər partlaması meydana gətirməsidir. Belə bir paylama tez-tez zərər üçün istifadə olunur və nadir hallarda atributlar üçün istifadə olunur. Budur max () min () -ə qaytarılır:

Kritik hitlər

Bəzən yüksək ziyan partlayışları yaratmağın başqa bir yolu onu daha birbaşa tətbiq etməkdir. Bəzi oyunlarda "kritik bir hit" bir az bonus verir. Ən sadə bonus əlavə ziyandır. Aşağıdakı kodda kritik zərbə zamanı əlavə olunur:

Asimmetriya əlavə etmək üçün digər yanaşmalar daha çox hücumları təsir etməyi əhatə edir: kritik hitlərin daha da kritik hitləri tətikləmək şansı qazanması; kritik hitləri müdafiəni atlayan ikinci bir hücumu tetiklemek; ya da kritik zərbələr vurmaq, rəqibin hücumu qaçırmasına səbəb olur. Ancaq burada çox hücumlu zərər paylamalarını təhlil etməyəcəyəm.

Özünüzü dizayn etməyə çalışın

Hər təsadüfi istifadə üçün (zərər, atributlar və s.) Oyun üçün istədiyiniz paylanmanın xüsusiyyətlərini izah etməyə başlayın:

  • Aralıq:minimum və maksimum dəyərlər nə qədərdir? Dağılımınızı bu aralığa uyğunlaşdırmaq üçün miqyaslandırma və dəyişdirmə istifadə edin.
  • Varyans:dəyərlərin ortalamaya yaxın olmasını nə qədər istəyirsən? Böyük varyans üçün az sayda rulon və ya kiçik varyans üçün çox sayda rulon əlavə edin.
  • Asimmetriya:ortalamadan yüksək və ya ortalamadan aşağı dəyərlərin daha çox yayılmış olmasını istəyirsiniz? Dağıtımınıza asimmetriya əlavə etmək üçün min, maksimum və ya kritik bonuslardan istifadə edin.

Bu parametrlərdən bəziləri ilə oynamaqüçün oyun meydançasından istifadə edin :

Təsadüfi nömrələrinizi qurmaq üçün oyun meydançası təkliflərindən daha çox yol var, amma ümid edirəm ki, bu, onsuz da nə qədər rahatlıq olduğunu anlamağa imkan verir. Bu zərər rulosu kalkulyatorunu da nəzərdən keçirin [7]. Bəzən zar rulonlarını birləşdirmək sizə istədiklərinizi vermək üçün kifayət deyil.

Təsadüfi şekiller #

Biz başlayan olduğunuz giriş alqoritmlər və müvafiq baxaraq çıxış bölüşdürmələr. İstədiyimizə uyğun bir nəticə tapana qədər bir çox fərqli girişdən keçirik. Doğru alqoritmi əldə etməyin daha birbaşa yolu varmı? Bəli!

Bir histoqram şəklində ifadə olunan istənilən çıxışdan başlayaraq geriyə gedək. Bunu sadə bir nümunə ilə sınayaq.

Tutaq ki, bu nisbətlərdə 3, 4, 5 və 6 seçmək istəyirəm::::. Bu, normal olaraq zar rulonlarından alacağınız bir şeyə uyğun gəlmir.

Bunun üçün kodu necə yazardım?

Bu kodu öyrənin və növbəti addımdan əvvəl necə işlədiyini anladığınızdan əmin olun. Hansı nəticəni aldığınızı görmək üçün fərqli x dəyərlərini seçməyə çalışın. Bu kodu fərqli ehtimal cədvəlləri üçün yenidən istifadə edilə bilən bir şeyə ümumiləşdirək. İlk addım cədvəlin yazılmasıdır:

Əllə yazılmış kodda hər bir if ifadəsi x -ı ehtimalların məcmu cəmi ilə müqayisə etdi. Əl ilə ifadə olunan cəmlərlə ayrı-ayrı ifadələr yazmaq əvəzinə cədvəlin girişlərinə keçə bilərik:

Ümumiləşdirməyimiz lazım olan son şey cədvəl girişlərinin cəmidir. Cəmi hesablayaq və təsadüfi bir x seçmək üçün istifadə edək:

Bütün bunları bir araya gətirərək, nəticələri cədvəldən axtarmaq üçün bir funksiya və təsadüfi bir nəticə seçmək üçün bir funksiya yaza bilərik (bunları ziyan cədvəli sinfində metodlara çevirə bilərsiniz):

Cədvəldən rəqəmlər yaratmaq üçün kod sadədir. Bu kod mənim ehtiyaclarım üçün kifayət qədər sürətli olmuşdur, ancaq profileriniz çox yavaş olduğunu deyirsə, ikili / interpolasiya axtarışı, axtarış cədvəlləri və ya alias metodunu sınayaraq xətti axtarışı sürətləndirin (bax Keith Schwarz-un izahı [8] və Bruce Hill's interaktiv izahat [9]). Ters çevrilmə nümunəsinə baxın [10].

Öz paylamanızı çəkin #

Bu yanaşmanın ən yaxşı tərəfi odur ki, istənilən formaya imkan verir . Kodun nə olacağını görmək üçün bu meydançada rəsm çəkməyə çalışın:

Bu yanaşma ilə zar rulonlarının istehsal etdiyi paylamalarla məhdudlaşmadan istədiyiniz oyun təcrübəsinə uyğun bir paylama seçə bilərsiniz.

Nəticə

Təsadüfi ziyan rulonlarını və təsadüfi atributları tətbiq etmək asandır. Oyun dizayneri olaraq, nəticədə paylanmanın hansı xüsusiyyətlərə sahib olmasını istədiyinizi düşünməlisiniz. Zar rulonlarını istifadə etmək istəyirsinizsə:

  • Varyansa nəzarət etmək üçün rulon sayından istifadə edin . Az sayda rulon yüksək bir varyansa cavab verir və əksinə.
  • Ölçüyə nəzarət etmək üçün ofset və qəlib ölçüsündən istifadə edin . Təsadüfi rəqəmlərin X- dən Y - yə qədər olmasını istəyirsinizsə, N rulonlarının hər biri 0-dan (YX) / N- ə qədər təsadüfi bir rəqəm çıxarmalı və cəminə X əlavə etməlisiniz . Müsbət ofsetlər bonus ziyanı və ya bonus xüsusiyyətləri üçün istifadə edilə bilər; mənfi zərərlər zərərin qarşısını almaq üçün istifadə edilə bilər.
  • Ortalamadan yüksək və ya ortalamadan aşağı bir dəyərin daha tez-tez baş verməsi üçün asimmetriyadan istifadə edin . Atribut rulonları, maksimum, ən yaxşı üçü istifadə edərək və ya ən aşağı səviyyəni dəyişdirərək, orta dəyərlərdən daha yüksəkdir. Zərər rulonları tez-tez minimum və ya kritik bonuslardan istifadə edərək orta dəyərlərdən daha aşağı olur. Təsadüfi qarşılaşma çətinliyi də tez-tez orta dəyərdən daha aşağı olanları daha çox yayılmışdır.

Dağıtımın oyun boyunca necə dəyişməsini istədiyinizi düşünün. Hücum bonusları, zərərin qarşısını almaq və kritik hitlər paylanmanı sadə parametrlərlə dəyişdirmək üçün bəzi yollardır. Bu parametrlər daha sonra oyundakı maddələrə təyin edilə bilər. Bu parametrlərin paylamaları necə təsir etdiyini görmək üçün yuxarıdakı oyun meydançasından istifadə edin. Oyunçu səviyyələri yüksəldikcə paylanmanın necə dəyişməsini istədiyinizi düşünün; AnyDice [12] istifadə edərək hesablanan dağılımları ilə (ortaqlığı artırmaq və zamanla fərqi azaltmaq üçün bu səhifəyə [11] baxın (gözəl bloqu var [13]).

Kağız və zar oyunlarından fərqli olaraq, təsadüfi rəqəmlərin cəminə əsaslanan paylama ilə məhdudlaşmırsınız. “Öz paylamanın dizaynı” bölməsində hazırladığımız kodu istifadə edərək istədiyiniz paylanmadan istifadə edə bilərsiniz . Bir histoqram çəkməyinizə, məlumatları bir cədvəldə saxlamağınıza və sonra bu paylanmadan təsadüfi rəqəmlər çəkməyinizə imkan verən vizual bir vasitə edə bilərsiniz. Və ya masaları JSON və ya XML formatında düzəldə bilərsiniz. Və ya Excel-də cədvəlləri düzəldə və CSV olaraq ixrac edə bilərsiniz. Parametrik olmayan paylamalar sizə çox rahatlıq verir və kod yerinə məlumat cədvəllərindən istifadə etmək kodu yenidən yığmadan sürətli təkrarlamağa imkan verir.

Sadə kodla maraqlı ehtimal paylamaları etmək üçün bir çox yol var. Əvvəlcə hansı növ xüsusiyyətlərə ehtiyacınız olduğuna qərar verin və sonra uyğun kodu seçin.