检查C#中是否只有一个按钮未被点击

时间:2017-01-19 08:36:28

标签: c#

我是C#的初学者所以请耐心等待。 我在C#中创建了一个棋盘游戏,但我遇到了问题。 游戏看起来像这样: Solo Board game

  

两个白点是你的起始位置。游戏的目标是用白点填充棋盘,但只有一个点保持黑色。

我的问题是:如何检查所有按钮是否为白色且只有一个是黑色?

代码不是很优化。 Form1类用于表单,Stone类用于所有点,Win表单类用于赢得游戏时的表单。

Code Form1类:

using System;
using System.Windows.Forms;

namespace Solo
{
    public partial class Form1 : Form
    {
        //Objects
        public Stone[] st = new Stone[41];
        int[] x = { 50, 100, 150, 200, 250, 300, 350, 0, 50, 100, 150, 200, 250, 300, 350, 400, 0, 50, 100, 150, 200, 250, 300, 350, 400, 50, 100, 150, 200, 250, 300, 350, 100, 150, 200, 250, 300, 150, 200, 250, 200 };
        int[] y = { 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 100, 100, 100, 100, 100, 100, 100, 100, 100, 150, 150, 150, 150, 150, 150, 150, 200, 200, 200, 200, 200, 250, 250, 250, 300 };

        bool cl = true;

        public Form1()
        {
            InitializeComponent();

            for (int a = 0; a < 41; a++)
            {
                st[a] = new Stone();
            }

            st[12].getPen().Color = System.Drawing.Color.White;
            st[13].getPen().Color = System.Drawing.Color.White;
            st[0].setClick(cl);
        }

        public void Form1_Load(object sender, EventArgs a)
        {
            for (int i = 0; i < st.Length; i++)
            {
                st[i].setLocation(x[i], y[i]);
                st[i].Click += new EventHandler(st[i].stone_Click);

                this.Controls.Add(st[i]);
            }
        }
    }
}

Code Stone类:

using System;
using System.Drawing;
using System.Windows.Forms;

namespace Solo
{
    public class Stone : Button
    {
        Pen pen = new Pen(Color.Black, 19);

        bool clicked = false;

        public Stone()
        {
            this.Paint += new PaintEventHandler(this.Stone_Paint);
            this.FlatStyle = FlatStyle.Flat;
            this.FlatAppearance.BorderSize = 0;
            this.Size = new Size(40, 40);
        }

        public void setLocation(int x, int y)
        {
            Point loc = new Point(x, y);
            this.Location = loc;
        }

        public void stone_Click(object sender, EventArgs a)
        {
            Button btn = sender as Button;

            if (clicked == true)
            {
                pen.Color = Color.Black;
                Invalidate();
                clicked = false;
                Console.WriteLine(clicked);
            }

            else if (clicked == false && pen.Color == Color.Black)
            {
                pen.Color = Color.White;
                Invalidate();
                clicked = true;
                Console.WriteLine(clicked);
            }
        }

        public void Stone_Paint(object sender, PaintEventArgs b)
        {
            b.Graphics.DrawEllipse(pen, 10, 10, 19, 19);
        }

        public Pen getPen()
        {
            return pen;
        }

        public void setClick(bool bl)
        {
            bl = clicked;
        }
    }
}

Code Win Form Class:

using System;
using System.Drawing;
using System.Windows.Forms;

namespace Solo
{
    public partial class Win : Form
    {
        Button okBut = new Button();
        Label txt = new Label();

        public Win()
        {
            InitializeComponent();

            this.Text = "U hebt Gewonnen!!!";
            this.BackColor = Color.Green;
            this.ForeColor = Color.White;
            this.StartPosition = FormStartPosition.CenterScreen;

            okBut.BackColor = Color.White;
            okBut.ForeColor = Color.Black;
            okBut.Size = new Size(90, 25);
            okBut.Location = new Point(140, 240);
            okBut.Text = "OK";
            okBut.Click += new EventHandler(this.okBut_Click);

            txt.Text = "U hebt Gewonnen!!!";
            txt.Location = new Point(20, 100);
            txt.Size = new Size(400, 100);
            txt.Font = new Font("Arial", 25.0f, FontStyle.Bold);

            this.Controls.Add(okBut);
            this.Controls.Add(txt);
        }

        public void okBut_Click(object sender, EventArgs e)
        {
            this.Hide();
        }
    }
}

我希望这是足够的信息。 提前谢谢!

4 个答案:

答案 0 :(得分:1)

如果我正确理解了您的代码,您就会记住是否在Stone.clicked变量中点击了一块石头。

公开此变量,以便可以从Stone类外部访问它:

public class Stone : Button {
    public bool Clicked { get; private set; }
}

然后,您可以通过检查Stone[] st来检查每次点击后的整体状态。我这样做是使用LINQ:

bool onlyOneNotClicked = st.Count(s => s.Clicked) == st.Length -1;

修改

根据prof1990的建议,以下内容更具可读性:

bool onlyOneNotClicked = st.Count(s => s.!Clicked) == 1;

此外,将Stone.Clicked私人设定为私人,确保没有人可以从外面捣乱国家。

答案 1 :(得分:1)

所以,实际上,您要检查Stone s,而不是Button s;在 Linq 的帮助下,你可以这样说:

  

如何检查所有按钮是否为白色且只有一个是黑色?

   var blackCount = Controls
     .OfType<Stone>()
     .Count(stone => stone.getPen().Color == System.Drawing.Color.Black);

   if (blackCount == 1) {
     ...
   }

PS 事实上,我不喜欢混合UI的条件stone.getPen().Color == System.Drawing.Color.Black(按钮的颜色;如果将按钮重新分为灰色和黄色会怎样?)和逻辑(采取和活石)。您可能应该将条件更改为stone => stone.Clicked

答案 2 :(得分:0)

您需要将石头颜色设为公共属性,并在每次点击后检查Form1课程中的获胜条件。 条件是:

st.Count(x => x.Color == Color.Black) == 1 &&
st.Count(x => x.Color == Color.White) == st.Count() - 1

答案 3 :(得分:0)

假设未点击的石头仍为黑色..

        int numBlack = 0;
        for (int i = 0; i < st.Length; i++)
        {
            if (!st[i].Clicked) numBlack++;
        }

这可以在每次点击一块石头时运行,这样你就可以检查有多少石头仍然是黑色的