2012-05-01 6 views
0

私は小さなプロジェクトのために小さなクラスを作っています。これはテキストベースのRPGゲームで、NPCの死亡時のドロップクラスを作成しようとしています。私はアイテムID(名前)のランダムな量を落としてアイテムの希少性を落とすために、いくつかのMath.randomメソッドを作成しています(まったく同じです。それはすべて正常に動作しますが、(起動時または実行時に)1回ランダム化するだけで、それ以降の量はランダム化されません。私はまた、2つの数字、例えば25と50の間で無作為化しています。無作為ではなく、次に25より小さくならないでしょう。乱数化する配列の番号ランダムを使用する

私の質問は次のとおりです。2D配列または一般的な配列NPCが死ぬたびに、最初に取得された乱数が変化し、同じままではありません。今のところ、それは選択肢の数にとどまります。数が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)); 
    } 

私は私が正しく理解していれば、あなたはこれが配列のNPC_DROPSたびに再初期化されるdrop()への呼び出しで初期化さNPC_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]); 
      } 
     } 
    } 
} 

答えて

1

滴メソッドを呼び出し相続人中古。

まあ、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]); 
      } 
     } 
    } 
} 
+0

シンプルですがスケーラビリティに優れていません。 ;) –

+0

測定する必要があります。パフォーマンスへの影響に気づく前に、毎秒非常に多くの死亡が予想されます。 –

+0

+1:たくさんのドロップタイプがありますが、しばしばシンプルさが最適です。 –

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()を呼び出す必要があります。

+0

ありがとうございます。私はこれを念頭に置いておきます! – Newbie

0

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

+0

フィードバックいただきありがとうございます。 – Newbie

関連する問題