2013-10-09 34 views
1

我創建賓果遊戲,我使用Random來產生int數組中的隨機數,但我的問題在於,有時在索引中再次使用數字。我如何讓索引中的數字是唯一的?如何填充每個索引中具有唯一編號的int數組?

這是我的工作:你搶一個新的數字

namespace Bingo 
{ 
    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
     } 

    Random randNum1 = new Random(); 

    int[] random1 = new int[5]; 
    int qwe = 0; 
    int i = 0; 

    private void button1_Click(object sender, EventArgs e) 
    { 
     Class1 class1 = new Class1(); 
     class1.checker(this); 

     if (label1.Text == label2.Text || label3.Text == label4.Text) { 

      label2.Text = randNum1.Next(1, 15).ToString(); 
      label4.Text = randNum1.Next(1, 15).ToString(); 
     } 

     if (label5.Text == label1.Text || label5.Text == label2.Text) { 

      label5.Text = randNum1.Next(1, 15).ToString();    
     } 
    } 

    private void Form1_Load(object sender, EventArgs e) 
    { 
     Class1 class1 = new Class1(); 

     class1.SetTwo(this); 

     for (int i = 0; i < random1.Length; i++) 
     { 
      random1[i] = randNum1.Next(1, 15); 

      label1.Text = random1[0].ToString(); 
      label2.Text = random1[1].ToString(); 
      label3.Text = random1[2].ToString(); 
      label4.Text = random1[3].ToString(); 
      label5.Text = random1[4].ToString(); 
     } 
    } 
} 
+1

檢查您的隨機數數組中存在,只有當它不 添加它。 – Habib

+0

如果你想將它用於「真實遊戲」,那麼選擇的密碼應該很強,以確保「公平」的隨機性。 http://stackoverflow.com/a/19275698/659190 – Jodrell

回答

7

與循環,直到問題你發現一個未使用的是,隨着遊戲的進行,你會花更長,更長的時間找到一個有效的數字。理論上你的循環可能永遠不會結束(無限可能,但仍然...)

最簡單的事情就是在真正的賓果遊戲中發生的事情。從有限的集合開始,每次繪製時都會從集合中移除項目。用最初的可能性填充List或任何其他動態索引容器,隨機選擇一個從0到列表大小的索引,然後從列表中刪除選擇。

這將保證每個選擇產生一個獨特的結果,沒有循環。

+0

這絕對是一個更好的方法 – Jonesopolis

+0

+1偉大的方法,我不確定是否猶太潔食這樣做,但我創建了一個基於你的答案。這是你在想什麼? – Khan

+1

最好使用具有良好移除性能的集合類,並且如果遊戲是真實的,即爲了錢,則使用質量良好,均勻分佈的隨機數生成器。 http://stackoverflow.com/a/19275698/659190 – Jodrell

0

每次,只是圍繞着它本:

int num; 
do 
{ 
    num = randNum1.Next(1, 15); 
} 
while(random1.Contains(num)) 

random1[i] = num; 

,以保證它是唯一

1

另一種方法是重新洗牌數字的排序列表:

var numbers = Enumerable.Range(1, 15).OrderBy(i => Guid.NewGuid()).ToArray(); 

這是如何工作的?

  • 開始與整數(Enumerable.Range(1, 15) => [1, 2, 3, ..., 15]
  • 重新排序(OrderBy
  • 有 「隨機」 指數Guid.NewGuid()

顯然,這隻會工作的列表,如果Guid.NewGuid()沒有按」不會產生連續的GUID,但是,我認爲默認沒有,因爲這是GUID算法的第一個實現的安全問題。

(我用的GUID尖端洗牌從這裏: Randomize a List<T>

你可以用其他更有效的方法來洗牌「甲板」,但賓果遊戲風格的應用程序,這應該只是罰款。

另一個想法:

var rand = new Random(); 
var numbers = Enumerable.Range(1, 15).OrderBy(i => rand.Next()).ToArray(); 

由於在首發名單中的元素是唯一的,其結果是保證重現該屬性。

2

我想通斯科特Mermelstein的答案的說明可以幫助:

List<int> AvailableNumbers; 
Random random; 
private void Form1_Load(object sender, EventArgs e) 
{ 
    //Create a list of numbers, 1-14 
    AvailableNumbers = Enumerable.Range(1, 14).ToList(); 
    random = new Random(); 

    label1.Text = GetNextNumber().ToString(); 
    label2.Text = GetNextNumber().ToString(); 
    label3.Text = GetNextNumber().ToString(); 
    label4.Text = GetNextNumber().ToString(); 
    label5.Text = GetNextNumber().ToString(); 
} 
private int GetNextNumber() 
{ 
    //Get a random index within the bounds of AvailableNumbers 
    var nextIndex = random.Next(0, AvailableNumbers.Count); 

    var nextNumber = AvailableNumbers[nextIndex]; 
    AvailableNumbers.RemoveAt(nextIndex); 

    return nextNumber; 
} 
+1

這看起來不錯,並增加了我的答案中極其缺乏的價值(即一些實際代碼)。 –

+0

您犯的一個錯誤是將'new Random()'放入函數中,使其在函數外部,並在'Load'語句中聲明新的函數。 –

+0

@ScottChamberlain好點。我相應地編輯了我的答案。我不明白爲什麼,直到我讀到這個:「每次你創建一個實例,它將使用當前時間作爲'種子'」來自:http://stackoverflow.com/questions/1011198/non-repetitive-random- number-c-sharp – Khan

相關問題