首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >循环不像预期的那样从列表中随机选择新字符串。

循环不像预期的那样从列表中随机选择新字符串。
EN

Stack Overflow用户
提问于 2015-07-28 22:45:26
回答 2查看 64关注 0票数 4

作为一个完全的初学者,我认为我在我的WPF应用程序中做了一些严重错误,因为我合并的while循环没有按计划工作。

代码语言:javascript
复制
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;
}

while循环应该遍历并返回一个尚未使用的reagent,所有使用过的试剂都应该存储在then循环分析的alreadyUsedReagents列表中,然后在设置按钮属性的my SetButtonContent方法中使用该CycleThroughReagents方法。

代码语言:javascript
复制
public void SetButtonContent(string ChosenMetal, TextBlock reagentText, TextBlock transMetalText,
        Button opt1, Button opt2, Button opt3, Button opt4, Button opt5, Button opt6, Button opt7, Button opt8)
{
    string pickedMetal = "Cobalt";
    string pickedReagent = CycleThroughReagents();

    reagentText.Text = pickedReagent;
    transMetalText.Text = pickedMetal;
} 

在此方法中实现了开关功能,该方法将特定按钮的标记设置为“正确”,如果按钮与试剂集匹配的话。

代码语言:javascript
复制
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();


    }
}

然后在MainWindow中使用上述方法来最初设置按钮和试剂文本,然后使用单击方法来查看单击的按钮对于所设置的特定试剂是否正确,如果是,则设置一个新的试剂。我遇到的问题是,我处理试剂的循环和设置的方式似乎完全搞砸了我的代码,就像每次单击后在屏幕上显示试剂时,TextBlock显示为空白,并使用了以前使用过的试剂。任何帮助都将是非常感谢的,我很抱歉事先包含了这么多的代码示例,但是我真的很困惑接下来该做什么。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-07-28 23:02:13

如果您没有跟踪alreadyUsedReagents,而是保留了一个unusedReagents列表,则完全可以不使用任何循环来完成这一任务。

然后,RefreshReagents()用整个列表填充unusedReagents

CycleThroughReagents()随机选择一个,从unusedReagents中删除并返回它。

只要RefreshReagents()是空的,就调用unusedReagents

票数 3
EN

Stack Overflow用户

发布于 2015-07-28 22:52:38

只要看一下while循环,就会发现这段代码:

代码语言:javascript
复制
if (!alreadyUsedReagents.Contains(pickedReagent))
{
    alreadyUsedReagents.Add(pickedReagent);
    chosenReagent = pickedReagent;
    keepinLoop = false;
}

应该是做break的。它当前的工作方式并不会阻止循环的进一步迭代,因为您在keepinloop中设置的值可以被下面的if/ set覆盖。所以试着更换线路

代码语言:javascript
复制
keepinLoop = false;

使用

代码语言:javascript
复制
break;

这应该能解决你的循环问题。

Update.实际上不是使用一些组合标志来控制您的循环,而是使用一些实际的条件,例如,使用的试剂数量:

代码语言:javascript
复制
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
}
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31688401

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档