-1

可能重复:
c#使用二维数组作为按钮

我正在使用将扩展到 7x6 的 2x2 板进行游戏。

我目前正在做获胜检测,但我认为我正在做很长的路要走。必须有一个更短的方法。

胜利

  1. 横向
  2. 垂直
  3. 对角线

这是游戏板的图片:

在此处输入图像描述

这就是我目前检测获胜者的方式

if (btns[0, col].BackColor.Equals(Color.Red) && btns[1, col].BackColor.Equals(Color.Red))
{
    MessageBox.Show("Red Win");
}

if (btns[0, col].BackColor.Equals(Color.Blue) && btns[1, col].BackColor.Equals(Color.Blue))
{
    MessageBox.Show("Blue Win");
}

这种方式好像我必须列出所有的组合,当我扩展到 7x6 时它不会很理想。

这是程序的全部代码

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {

        private Button[,] btns;

        public Form1()
        {
            InitializeComponent();

            btns = new Button[,] { { button2 , button1 },
                                   { button4 , button3 }};
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            foreach (var btn in btns)
            {
                btn.Enabled = false;
            }
        }
        int cc = 0;


        private void button5_Click(object sender, EventArgs e)
        {
          // Button[] row1 = new Button[] {button2, button1};

            for (int col = 0; col < btns.GetLength(1); ++col)
            {
                var btn = btns[0, col];

                if (!btn.Enabled)
                {
                    btn.Enabled = true;

                    if (cc == 0)
                    {
                        cc = 1;
                        btn.BackColor = Color.Red;
                    }
                    else
                    {
                        cc = 0;
                        btn.BackColor = Color.Blue;
                    }

                    if (btns[0, col].BackColor.Equals(Color.Red) && btns[1, col].BackColor.Equals(Color.Red))
                    {
                        MessageBox.Show("Red Win");
                    }

                    if (btns[0, col].BackColor.Equals(Color.Blue) && btns[1, col].BackColor.Equals(Color.Blue))
                    {
                        MessageBox.Show("Blue Win");
                    }

                    return;
                }
            }
        }


        private void button6_Click(object sender, EventArgs e)
        {
           // Button[] row2 = new Button[] { button4, button3 };
            for (int col = 0; col < btns.GetLength(1); ++col)
            {
                var btn = btns[1, col];

                if (!btn.Enabled)
                {
                    btn.Enabled = true;

                    if (cc == 0)
                    {
                        cc = 1;
                        btn.BackColor = Color.Red;
                    }
                    else
                    {
                        cc = 0;
                        btn.BackColor = Color.Blue;
                    }

                    if (btns[1, col].BackColor.Equals(Color.Red) && btns[0, col].BackColor.Equals(Color.Red))
                    {
                        MessageBox.Show("Red Win");
                    }

                    if (btns[1, col].BackColor.Equals(Color.Blue) && btns[0, col].BackColor.Equals(Color.Blue))
                    {
                        MessageBox.Show("Blue Win");
                    }
                    return;
                }
            }
        }
    }
}

我已经尝试了很多其他方法,但我似乎无法让它发挥作用。

4

3 回答 3

2

也许这个答案很复杂,我会得到很多反对意见,但我无法抗拒尽可能优化地解决这个问题。尝试详细检查此代码:

        int n; //dimension of the matrix
        Button [,] btns;
        public Form1()
        {
            InitializeComponent();
            n = 2;/*You should set here the dimension of your matix. I considered it nxn because of diagonals. If you want nxm matrix than the code is a little bit complicated but not too much*/
            btns = new Button[n, n];
            for(int i = 0;i<n;i++)
               for(int j = 0; j<n; j++)
               {
                   Button btn = new Button();
                   btn.Location = new Point(i*20,j*40);
                   btn.Size = new Size(18,38);
                   btns[i,j] = btn;
                   this.Controls.Add(btn);
               }

        }

        private void button1_Click(object sender, EventArgs e)
        {
            int mainDiag = 0;
            int secDiag = 0;
            int i = 0;
            int j = 0;
            int [] cols = new int[n];
            int winner = 0; //no winner
            while(winner == 0 && i<n)
            {
                int row = 0;
                j = 0;
                while(j<n)
                {
                    if (btns[i, j].BackColor == Color.Blue)
                    {

                        if (i == j)
                            mainDiag++;//inrement main diagonal
                        if(i + j == n-1)
                            secDiag++;//increment second diagonal
                        row++; //increment row
                        cols[i]++; //increment column
                    }
                    else if (btns[i, j].BackColor == Color.Red)
                    {
                        if (i == j)
                            mainDiag--;
                        if(i + j == n-1)
                            secDiag--;
                        row--;
                        cols[i]++;
                    }
                    j++;
                }
                if(row == n) //if row value == n whole row is blue and blue player wins
                    winner = 1;
                else if(row == -n)
                    winner = -1; //if row value == -n whole row is red and red player wins
                i++;
            }
            if(winner == 0)
            {
                if(mainDiag == n)
                    winner = 1; //similar for the diagonal
                else if(mainDiag == -n)
                    winner = -1; 
                else if(secDiag == n)
                    winner = 1;//similar for the second diagonal
                else if(secDiag == -n)
                    winner = -1;
                else
                {
                    i = 0;
                    while (winner == 0 && i < n)
                    {
                        if (cols[i] == n)
                            winner = 1; //i-th column is whole blue and blue player wins
                        else if (cols[i] == -n)
                            winner = -1; //i-th column is whole red and red player wins
                    }
                }
            }
            if (winner == 1)
                MessageBox.Show("Blue wins");
            else if(winner == -1)
                MessageBox.Show("Red wins");


        }
于 2012-11-01T21:49:18.963 回答
1

正如人们在评论中所说,您可能需要使用循环来执行此操作。

我不会在这里详细介绍,但我会描述一些算法来完成你的获胜条件检测。

算法 1:
对于每个单元格,检测它是否是水平、垂直或对角行的一部分。时间复杂度为 O(n^(3/2))。如果您愿意,您可以考虑重复检查,但您不必这样做。

算法 2:
检查所有垂直行、所有水平行和所有对角行,并查看这些行是否存在获胜条件。这种方法的时间复杂度应该大约为 O(n)。通过不检查不足以保持获胜条件的对角线行,您可能会节省一点时间,但您不必这样做。

于 2012-11-01T21:13:50.343 回答
1

如果您想要一个非常基本的答案,我会考虑以下

将每一行添加到数组中

将每一列添加到数组中

对于数组中的每个项目,如果它们都等于一种颜色,那么您就赢了

当您处理较大的数字(即 6x6 网格)时,您可能希望使用多维数组

于 2012-11-01T21:40:28.627 回答