我为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);
}
答案 0 :(得分: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);
}
答案 1 :(得分: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应用程序,网络应用程序,控制台应用程序等。