C# While循环无法按预期从列表中随机选取新字符串
作为一个完全的初学者,我认为我在WPF应用程序中犯了一些严重的错误,因为我合并的while循环没有按计划工作C# While循环无法按预期从列表中随机选取新字符串,c#,wpf,C#,Wpf,作为一个完全的初学者,我认为我在WPF应用程序中犯了一些严重的错误,因为我合并的while循环没有按计划工作 List<string> alreadyUsedReagents = new List<string>(new string[] {}); List<string> alreadyUsedMetals = new List<string>(new string[] { }); List<string> reagents = n
List<string> alreadyUsedReagents = new List<string>(new string[] {});
List<string> alreadyUsedMetals = new List<string>(new string[] { });
List<string> reagents = new List<string>(new string[]{
"Hexaaqua ion",
"Dilute NaOH",
"Excess NaOH",
"Dilute NH₃",
"Excess NH₃",
"Salt",
"Na₂CO₃",
"HCl"});
public void RefreshReagents()
{
alreadyUsedReagents.Clear();
}
public string CycleThroughReagents()
{
bool keepinLoop = true;
string chosenReagent = null;
while (keepinLoop == true)
{
int r = rnd.Next(reagents.Count);
string pickedReagent = (string)reagents[r];
if (!alreadyUsedReagents.Contains(pickedReagent))
{
alreadyUsedReagents.Add(pickedReagent);
chosenReagent = pickedReagent;
keepinLoop = false;
}
if (alreadyUsedReagents.Count == 8)
{
RefreshReagents();
keepinLoop = false;
}
else
{
keepinLoop = true;
}
}
return chosenReagent;
}
此方法中实现了开关功能,如果按钮与试剂组匹配,则将特定按钮的标签设置为“正确”
public partial class MainWindow : Window
{
GameControl _GameControl = new GameControl();
public string chosenMetal;
int amtLeft = 8;
public MainWindow()
{
InitializeComponent();
chosenMetal = _GameControl.CycleThroughMetals();
_GameControl.SetButtonContent(chosenMetal,ReagentAdded, transMetal, Opt1, Opt2, Opt3, Opt4, Opt5, Opt6, Opt7, Opt8);
Opt1.Click += HandleButtonClicks;
Opt2.Click += HandleButtonClicks;
Opt3.Click += HandleButtonClicks;
Opt4.Click += HandleButtonClicks;
Opt5.Click += HandleButtonClicks;
Opt6.Click += HandleButtonClicks;
Opt7.Click += HandleButtonClicks;
Opt8.Click += HandleButtonClicks;
}
public void SwitchMetals()
{
chosenMetal = _GameControl.CycleThroughMetals();
_GameControl.RefreshReagents(); //method which clears the 'alreadyUsedReagents' list
_GameControl.SetButtonContent(chosenMetal, ReagentAdded, transMetal, Opt1, Opt2, Opt3, Opt4, Opt5, Opt6, Opt7, Opt8);
}
private void HandleButtonClicks(object sender, RoutedEventArgs e)
{
Button button = sender as Button;
CheckForCorrect(button);
}
public void CheckForCorrect(Button button)
{
if ((string)button.Tag == "correct" && amtLeft != 0)
{
amtLeft -= 1;
MessageBox.Show("You guessed correct!");
_GameControl.SetButtonContent(chosenMetal, ReagentAdded, transMetal, Opt1, Opt2, Opt3, Opt4, Opt5, Opt6, Opt7, Opt8);
button.IsEnabled = false;
}
if ((string)button.Tag != "correct")
{
MessageBox.Show("Oops!");
}
else if (amtLeft == 0)
SwitchMetals();
}
}
然后在
主窗口中使用上述方法最初设置按钮和试剂文本,然后使用单击方法查看单击的按钮是否正确,如果正确,则设置新试剂。我遇到的问题是,我处理试剂循环和设置的方式似乎完全弄乱了我的代码,就像每次单击后屏幕上显示试剂一样,有时TextBlock
显示为空白,并使用以前使用过的试剂。任何帮助都将不胜感激,我很抱歉提前包含了这么多代码示例,但我真的很难从这里开始做什么。看看while循环,这篇文章似乎:
if (!alreadyUsedReagents.Contains(pickedReagent))
{
alreadyUsedReagents.Add(pickedReagent);
chosenReagent = pickedReagent;
keepinLoop = false;
}
应该执行中断
。它当前的工作方式不会阻止循环的进一步迭代,因为您在keepinloop
中设置的值可以被下面的if/else覆盖。所以试着换一条线
keepinLoop = false;
与
这应该可以修复你的循环
更新。实际上,与其使用某些虚构的标志来控制循环,不如使用一些真实的条件,如使用的试剂数量,例如:
while (alreadyUsedReagents.Count != 8)
{
int r = rnd.Next(reagents.Count);
string pickedReagent = (string)reagents[r];
if (!alreadyUsedReagents.Contains(pickedReagent))
{
alreadyUsedReagents.Add(pickedReagent);
chosenReagent = pickedReagent;
break;
}
}
RefreshReagents();
if (chosenReagent == null)
{
// make sure to come up with some default
// or your method will return null in some cases
}
如果您没有跟踪alreadyusedAgentures
而是保留了unusedAgentures
的列表,那么您完全可以不进行任何循环
refreshAgents()
然后用整个列表填充unusedAgents
cyclethrawagents()
随机选取一个,将其从unusedagents
中移除并返回
每当unusedagreents
为空时调用refreshAgreents()
。如果您正在这样做,则只需将while设置为loop on truewhile(true)
因为您不再使用keepinLoop
。OP需要处理的下一件事是当您返回到cyclethrawagents()
和alreadyusedagents.Count==8
时,它将返回一个空字符串。谢谢!,这修复了TextBlock显示为空白并使用以前使用的文本块的问题reagents@evanb,那么也许最好的方法是执行类似于的操作,而(count!=8)
。事实上,让我用这个更新答案。同时提到你对null的观察我无法停止阅读KeepLoopin,因为KeepLoopin‘我没有读过你的代码,但是你的描述表明你做的都是错的。既然你可以记住那些没有被选中的项目,为什么还要记住那些已经被选中的项目呢?首先将所有项目放入第二个列表,使用Random
实例随机选择一个项目,然后从列表中删除该项目。继续这样做,直到列表为空,然后在需要时重新填充。@CallumHoughton继续学习,不要害怕新手犯错误。我们都去过那里。@jmcilhinney这基本上就是我发布的答案。@CoderDennis,我写评论时没有评论或答案,但我遇到了连接问题,所以在它实际发布时已经发生了很多活动。这听起来比我目前的解决方案干净多了,我会在早上尝试。谢谢你的回答
break;
while (alreadyUsedReagents.Count != 8)
{
int r = rnd.Next(reagents.Count);
string pickedReagent = (string)reagents[r];
if (!alreadyUsedReagents.Contains(pickedReagent))
{
alreadyUsedReagents.Add(pickedReagent);
chosenReagent = pickedReagent;
break;
}
}
RefreshReagents();
if (chosenReagent == null)
{
// make sure to come up with some default
// or your method will return null in some cases
}