RPG seviye yukarı gereksinimleri için ayarlanabilir formül nasıl oluşturulur?


44

Sadece iki değeri değiştirerek değiştirilebilecek bir formül oluşturmaya çalışıyorum: number_of_levels ve last_level_experience. Bu, insanların oyunu seviyelendirme gerekliliklerini değiştirmeleri için modlamalarını sağlamaktır.

Son seviye yukarı için gerekli olan XP sayısını belirleyebildiğim için, bu durumda çılgınca değişebilecek olan birinci seviye için gereken XP'yi kontrol etmek istiyorum. Örneğin, son seviye için 40 seviyem ve 1.000.000 XP'ye sahipsem, ilk seviye yükselme şartı 625'tir. Fakat seviyeleri 80'e değiştirirsem, ilk seviye yükselme 156 olur. 1,000,000.

Bilgisayarın sadece bu iki temel değer verilen uygun bir eğriyi ortaya çıkarmasının bir yolu olmalı.

#include <iostream>

int main()
{
    int levels = 40;
    if (levels < 2) levels = 2;

    int experience_for_last_level = 1e6;
    float fraction = 1.0 / levels;

    {
        int i = 0;
        float fraction_counter = fraction;
        int counter = levels;
        int total = 0;

        for (i = 1; i <= levels; ++i, fraction_counter += fraction, --counter)
        {
            int a = static_cast<int>(fraction_counter * experience_for_last_level / counter);

            std::cout <<"Level "<<i<<":  "<<a<<" ("<<counter<<")"<<"\n";

            total += a;
        }

        std::cout << "\nTotal Exp: " << total;
    }
}

Çıktı:

Level 1:  625   (40)      Level 15: 14423  (26)      Level 29: 60416  (12)
Level 2:  1282  (39)      Level 16: 16000  (25)      Level 30: 68181  (11)
Level 3:  1973  (38)      Level 17: 17708  (24)      Level 31: 77499  (10)
Level 4:  2702  (37)      Level 18: 19565  (23)      Level 32: 88888  (9)
Level 5:  3472  (36)      Level 19: 21590  (22)      Level 33: 103124 (8)
Level 6:  4285  (35)      Level 20: 23809  (21)      Level 34: 121428 (7)
Level 7:  5147  (34)      Level 21: 26250  (20)      Level 35: 145833 (6)
Level 8:  6060  (33)      Level 22: 28947  (19)      Level 36: 179999 (5)
Level 9:  7031  (32)      Level 23: 31944  (18)      Level 37: 231249 (4)
Level 10: 8064  (31)      Level 24: 35294  (17)      Level 38: 316666 (3)
Level 11: 9166  (30)      Level 25: 39062  (16)      Level 39: 487499 (2)
Level 12: 10344 (29)      Level 26: 43333  (15)      Level 40: 999999 (1)
Level 13: 11607 (28)      Level 27: 48214  (14)
Level 14: 12962 (27)      Level 28: 53846  (13)

13
Temel bir sorun olmasıdır sonsuz o kadar XP gerektiren son seviyesi ile sona ereceğini birçok XP seviye eğrileri. Sorunun boyutlarını sınırlandırmadınız, çünkü XP'nin seviyeden seviyeye nasıl değişmesini istediğinizi belirtmediniz . Üstel bir büyüme eğrisi ister misiniz? Parabolik bir büyüme eğrisi? Doğrusal mı? Sorununuz şu andaki durumunda çözülemez. Şahsen, eğer oyunu değiştirirsem, XP eğrisi üzerinde sadece son seviye numaradan ve son seviye XP'den daha fazla kontrol sahibi olmak isterdim. Asıl eğrinin kendisini kontrol etmek isterdim.
Nicol Bolas

Modderlerin seviyelemeyi bir script ile kontrol etmesine izin verebilirim.
Truncheon

Yanıtlar:


71

Bunları seçmek için sonsuz sayıda yol olsa da, aşağıdakiler gibi bir güç kuralına uymak için eğrilerin dengelenmesi yaygındır :

f(level) == A * exp(B * level)

Bu formülün en büyük avantajı kolayca açıklanabilir: verilen bir kural için, her seviye bir öncekinden yüzde N daha fazla olan sabit bir N değeri vardır .

İlk değişkenleriniz aşağıdaki kısıtlamaları ekler:

f(1) - f(0) == experience_for_first_level
f(levels) - f(levels - 1) == experience_for_last_level

İki denklem, iki bilinmeyenli. Bu iyi görünüyor. Basit matematik verir Ave B:

B = log(experience_for_last_level / experience_for_first_level) / (levels - 1);
A = experience_for_first_level / (exp(B) - 1);

Aşağıdaki kodda sonuçlanan:

#include <cmath>
#include <iostream>

int main(void)
{
    int levels = 40;
    int xp_for_first_level = 1000;
    int xp_for_last_level = 1000000;

    double B = log((double)xp_for_last_level / xp_for_first_level) / (levels - 1);
    double A = (double)xp_for_first_level / (exp(B) - 1.0);

    for (int i = 1; i <= levels; i++)
    {
        int old_xp = round(A * exp(B * (i - 1)));
        int new_xp = round(A * exp(B * i));
        std::cout << i << " " << (new_xp - old_xp) << std::endl;
    }
}

Ve aşağıdaki çıktı:

1 1000          9 4125          17 17012        25 70170        33 289427
2 1193          10 4924         18 20309        26 83768        34 345511
3 1425          11 5878         19 24245        27 100000       35 412462
4 1702          12 7017         20 28943        28 119378       36 492389
5 2031          13 8377         21 34551        29 142510       37 587801
6 2424          14 10000        22 41246        30 170125       38 701704
7 2894          15 11938        23 49239        31 203092       39 837678
8 3455          16 14251        24 58780        32 242446       40 1000000

12
Keşke bütün cevaplar bu iyi planlanmış ve düşünülmüş olsaydı.
Nate,

Buradaki eğri çok daha lezzetli.
Truncheon

İyi cevap. Bu aptalca bir soru olabilir, ama Nyukarıda anlattığını nasıl hesaplarsın ? NTakılabilir değişken yapmak istiyorsanız ne yapmalıyım ? Bunun için ayrı bir soru sormam gerekip gerekmediğini bana bildirin.
Daniel Kaplan

1
arasındaki ilişkiyi @tieTYT Nve Bbir exp(B) = 1 + Nveya B = log(1 + N). Her seviye gerektirir istiyorsak mesela daha öncekinden% 15'den, ihtiyacınız B = log(1 + 0.15) = 0.13976.
sam hocevar

18

Eğrinizi belirledikten sonra sayıları yuvarlamayı unutmayın. Oyuncuya bir sonraki seviyeye ulaşmak için 119.378 tecrübe puanına ihtiyacı olduğunu söylemek mantıklı değil - çünkü kişi her zaman "kabaca 120.000" olarak anlayacaktır. Böylece yuvarlamayı kendiniz yapmaktan ve oyuncularınıza "temiz" sonuçları sunmaktan daha iyi olacaksınız. Örneğin, aşağıdaki kod (Sam Hocevar'ı genişleten) ≈2.2 önemli basamağa kadar yuvarlamaya çalışacaktır (tabii ki sabit istediğiniz gibi ayarlanabilir):

from math import exp, log

levels = 40
xp_for_first_level = 1000
xp_for_last_level = 1000000

B = log(1.0 * xp_for_last_level / xp_for_first_level) / (levels - 1)
A = 1.0 * xp_for_first_level / (exp(B) - 1.0)

def xp_for_level(i):
    x = int(A * exp(B * i))
    y = 10**int(log(x) / log(10) - 2.2)
    return int(x / y) * y

for i in range(1, levels+1):
    print( "%d:  %d" % (i, xp_for_level(i) - xp_for_level(i-1)) )

Çıktı:

1:  1000     9:  4200     17:  17100    25:  70000     33:  287000
2:  1190    10:  4900     18:  20300    26:  84000     34:  340000
3:  1420    11:  5900     19:  24200    27:  100000    35:  420000
4:  1710    12:  7000     20:  28700    28:  119000    36:  490000
5:  2030    13:  8400     21:  34000    29:  142000    37:  590000
6:  2420    14:  10000    22:  42000    30:  171000    38:  700000
7:  2870    15:  11900    23:  49000    31:  203000    39:  840000
8:  3400    16:  14200    24:  59000    32:  242000    40:  1000000
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.