【问题标题】:2 in a row game in c#c#中的连续2个游戏
【发布时间】:2012-11-01 15:10:19
【问题描述】:

上面是棋盘的图片

我发现很难找出如何连续检测 2 种颜色来确定获胜者 不使用暴力枚举..

我有一个算法,我一直在尝试实现它,但我似乎无法让它工作 有谁知道该怎么做..会很有帮助谢谢..

我想检测获胜者对角线垂直和水平..

p.s 我通常不寻求解决方案,但这次我真的需要一些帮助。非常感谢

这是我为程序提供的代码,可让您进行和平处理

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {

        private Button[] btns;
        private Button[] btns2;
        private Button[] btns3;
        public Color[] col;
      //  public var x;

        public Form1()
        {
            InitializeComponent();

            btns = new Button[2] { button2, button3 };
            btns2 = new Button[2] { button4, button5 };
            btns3 = new Button[2] { button9, button8 };
            col = new Color[2] { Color.Red, Color.Yellow };
           Color x = col[0];
            Color y = col[1];


        }



        private void Form1_Load(object sender, EventArgs e)
        {

            foreach (var btn in btns)
            {
                btn.Enabled = false;
                btn.BackColor = Color.LightCyan;
            }

            foreach (var btn in btns2)
            {
                btn.Enabled = false;
                btn.BackColor = Color.LightCyan;
            }
            foreach (var btn in btns3)
            {
                btn.Enabled = false;
                btn.BackColor = Color.LightCyan;
            }
        }




        public int state;
        int cc = 0;
        private void button1_Click(object sender, EventArgs e)
        {
            foreach (var btn in btns)
            {
                  {
                    if (!btn.Enabled)
                    {
                        btn.Enabled = true;

                        if (cc == 0)
                        {
                            cc = 1;
                            btn.BackColor = col[0];

                        }
                        else
                        {
                            cc = 0;
                            btn.BackColor = col[1];
                        }



                        return;
                    }

                }
            }       
        }


        private void button6_Click(object sender, EventArgs e)
        {
            foreach (var btn in btns2)
            {
                if (!btn.Enabled)
                {
                    btn.Enabled = true;

                    if (cc == 0)
                    {
                        cc = 1;
                        btn.BackColor = col[0];
                    }
                    else
                    {
                        cc = 0;
                        btn.BackColor = col[1];

                    }



                    return;
                }
            }
        }

        private void button7_Click(object sender, EventArgs e)
        {

            foreach (var btn in btns3)
            {
                if (!btn.Enabled)
                {
                    btn.Enabled = true;

                    if (cc == 0)
                    {
                        cc = 1;
                        btn.BackColor = col[0];
                    }
                    else
                    {
                        cc = 0;
                        btn.BackColor = col[1];

                    }



                    return;
                }
            }

        }
    }
}

【问题讨论】:

  • 在此之前我已经多次看到您的问题。你真的只在寻找 2 的比赛吗?我记得你说过这最终会成为一种连接 4 或 5 的游戏?
  • 是的,它将是连接 4,但我在想如果我学会如何连接 2,我可以通过扩展它继续前进
  • 我认为这不是一个好方法。游戏的整个网格有多大?
  • 我认为这是一种合理的方法,前提是您要特别注意在较小的集合中可行但在较大的集合中不可行的事情。比如蛮力检查。
  • @Tacit 我们可以就已提供的多个答案获得一些反馈吗?这些对你有意义吗?你认为你知道足够的知识来实施这些解决方案吗?您需要更多说明吗?等

标签: c# .net winforms visual-studio-2010 visual-c#-express-2010


【解决方案1】:

您不应该使用按钮执行此逻辑。创建一个实现逻辑的游戏类,您可以通过包含 X 和 Y 参数的函数调用来控制它。

然后在每次点击按钮时,如果左上角的按钮被点击,则调用类似game.MakeMove(0, 0); 的游戏逻辑。

这样做的好处:它是可测试的,用户界面可以很容易地改变。

【讨论】:

  • 这绝对是解决问题的最佳方式。但是我觉得原始海报可能是编程新手/可能正在做家庭作业,所以它可能有点超出这个项目可以完成的范围。
  • 是的,没错@jesse,我在这方面真的需要一些帮助。你愿意通过电子邮件交流吗?也许我可以把我的工作发给你
  • @jesse 不,我不只是想提高我的技能,我正在尝试学习如何处理数组和二维数组,我现在已经更改了我的代码,它可以使用二维数组,但我仍然在努力做我喜欢编程的获胜检测,所以我试图设置自己的迷你项目来正确学习它
  • 如果您使用 2D 数组进行工作,请考虑尝试实现我在原始答案中给您的逻辑。如果您至少开始使用它,那么我会考虑看看并给您一些正确方向的指示,但首先要看到一些努力;)
  • 另外,考虑在此处选择一个答案并将此问题标记为已解决,因为您知道需要做什么来解决此问题。您现在只需要着手实施。 Stack Overflow 不会为您编写代码。
【解决方案2】:

两个选项。更简单的方法是创建一个Button[][] 数组,然后填充它以匹配按钮的实际位置。然后可以通过索引查看其他按钮。

更复杂的是创建Button 的子类,它知道自己在网格中的位置(XY 属性)并知道如何找到相邻的按钮。然后你可以得到一个相同颜色的所有相邻按钮的列表,并以此方式建立一个链。

【讨论】:

    【解决方案3】:

    这是我认为没有任何代码的逻辑方法,因为我目前正在工作,无法测试任何东西。您需要将您的按钮或部件或您的游戏最终将位于某种二维数组/集合中,并为 X 和 Y 轴设置相应的值。

    当一个按钮被点击时,你只需要检查相关的触摸按钮来检查潜在的匹配。例如。让我们假设左下角的按钮位于位置 0,0。如果点击它,您只需检查 1,0 和 0,1 处的按钮,看看它们是否颜色相同,就知道匹配成功了。

    这可以很容易地扩展为有效集合所需的任何匹配项。它还允许您避免“蛮力”方法。在与之前完全相同的情况下,如果您连续查找 4 个并且 0,1 不是相同的颜色,您不需要检查 0,2 或 0,3 或沿该轴的任何其他内容,因为我们已经知道那里没有匹配项。

    【讨论】:

      【解决方案4】:

      您应该考虑使用多维数组来表示您的数据 - 按钮。换句话说,一个矩阵。

      基本上,您可以像这样声明您的按钮:

      private Button[,] buttons = new Button[2, 3];
      

      一个 MSDN 页面解释了how multidimensional arrays work

      然后,您可以对数组进行迭代以检测任何逻辑 - 水平、垂直、对角线匹配等。您可以编写如下内容:

      bool hasAWinner = false;
      // for each line
      for (int i = 0; i < 2; i++)
          Dictionary<Color, int> numberOfbuttonsWithColor = new Dictionary<Color, int>();
          numberOfbuttonsWithColor[Color.Red] = 0;
          numberOfbuttonsWithColor[Color.Yellow] = 0;
      
          // detect if there is at least two buttons of the same color
          for (int j = 0; j < 3; j++) {
              Color currentButtonColor = buttons[i,j].BackColor;
              numberOfbuttonsWithColor[currentButtonColor]++;
              if (numberOfbuttonsWithColor[currentButtonColor] == 2) {
                  hasAWinner = true;
                  break;
              }
          }
      
          if (hasAWinner) break;
      }
      
      
      // execute victory actions
      if (hasAWinner) {
          Console.writeline(String.format("Color {0} wins!", currentButtonColor);
      }
      

      【讨论】:

      • 为什么 bot red 和 yellow 的值为 0
      • 用于计算该行中具有该颜色的按钮的数量。然后,当我们开始计算每一行时,我们需要将该值重置为 0
      • 你愿意通过电子邮件沟通来帮助我做这件事吗,因为我发现很难让它工作,也许我可以把我的工作发给你
      • 对不起,我没空
      【解决方案5】:

      这个怎么样。

      以每个按钮的列和行命名。即btn00(左上角)、btnNN(右下角,N为行数和列数,假设为正方形)等

      在每个事件处理程序上,保存单击按钮的名称及其颜色。 然后遍历每种颜色的单击按钮集合并比较索引。 如果您找到两个符合以下条件的按钮名称,则为连续两个:

      if ((Math.Abs(index0ButtonA - index0ButtonB) == 1 && index1ButtonA == index1ButtonB) || ( Math.Abs(index1ButtonA - index1ButtonB) == 1 && index0ButtonA == index0ButtonB)
      {
           twoInARow = true;
      }
      

      【讨论】:

      • 这可能有效,但我不赞成使用按钮名称作为标识其位置的方法。这不是好的编码习惯。
      • 您也可以将列/行存储在标签中,也许这可能是一个好方法(虽然不确定标签是否在 WinForms 中可用,即 WPF)。
      猜你喜欢
      • 2016-08-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-23
      • 1970-01-01
      • 1970-01-01
      • 2014-07-21
      相关资源
      最近更新 更多