2013-04-01 147 views
0

我已經編寫了一個C#windows窗體項目的事件處理程序,它模擬兩個骰子的100個卷並返回每個卷的兩個骰子的總和。代碼爲這些總和做了三件事,它將它放在名爲「rollDisplay」的RichTextBox中,它將總和寫入文本文件,並將總和添加到名爲「roll」的整數列表中。所有這些工作正常,但現在我需要計算每個總和的頻率,並在ListBox中顯示這些頻率。如下面的代碼所示,我使用了11個不同的計數器變量,以及11個不同的字符串添加到ListBox。我在下面的工作,但它真的很醜,在我看來,這是一個非常低效的方式。計算骰子卷的頻率

我的問題是。任何人都可以提出一個更清潔的方式做到這一點?這個任務要求我有11個獨立的計數器來識別骰子卷的頻率,所以我不能使用Linq,正如我看到的其他幾個問題所表明的那樣,但我真的很不確定這是完成什麼的最好方法我需要。

private void Roll_Click(object sender, EventArgs e) 
    { 
     int roll = 0, hitTwo = 0, hitThree = 0, hitFour = 0, hitFive = 0, hitSix = 0, hitSeven = 0, hitEight = 0, 
      hitNine = 0, hitTen = 0, hitEleven = 0, hitTwelve = 0; 
     String freq1, freq2, freq3, freq4, freq5, freq6, freq7, freq8, freq9, freq10, freq11; 
     StreamWriter file = new StreamWriter("dicerolls.txt", true); 
     List<int> rolls = new List<int>(); 

     for (int i = 0; i < 100; i++) 
     { 
      dieUno.setSide(dieUno.roll()); 
      dieDuo.setSide(dieDuo.roll()); 

      int diceTotal = dieUno.getSide() + dieDuo.getSide(); 
      rolls.Add(diceTotal); 
      rollDisplay.AppendText(diceTotal.ToString() + "\u2028"); 

      try 
      { 
       file.WriteLine(diceTotal.ToString()); 
      } 
      catch (Exception ex) 
      { 
       MessageBox.Show(ex.Message); 
      } 
     } 

     file.Close(); 

     for (int i = 0; i < rolls.Count; i++) 
     { 
      roll = rolls[i]; 

       if(roll==2) 
       { hitTwo++; } 
       else if(roll==3) 
       { hitThree++; } 
       else if(roll==4) 
       { hitFour++; } 
       else if(roll==5) 
       { hitFive++; } 
       else if(roll==6) 
       { hitSix++; } 
       else if(roll==7) 
       { hitSeven++; } 
       else if(roll==8) 
       { hitEight++; } 
       else if(roll==9) 
       { hitNine++; } 
       else if (roll == 10) 
       { hitTen++; } 
       else if (roll == 11) 
       { hitEleven++; } 
       else if (roll == 12) 
       { hitTwelve++; } 
     } 

     freq1 = " 2 Occurs: " + hitTwo + " times"; freq2 = " 3 Occurs: " + hitThree + " times"; freq3 = " 4 Occurs: " + hitFour + " times"; 
     freq4 = " 5 Occurs: " + hitFive + " times"; freq5 = " 6 Occurs: " + hitSix + " times"; freq6 = " 7 Occurs: " + hitSeven + " times"; 
     freq7 = " 8 Occurs: " + hitEight + " times"; freq8 = " 9 Occurs: " + hitNine + " times"; freq9 = " 10 Occurs: " + hitTen + " times"; 
     freq10 = " 11 Occurs: " + hitEleven + " times"; freq11 = " 12 Occurs: " + hitTwelve + " times"; 


     frequency.Items.Add(freq1); frequency.Items.Add(freq2); frequency.Items.Add(freq3); frequency.Items.Add(freq4); frequency.Items.Add(freq5); 
     frequency.Items.Add(freq6); frequency.Items.Add(freq7); frequency.Items.Add(freq8); frequency.Items.Add(freq9); frequency.Items.Add(freq10); 
     frequency.Items.Add(freq11); 
    } 
+4

你學「陣列」了嗎? http://msdn.microsoft.com/en-us/library/aa288453%28v=vs.71%29.aspx – paulsm4

+0

'frequency [roll] ++;' –

+1

'這個任務要求我有11個獨立的計數器'YUCK 。他們現在在學校教你什麼? – walther

回答

1

Roll_Click確實做得太多了。

首先,創建一個GatherSamples函數。

int[] GatherSamples() 
{ 
    var rolls = new List<int>(); 

    // roll dice ... 

    return rolls.ToArray(); 
} 

然後,DisplayRolls方法

void DisplayRolls(int[] rolls) 
{ 
    // output to your control  
} 

...和WriteToDisk方法

void WriteToDisk(int[] rolls, string file) 
{ 
    using (var writer = new StreamWriter(file)) // research C# using if you don't understand this 
    { 
     ... 
    } 
} 

...然後做你的頻率分析

string[] AnalyzeRolls(int[] rolls) 
{ 
    // though I don't approve of 11 counters, use them here 

    return new [] { "2 occurs " ... }; 
} 

...然後給我打電話像這樣:

foreach(var analysis in AnalyzeRolls(rolls)) 
{ 
    frequency.Items.Add(analysis); 
} 
0

在這裏,你去。一個6面骰子滾筒。它對用戶界面一無所知。它幾乎沒有公開其內部實現。

class SixSidedDiceRoller 
{ 
    private static readonly RandomNumberGenerator rng = RandomNumberGenerator.Create(); 
    private SortedDictionary<int,int> frequencyTable; 
    private List<Tuple<int,int,int>> rollHistory; 

    public int Count { get { return rollHistory.Count; } } 

    public IEnumerable<Tuple<int , int , int>> RollHistory 
    { 
    get { return rollHistory.AsReadOnly(); } 
    } 

    public IEnumerable<Tuple<int,int>> FrequencyTable 
    { 
    get 
    { 
     return frequencyTable.Select(
     x => new Tuple<int,int>(x.Key,x.Value) 
     ) ; 
    } 
    } 

    public SixSidedDiceRoller() 
    { 

    rollHistory = new List<Tuple<int , int , int>>(); 

    // initialize the frequency table 
    for (int i = 2 ; i <= 12 ; ++i) 
    { 
     frequencyTable[i] = 0; 
    } 

    return; 
    } 

    public int RollDice() 
    { 
    int d1 = RollDie(); 
    int d2 = RollDie(); 
    int n = d1 + d2; 

    rollHistory.Add(new Tuple<int , int , int>(d1 , d2 , n)); 
    ++frequencyTable[n]; 

    return n; 
    } 

    private int RollDie() 
    { 
    byte[] octets = new byte[1]; 
    rng.GetBytes(octets); 
    int die = 1 + (octets[0] % 6); 
    return die; 
    } 

} 

應該不會太硬連線,最多一個Windows應用程序,WPF應用程序,Web應用程序,控制檯應用程序等等

+0

有點過於複雜,構造函數需要兩個parms,它不使用,而'RollDie'方法不會返回一致的結果。您將生成一個從0到255的隨機值並將模數乘以6. 1到4的值更可能比5到6大約1/43。給定100卷2個骰子(200個樣本),結果將偏離預期的鐘形曲線。 – Corey