2017-02-28 63 views
2

我有一段時間想着以下,我想做一個按鈕來隨機化一些技能的整個值。問題是我有10點要分配4個技能,這個想法是選擇不超過10分的隨機數。隨機化值而不超過值?

我原以爲在這個

public int startPts = 10, usedPts = 0; 
public int skill1 = 0, skill2 = 0, skill3 = 0, skill4 = 0; 

public void ButtonRandom(){ 
    startPts = 10; 
    usedPts = 0; 

    skill1 = Random.Range(1, 10); 
    usedPts += skill1; 

    skill2 = Random.Range(1, usedPts); 
    usedPts += skill2; 

    skill3 = Random.Range(1, usedPts); 
    usedPts += skill3; 

    skill4 = startPts - usedPts; 
    usedPts += skill4; 

    startPts = startPts - usedPts; 

} 

我也試着與幾個條件語句和重複的方法,但我沒有得到期望的結果。由於有時超過了10分,因此在放置條件時不使用或僅改變前2個數值。

謝謝,夥計們。

+0

您的上次作業需要分配剩餘點數,而不是嘗試猜測隨機數。 「skill4 = startPts - usedPts」 – Aaron

+0

你確定你實際上並不想使用Random.Range(1,startPts - usedPts);'?現在你的號碼並沒有考慮到有多少點可用。 – Serlite

+0

@Aaron是的,你是對的我現在編輯那部分,謝謝。 –

回答

4

如果我理解正確你:

int[] skills = new int[4]; 

int pointsToDistribute = 10; 

var rnd = new Random(); 

for (int i = 0; i < pointsToDistribute; i++) 
{ 
    int whichSkill = rnd.Next (0, 4); 

    skills[whichSkill]++; 
} 

測試:https://dotnetfiddle.net/891OlN

+1

我認爲每項技能都應該以1的值開始,那麼循環只會去'pointsToDistribute - skills.Length'。這是問題的要求。 – dcg

+2

@dcg:我給了他一個主意,他可以很容易地適應他的要求。但你當然是對的。 – apocalypse

+0

嗨@apocalypse我想使用.Next()方法,但在Unity中它似乎不能使用,或者我認爲是這樣。但是,這是所期望的結果,謝謝你,現在我不知道如何將它植入Unity。 –

1

這是爲我工作。
每一行都有解釋,但簡而言之,它使用一個數組來存儲隨機生成的數字。

public void RandomButton() 
{ 
    int toDistribute = 10; // 10 points to distribute 

    int[] skills = new int[4]; // Array that contains 4 skills 

    Random random = new Random(); // New instance of Random 

    for (int i = 0; i < 4; i++) // For loop that loops four times 
    { 
     if (toDistribute > 0) // Do this IF there are points to distribute 
     { 
      int points = random.Next(0, toDistribute + 1); // Assign points a value between 0 and the remaining amount of points 
      // Random.Next(lowerBoundary,upperBoundary-1) e.g. Random.Next(0,100) gives values from 0 to 99 
      skills[i] = points; // The current skill is given the value of points 
      toDistribute -= points; // Total number of points remaining is reduced by the number of points assigned this iteration 
     } else break; // If there are no points, end the loop 
    } 
} 

如果你不明白Random.Next是如何工作的,閱讀here

編輯/ UNITY UPDATE:

研究使我相信,Random.Next()在Unity中不是現成的,而是使用Random.Range。在這種情況下,使用以下命令:

int point = Random.Range(0,toDistribute); 

此外,據我瞭解,你並不需要創建隨機的新實例,這意味着

Random random = new Random(); 

可以去掉

8

如果你想要的是每一個可能的分佈是相同的可能,那麼到目前爲止提出的解決方案都沒有工作。迄今爲止提出的解決方案比7, 1, 1, 1更經常選擇3, 3, 2, 2。你明白爲什麼?

如果您所需的分佈是均勻的可能性,這種算法爲您提供了:

using System; 
using System.Collections.Generic; 
using System.Linq; 

public class Program 
{ 
    // Partition n into m summands 
    static IEnumerable<IEnumerable<int>> Partitions(int n, int m) 
    { 
     // There is no partition of n into zero summands for any value of n other than zero. 
     // Otherwise, give the partitions that begin with 0, 1, 2, ... n. 
     if (m == 0) 
     { 
     if (n == 0) 
      yield return Enumerable.Empty<int>(); 
     } 
     else 
     { 
     for (int nn = 0; nn <= n; ++nn) 
      foreach(var p in Partitions(n - nn, m - 1)) 
       yield return (new[] { nn }).Concat(p); 
     } 
    } 

    public static void Main() 
    { 
     // Divide up six points into four buckets: 
     var partitions = Partitions(6, 4).ToArray(); 
     // Now choose a random member of partitions, and 
     // add one to each element of that sequence. Now 
     // you have ten points total, and every possibility is 
     // equally likely. 

     // Let's visualize the partitions: 
     foreach(var p in partitions) 
      Console.WriteLine(string.Join(",", p)); 

    } 
} 
2

使用統一的API,這將是這樣的,建立在@apocalypse氏液

int[] skills = new int[4]; 
    int pointsToDistribute = 10; 
    for (int i = 0; i < pointsToDistribute; i++) { 
     int whichSkill = Random.Range (0, 4); 
     skills [whichSkill]++; 
    } 
0

我們開始學習他們的算法和解決方案,真的非常感謝你們。這是我的代碼的結果,以防有人懷疑。

public int startPts = 10, usedPts = 0; 
public int skill1 = 0, skill2 = 0, skill3 = 0, skill4 = 0; 

public void ButtonRandom(){ 
    startPts = 10; 
    usedPts = 0; 

    int[] skills = new int[4]; 

    for (int i = 0; i < 4; i++){ 
     skills[i] = 1; 
    } 

    for (int i = 0; i < (startPts - skills.Length); i++) { 
     int tempRandom = Random.Range (0, 4); 
     skills [tempRandom]++; 
    } 

    for (int i = 0; i < 4; i++){ 
     usedPts += skills[i]; 
    } 

    startPts = startPts - usedPts; 

    skill1 = skills[0]; 

    skill2 = skills[1]; 

    skill3 = skills[2]; 

    skill4 = skills[3]; 

}