C# Winform自动填写数独

所有填空标签为Textbox,从左边第一行第一列开始,ID值为textbox1,依次从左至右,textbox2.........textbox81。


 图片


实体类 Point

public class Point
    {
        private int col;// 行号 
        private int row;// 列号 
        private bool flag = false;// 真为未设置。 
        private int value;

        public Point() { }

        // 构造点 
        public Point(int col, int row, bool flag, int value)
        {
            this.col = col;
            this.row = row;
            this.flag = flag;
            this.value = value;
        }

        public void changeFlag()
        {
            flag = !flag;
        }

        public bool getFlag()
        {
            return flag;
        }

        public int getValue()
        {
            return value;
        }

        public void setValue(int value)
        {
            this.value = value;
        }

        public bool canHere(Point[,] pArr)
        {
            bool cb = canCol(pArr);
            bool cr = canRow(pArr);
            bool cminiArr = canMiniArr(pArr);
            return cb && cr && cminiArr;
        }

        //判断在小3*3格子里是否有相同元素 
        private bool canMiniArr(Point[,] pArr)
        {
            int coltemp = this.col % 3;
            int rowtemp = this.row % 3;

            for (int i = this.col - coltemp; i < col + (3 - coltemp); i++)
            {
                for (int j = this.row - rowtemp; j < row + (3 - rowtemp); j++)
                {
                    if (i == this.col && j == this.row)
                    {
                        continue;
                    }
                    else
                    {
                        if (this.value == pArr[i,j].getValue())
                        {
                            return false;
                        }
                    }
                }
            }
            return true;
        }

        // 判断列上是否有相同元素 
        private bool canRow(Point[,] pArr)
        {
            for (int i = 0; i < 9; i++)
            {
                if (i == this.col)
                {
                    continue;
                }
                else
                {
                    if (this.value == pArr[i,this.row].value)
                    {
                        // 行变,列不变 
                        return false;
                    }
                }
            }
            return true;
        }

        // 判断行上是否有相同元素 
        private bool canCol(Point[,] pArr)
        {
            for (int i = 0; i < 9; i++)
            {
                if (i == this.row)
                {
                    continue;
                }
                else
                {
                    if (this.value == pArr[this.col,i].value)
                    {
                        // 列边,行不变 
                        return false;
                    }
                }
            }
            return true;
        } 
    }  


Form1 窗体类
public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
 
       //计算按钮)
        private void btnCalculate_Click(object sender, EventArgs e)
        {
            if (InputNum())
            {
                Point[,] numMat = new Point[9, 9];
                List<Point> al = new List<Point>();

                initNumMat(numMat, al);

                setNum(numMat, al);

                printMat(numMat);
            }
            else
            {
                MessageBox.Show("请确保填入的是数字(或者已经完成全部数字)!");
            }
        }

        //确保写入都是数字
        public bool InputNum()
        {
            bool flag = true;
            int num = 0;
            foreach (Control control in panel1.Controls)
            {
                if (control is TextBox && control.Text != string.Empty)
                {
                    num++;
                    int i = 0;
                    if (!int.TryParse(control.Text, out i))
                    {
                        return flag = false;
                    }
                }
            }

            if (num > 80) { flag = false; }
            return flag;
        }

        //自动换算所有合适值
        private void setNum(Point[,] numMat, List<Point> al)
        {
            int i = 0;
            int j = 0;
            while (i != 9)
            {
                if (numMat[i, j].getFlag())
                {
                    for (int v = numMat[i, j].getValue() + 1; v <= 9; v++)
                    {
                        //给回退到的位置的值加一。 
                        numMat[i, j].setValue(v);
                        if (numMat[i, j].canHere(numMat))
                        {
                            //满足条件,不冲突。 
                            numMat[i, j].changeFlag();//改变标记为假。表示已设置过。 
                            break;
                        }
                        else
                        {
                            //满足不条件,冲突。value值自加一次 
                        }

                        while (v == 9)
                        {
                            //如果1-9都不能满足要求,则先将本位重置为0,并回退一格,给回退到的位置的值加一(当回退位置的值不为9时,并且保证回退到的位置不是九宫格原本的点)。 
                            numMat[i, j].setValue(0);
                            j--;
                            if (j == -1)
                            {
                                i--;
                                j = 8;
                            }
                            while (al.Contains(numMat[i, j]))
                            {
                                //如果回退到的位置为九宫格本来的点时,继续回退,直到不是本身的点时跳出while。 
                                j--;
                                if (j == -1)
                                {
                                    i--;
                                    j = 8;
                                }
                            }
                            numMat[i, j].changeFlag();//将标记 
                            v = numMat[i, j].getValue();
                        }
                    }
                }
                j++;
                if (j == 9)
                {
                    j = 0; i++;//此处i++ 可能使i自加为9,故下面需要i!=9判断 
                }
                if (i != 9)
                {
                    while (al.Contains(numMat[i, j]))
                    {
                        j++;
                        if (j == 9)
                        {
                            j = 0;
                            i++;
                            //防止下标越界
                            if (i > 8) { break; }
                        }
                    }
                }
            } 
        }

        //int m=a.GetLength(0); 一维获取长度
        //int n=a.GetLength(1); 二维获取长度

        //初始值
        public void initNumMat(Point[,] numMat, List<Point> al)
        {
            for (int i = 0; i < numMat.GetLength(0); i++)
            {
                for (int j = 0; j < numMat.GetLength(1); j++)
                {
                    numMat[i, j] = new Point(i, j, true, 0);
                }
            }
            initNumMat2(numMat, al);
        }

        //获取值
        public void initNumMat2(Point[,] numMat, List<Point> al)
        {
            foreach (Control control in panel1.Controls)
            {
                if (control is TextBox && control.Text != string.Empty)
                {
                    int id = Convert.ToInt32(control.Name.Replace("textBox", ""));
                    int num1 = 0;
                    int num2 = 0;
                    if (id % 9 == 0)
                    {
                        num1 = id / 9 - 1;
                        num2 = 8;
                    }
                    else
                    {
                        num1 = id / 9;
                        num2 = id % 9 - 1;
                    }

                    numMat[num1, num2].setValue(Convert.ToInt32(control.Text));
                    numMat[num1, num2].changeFlag();
                    al.Add(numMat[num1, num2]);

                }
            }
        }

        //完成数独
        public void printMat(Point[,] numMat)
        {
            foreach (Control control in panel1.Controls)
            {
                if (control is TextBox && control.Text == string.Empty)
                {
                    int id = Convert.ToInt32(control.Name.Replace("textBox", ""));
                    int num1 = 0;
                    int num2 = 0;
                    if (id % 9 == 0)
                    {
                        num1 = id / 9 - 1;
                        num2 = 8;
                    }
                    else
                    {
                        num1 = id / 9;
                        num2 = id % 9 - 1;
                    }

                    control.Text = numMat[num1, num2].getValue().ToString();
                }
            }
        }  



  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值