数独 C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Sudoku.UI
{
    public class XRow
    {
        public int C1 { get; set; }
        public int C2 { get; set; }
        public int C3 { get; set; }
        public int C4 { get; set; }
        public int C5 { get; set; }
        public int C6 { get; set; }
        public int C7 { get; set; }
        public int C8 { get; set; }
        public int C9 { get; set; }
        public int this[int key]
        {
            set
            {
                if (key == 1)
                {
                    C1 = value;
                }
                else if (key == 2)
                {
                    C2 = value;
                }
                else if (key == 3)
                {
                    C3 = value;
                }
                else if (key == 4)
                {
                    C4 = value;
                }
                else if (key == 5)
                {
                    C5 = value;
                }
                else if (key == 6)
                {
                    C6 = value;
                }
                else if (key == 7)
                {
                    C7 = value;
                }
                else if (key == 8)
                {
                    C8 = value;

                }
                else if (key == 9)
                {
                    C9 = value;
                }
            }
            get
            {
                if (key == 1)
                {
                    return C1;
                }
                else if (key == 2)
                {
                    return C2;
                }
                else if (key == 3)
                {
                    return C3;
                }
                else if (key == 4)
                {
                    return C4;
                }
                else if (key == 5)
                {
                    return C5;
                }
                else if (key ==6)
                {
                    return C6;
                }
                else if (key == 7)
                {
                    return C7;
                }
                else if (key == 8)
                {

                    return C8;
                }
                else if (key == 9)
                {
                    return C9;
                }
                throw new Exception("索引异常!");
            }
        }
    }
    public class XCell
    {
        public int R { get; set; }
        public int C { get; set; }
        public int B { get; set; }
        public int V { get; set; }
        public List<int> Candidate { get; set; }
        public XCell()
        {
            Candidate = new List<int>();
        }
    }
    public class XB
    {
        public int RBegin { get; set; }
        public int REnd { get; set; }
        public int CBegin { get; set; }
        public int CEnd { get; set; }
        public int B { get; set; }
    }
}
View Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Sudoku.UI
{
    public partial class Form1 : Form
    {
        private int[,] _Area=new int[10,10];
        private List<XB> _BList = new List<XB>();
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            var r=Do(_Area);
            if (!r)
            {
                MessageBox.Show("填充失败!");
            }
            else
            {
                MessageBox.Show("完成了!");
            }
            
        }

        private void button2_Click(object sender, EventArgs e)
        {
            Init();
          
        }

        private void Init()
        {
            // var data = "001003097;006700030;023980500;107008900;008500100;004309608;005032710;070005200;810600300";
            //var data = "005480000;001300002;900000010;000200700;010000060;003009000;090000008;400003500;000067400";
            var data = "000000000;000000000;000000000;000000000;000000000;000000000;000000000;000000000;000000000";
            var arr = data.Split(";".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
            for (int i = 1; i <= 9; i++)
            {
                for (int j = 1; j <= 9; j++)
                {
                    _Area[i, j] = int.Parse(arr[i - 1].Substring(j - 1, 1));
                }
            }
            Show();
            _BList.Add(new XB() { RBegin = 1, REnd = 3, CBegin = 1, CEnd = 3});
            _BList.Add(new XB() { RBegin = 1, REnd = 3, CBegin = 4, CEnd = 6 });
            _BList.Add(new XB() { RBegin = 1, REnd = 3, CBegin = 7, CEnd = 9 });

            _BList.Add(new XB() { RBegin = 4, REnd = 6, CBegin = 1, CEnd = 3 });
            _BList.Add(new XB() { RBegin = 4, REnd = 6, CBegin = 4, CEnd = 6 });
            _BList.Add(new XB() { RBegin = 4, REnd = 6, CBegin = 7, CEnd = 9 });

            _BList.Add(new XB() { RBegin = 7, REnd = 9, CBegin = 1, CEnd = 3 });
            _BList.Add(new XB() { RBegin = 7, REnd = 9, CBegin = 4, CEnd = 6 });
            _BList.Add(new XB() { RBegin = 7, REnd = 9, CBegin = 7, CEnd = 9 });
        }
        private int[,] CopyArray(int[,] arr)
        {
            var tArr = new int[arr.GetLength(0), arr.GetLength(1)];
            for (int i = 0; i < arr.GetLength(0); i++)
            {
                for (int j = 0; j < arr.GetLength(1); j++)
                {
                    tArr[i, j] = arr[i, j];
                }
            }
            return tArr;
        }
        private bool Do(int[,] area)
        {
            var arrTmp = CopyArray(area);

            var cell = GetCell(arrTmp);
            if (cell != null)
            {

                foreach (var v in cell.Candidate)
                {


                    arrTmp[cell.R, cell.C] = v;
                    //if (!CheckPart(arrTmp))
                    //{
                    //    continue;
                    //}
                    if (Do(arrTmp))
                    {
                        return true;
                    }
                }
                return false;
            }
            else
            {
                if (CheckFinally(arrTmp))
                {
                   
                    _Area = CopyArray(arrTmp);
                    Show();
                    return true;
                }
                return false;
            }
        }
        private bool CheckFinally(int[,] area)
        {
            #region 行检测
            for (int row = 1; row <= 9; row++)
            {
                var count=new int[10];
                for (int i = 1; i <=9; i++)
                {
                    count[area[row, i]] = 1;
                }
                for (int i = 1; i <= 9; i++)
                {
                    if (count[i] == 0)
                    {
                        return false; //行扫描失败

                    }
                }
            }
            #endregion
            #region 列检测

            for (int col = 1; col <= 9; col++)
            {
                var count = new int[10];
                for (int i = 1; i <= 9; i++)
                {
                    count[area[i, col]] = 1;
                }
                for (int i = 1; i <= 9; i++)
                {
                    if (count[i] == 0)
                    {
                        return false; //列扫描失败

                    }
                }
            }
           #endregion
            #region B检测
            foreach (var b in _BList)
            {
                var count = new int[10];
                for (int row = b.RBegin; row <= b.REnd; row++)
                {
                    for (int col = b.CBegin; col <= b.CEnd; col++)
                    {
                        count[area[row, col]] = 1;
                    }
                }
                for (int index = 1; index <= 9; index++)
                {
                    if (count[index] == 0)
                    {
                        return false; //列扫描失败

                    }
                }

            }
            #endregion

            return true;

        }
        private bool CheckPart(int[,] area)
        {
            #region 行检测
            for (int row = 1; row <= 9; row++)
            {
                var count = new int[10];
                for (int i = 1; i <= 9; i++)
                {
                    count[area[row, i]]++;
                }
                for (int i = 1; i <= 9; i++)
                {
                    if (count[i] >1)
                    {
                        return false; //行扫描失败

                    }
                }
            }
            #endregion
            #region 列检测

            for (int col = 1; col <= 9; col++)
            {
                var count = new int[10];
                for (int i = 1; i <= 9; i++)
                {
                    count[area[i, col]]++;
                }
                for (int i = 1; i <= 9; i++)
                {
                    if (count[i]>1)
                    {
                        return false; //列扫描失败

                    }
                }
            }
            #endregion
            #region B检测
            foreach (var b in _BList)
            {
                var count = new int[10];
                for (int row = b.RBegin; row <= b.REnd; row++)
                {
                    for (int col = b.CBegin; col <= b.CEnd; col++)
                    {
                        count[area[row, col]]++;
                    }
                }
                for (int index = 1; index <= 9; index++)
                {
                    if (count[index] >1)
                    {
                        return false; //列扫描失败

                    }
                }

            }
            #endregion

            return true;

        }
        private XCell GetCell(int[,] area)
        {
            XCell cell = null;

            for (int row = 1; row <= 9; row++)
            {
                for (int col= 1; col <= 9; col++)
                {
                    if (area[row, col] == 0)
                    {
                        cell = new XCell();
                        cell.R = row; cell.C = col;
                        #region 设定宫数
                        if (row <= 3 && col <= 3)
                        {
                            cell.B = 1;
                        }
                        else if (row<=3 && col >=4 && col<=6)
                        {
                            cell.B = 2;

                        }
                        else if (row<=3 && col>=6 )
                        {
                            cell.B = 3;
                        }
                        else if (row>=3 && row <= 6 && col <= 3)
                        {
                            cell.B = 4;
                        }
                        else if (row >= 4 && row <= 6 && col >= 4 && col <= 6)
                        {
                            cell.B = 5;

                        }
                        else if (row >= 4 && row <= 6 && col >= 7)
                        {
                            cell.B = 6;
                        }
                        else if (row >= 7 && col <= 3)
                        {
                            cell.B = 7;
                        }
                        else if (row >= 7 && col >= 4 && col <= 6)
                        {
                            cell.B = 8;
                        }
                        else if (row >= 7 && col >= 7)
                        {
                            cell.B = 9;
                        }

                        #endregion
                        #region 计算可能取值
                        var count=new int[10];
                        for (int index = 1; index <= 9; index++)
                        {
                            count[area[cell.R, index]] = 1;
                        }
                        for (int index = 1; index <= 9; index++)
                        {
                            count[area[index, cell.C]] = 1;
                        }

                        #region B检测
                        var b = _BList[cell.B - 1];
                        for (int rowIndex = b.RBegin; rowIndex <= b.REnd; rowIndex++)
                        {
                            for (int colIndex = b.CBegin; colIndex <= b.CEnd; colIndex++)
                            {
                                count[area[rowIndex, colIndex]]=1;
                            }
                        }

                        
                        #endregion

                        for (int index = 1; index < 10; index++)
                        {
                            if (count[index] == 0)
                            {
                                cell.Candidate.Add(index);
                            }
                        }
                        #endregion
                        return cell;
                    }
                }
            }
            return cell;
        }

        private void Show()
        {
            var list = new List<XRow>();
            for (int i = 1; i <= 9; i++)
            {
                var row = new XRow();
                list.Add(row);
                for (int j = 1; j <= 9; j++)
                {
                    row[j] = _Area[i, j];
                }
            }
            xRowBindingSource.Clear();
            xRowBindingSource.DataSource = list;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            button2.PerformClick();
        }

    }
}
View Code
原文地址:https://www.cnblogs.com/wdfrog/p/14720601.html