0

私は小さなプロジェクトのために小さなクラスを作っています。これはテキスト ベースの RPG ゲームで、NPC が死亡したときのドロップ クラスを作成しようとしています。アイテム ID (名前) のランダムな量をドロップし、ドロップされたアイテムの希少性を取得するために、いくつかの Math.random メソッド (まったく同じですが、便宜上、名前が異なるだけです) を作成しました。すべて正常に動作しますが、(起動時または実行時に) 1 回だけランダム化され、その後は量がランダム化されません。また、25 と 50 などの 2 つの数値の間でランダム化しています。ランダムは 25 未満または 50 未満にはなりません。

私の質問は次のとおりです。NPC が死亡するたびに 2D 配列または一般的な配列の整数をランダム化するにはどうすればよいですか。最初に取得される乱数は変化し、同じままではありません。今のところ、選択した数のままです。数が 25 の場合、次の npc を殺しても、その量は 25.. と 25.. と 25.. となります。ランダム化または変更する必要があります。

助けてください、ありがとう。

   public class DropConfig {

    private static final int
        ALWAYS = 0,
        VERY_COMMON = rate(1, 9),
        COMMON = rate(10, 20),
        UNCOMMON = rate(30, 40),
        RARE = rate(50, 60),
        VERY_RARE = rate(70, 80),
        SUPER_RARE = rate(90, 100);

    public static final int[][] NPC_DROPS = {

        // Normal NPC's
        {1, 526, 1, ALWAYS}, 
        {2, 526, 1, ALWAYS}, 
        {3, 526, 1, ALWAYS}, 
        {1, 995, drop(1, 50), ALWAYS}, 
        {2, 995, drop(1, 50), ALWAYS},
        {3, 995, drop(1, 50), ALWAYS},

        // Moderate NPC's
        {9, 526, 1, ALWAYS}, 
        {9, 995, drop(250, 500), UNCOMMON},
        {9, 555, drop(2, 7), VERY_COMMON},
        {9, 995, drop(5, 50), VERY_COMMON},
        {9, 1050, 1, RARE}, 
    };

    public static int rate(int min, int max) {
        return 1 + (int)(Math.random() * ((max - min) + 1));
    }

    //Same as rate, different name for looks.
    public static int drop(int min, int max) {
        return 1 + (int)(Math.random() * ((max - min) + 1));
    }

ここでdropsメソッドを呼び出します

public void npcDeath() {
    int npc = 0;    
    if (npc == null)
        return;
    for(npc = 0; npc < DropConfig.NPC_DROPS.length; npc++) {
        if(npc == DropConfig.NPC_DROPS[npc][0]) {
            if(Misc.random(DropConfig.NPC_DROPS[npc][3]) == 0) { //Drops ALWAYS item
                Item(DropConfig.NPC_DROPS[npc][1], DropConfig.NPC_DROPS[npc][2]);
            }
        }
    }
}
4

3 に答える 3

1

drop()私の理解が正しければ、この NPC_DROPS 配列が使用されるたびに、 への呼び出しで初期化された NPC_DROPS 配列の要素を再初期化する必要があります。

まあ、NPC_DROPS は定数なので変更できません。メソッドを使用して、アクセスされるたびに生成します。

public static int[][] generateNpcDrops(){
    return new int[][] {

    // Normal NPC's
    {1, 526, 1, ALWAYS}, 
    {2, 526, 1, ALWAYS}, 
    {3, 526, 1, ALWAYS}, 
    {1, 995, drop(1, 50), ALWAYS}, 
    {2, 995, drop(1, 50), ALWAYS},
    {3, 995, drop(1, 50), ALWAYS},

    // Moderate NPC's
    {9, 526, 1, ALWAYS}, 
    {9, 995, drop(250, 500), UNCOMMON},
    {9, 555, drop(2, 7), VERY_COMMON},
    {9, 995, drop(5, 50), VERY_COMMON},
    {9, 1050, 1, RARE}, 
    }
}

...

public void npcDeath() {
    int npc = 0;    
    if (npc == null)
        return;
    int[][] npcDrops = DropConfig.generateNpcDrops();
    for(npc = 0; npc < npcDrops.length; npc++) {
        if(npc == npcDrops[npc][0]) {
            if(Misc.random(npcDrops[npc][3]) == 0) { //Drops ALWAYS item
                Item(c, npcDrops[npc][1], npcDrops[npc][2]);
            }
        }
    }
}
于 2012-05-01T09:26:43.297 に答える
0

関数を定数として配置したい。これは Scala のような言語では自然に実行できますが、Java ではもう少し手間がかかります。

いずれの場合も、関数を呼び出して実際の値を取得する必要があります。

enum メソッドと匿名メソッドを使用できますが、最も簡単な方法/ハックは、範囲をエンコードすることです。

public static int rate(int min, int max) { // same for drop.
    int range = max - min;
    return (range << 16) | (min & 0xFFFF);
}

public static int eval(int minMax) {
    int min = (short) minMax;
    int range = (short) (minMax >> 16);
    if (range == 0)
       return min; // plain number.
    else
       return min + (int) (Math.random() * (range + 1));
}

エンコードされた範囲を乱数に変換するには、eval() を呼び出す必要があります。

于 2012-05-01T09:27:19.383 に答える
0

同じシードで Random のインスタンスを作成すると、同じ「乱数」が得られます。SecureRandom の使用を検討しましたか? SecureRandom と Random の違いは、SecureRandom が各呼び出しで非決定論的な出力を生成することです。

于 2012-05-01T09:28:14.970 に答える