C# 自嗨:数独

本来想自己写个创建+解题的数独流程,但是…写着写着发现创建和解题就是直接连贯的…
所以干脆搞个81步创建数独的流程算了;
主要关键点
1.随机数
现在的版本而言,无论是java还是C#的random出来的随机数都不是平均分布,所以要随机的基础上取随机数;
2.排除3×3九宫格中有相同数字
这里可以直接
x和y不同的值域(1~ 3、4 ~ 6、7 ~ 9)组合出9个3×3的宫格然后对比坐标的值去排查,也可以像下面代码那样利用数理去分区排查;
PS.解特定题目用的位置主要用来解题,把固定的坐标点及对应值输入即可~

			Dictionary<Point, int> pointsDic_0 = new Dictionary<Point, int>
            {
                // 解特定题目用,只想随机生成一个标准数独就直接注释即可
                { new Point(1, 1), 0 },{ new Point(1, 2), 0 },{ new Point(1, 3), 0 },{ new Point(1, 4), 0 },{ new Point(1, 5), 0 },{ new Point(1, 6), 0 },{ new Point(1, 7), 0 },{ new Point(1, 8), 0 },{ new Point(1, 9), 0 },
                { new Point(2, 1), 0 },{ new Point(2, 2), 0 },{ new Point(2, 3), 0 },{ new Point(2, 4), 0 },{ new Point(2, 5), 0 },{ new Point(2, 6), 0 },{ new Point(2, 7), 0 },{ new Point(2, 8), 0 },{ new Point(2, 9), 0 },
                { new Point(3, 1), 0 },{ new Point(3, 2), 0 },{ new Point(3, 3), 0 },{ new Point(3, 4), 0 },{ new Point(3, 5), 0 },{ new Point(3, 6), 0 },{ new Point(3, 7), 0 },{ new Point(3, 8), 0 },{ new Point(3, 9), 0 },
                { new Point(4, 1), 0 },{ new Point(4, 2), 0 },{ new Point(4, 3), 0 },{ new Point(4, 4), 6 },{ new Point(4, 5), 0 },{ new Point(4, 6), 0 },{ new Point(4, 7), 0 },{ new Point(4, 8), 0 },{ new Point(4, 9), 0 },
                { new Point(5, 1), 0 },{ new Point(5, 2), 0 },{ new Point(5, 3), 0 },{ new Point(5, 4), 0 },{ new Point(5, 5), 0 },{ new Point(5, 6), 0 },{ new Point(5, 7), 0 },{ new Point(5, 8), 0 },{ new Point(5, 9), 0 },
                { new Point(6, 1), 0 },{ new Point(6, 2), 0 },{ new Point(6, 3), 0 },{ new Point(6, 4), 0 },{ new Point(6, 5), 0 },{ new Point(6, 6), 0 },{ new Point(6, 7), 0 },{ new Point(6, 8), 0 },{ new Point(6, 9), 0 },
                { new Point(7, 1), 0 },{ new Point(7, 2), 0 },{ new Point(7, 3), 0 },{ new Point(7, 4), 0 },{ new Point(7, 5), 0 },{ new Point(7, 6), 0 },{ new Point(7, 7), 0 },{ new Point(7, 8), 0 },{ new Point(7, 9), 0 },
                { new Point(8, 1), 0 },{ new Point(8, 2), 0 },{ new Point(8, 3), 0 },{ new Point(8, 4), 0 },{ new Point(8, 5), 0 },{ new Point(8, 6), 0 },{ new Point(8, 7), 0 },{ new Point(8, 8), 0 },{ new Point(8, 9), 0 },
                { new Point(9, 1), 0 },{ new Point(9, 2), 0 },{ new Point(9, 3), 0 },{ new Point(9, 4), 0 },{ new Point(9, 5), 0 },{ new Point(9, 6), 0 },{ new Point(9, 7), 0 },{ new Point(9, 8), 0 },{ new Point(9, 9), 0 },
            };

            string numbers = "" +
                "1 0 0 0 0 0 0 0 0 " +
                "2 0 0 0 0 0 0 0 0 " +
                "3 0 0 0 0 0 0 0 0 " +

                "4 0 0 0 0 0 0 0 0 " +
                "5 0 0 0 0 0 0 0 0 " +
                "6 0 0 0 0 0 0 0 0 " +
                
                "7 0 0 0 0 0 0 0 0 " +
                "8 0 0 0 0 0 0 0 0 " +
                "9 0 0 0 0 0 0 0 0 " +
                "";
            string[] nums = numbers.Split();
            for (int i = 0; i < nums.Length; i++)
                if (int.TryParse(nums[i], out int num))
                    pointsDic_0[ pointsDic_0.Keys.ToList()[i]] = num;

            List<Point> keys = new List<Point>(pointsDic_0.Keys);
            foreach (var key in keys)
                if (pointsDic_0[key] == 0)
                    pointsDic_0.Remove(key);

            Dictionary<Point, int> pointsDic = new Dictionary<Point, int>(pointsDic_0);// 结果3维数组
            Random random = new Random();
            int buildFailTime = 0;// 构建失败次数

            for (int i = 1; i < 10; i++)
                for (int j = 1; j < 10; j++)
                {
                    Point point = new Point(i, j);
                    if (pointsDic.ContainsKey(point)) 
                        continue;// 解谜用
                    int randomInt = random.Next(1, 1000) % 9 + 1;// 由于random.Next的随机数不够平均分布,所以用取余方式让其趋向平均分布
                    int testTime = 0;
                    do
                    {
                        randomInt++;
                        testTime++;
                        if (randomInt > 9) 
                            randomInt = 1;
                    }
                    while (testTime < 10 && pointsDic.Any((point_int) =>// 9次之内是否有不存在横竖或者3×3宫格重复的数(这里只讨论【标准数独】玩法),存在则找其他数
                        {
                            Point key = point_int.Key;
                            int x = key.X;
                            int y = key.Y;
                            if (x == i || y == j // 同一横竖轴
                                || ((i - 1) / 3 == (x - 1) / 3 && (j - 1) / 3 == (y - 1) / 3))// 同一3×3宫格
                                return randomInt == point_int.Value;

                            return false;
                        }));

                    if (testTime == 10)// 重新再构建
                    {
                        i = 1;
                        j = 0;
                        pointsDic.Clear();
                        pointsDic = new Dictionary<Point, int>(pointsDic_0);
                        buildFailTime++;
                    }
                    else
                        pointsDic.Add(point, randomInt);
                }

            Console.WriteLine("  buildFailTime:" + buildFailTime);
            for (int i = 1; i < 10; i++)
            {
                Console.Write("  ");
                if ((i - 1) % 3 == 0 && i != 1)
                {
                    for (int j = 0; j < 16; j++)
                        Console.Write("—");
                    Console.Write("\n  ");
                }

                for (int j = 1; j < 10; j++)
                {
                    if ((j - 1) % 3 == 0 && j != 1)
                        Console.Write("|  ");
                    Console.Write(pointsDic[new Point(i, j)] + "  ");
                }

                Console.WriteLine();
            }

            Console.ReadKey();

在这里插入图片描述

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值