数独暴力破解代码(code by unity)

using System.Collections.Generic;
using UnityEditor;
using UnityEngine;

public class testSudo
{
class SudokuItem
{
public bool isNormal = false; //固定数字 不需要检测期望值
public int value; //该item存的值
public List<int> expectValueList; //该item是否可用1-9 1:可用 0:不可用
}

static List<List<SudokuItem>> sudoList;

[MenuItem("testSudo/action")]
public static void SudoAction()
{
int[][] target = {
new int[]{8,0,0,0,0,0,0,0,0},
new int[]{0,0,3,6,0,0,0,0,0},
new int[]{0,7,0,0,9,0,2,0,0},
new int[]{0,5,0,0,0,7,0,0,0},
new int[]{0,0,0,0,4,5,7,0,0},
new int[]{0,0,7,1,0,0,0,3,0},
new int[]{0,0,1,0,0,0,0,6,8},
new int[]{0,0,8,5,0,0,0,1,0},
new int[]{0,9,0,0,0,0,4,0,0}
};

ConstructionSudoku(target);
BeginCalculate(0);

string log = " ";
for (int r = 0; r < 9; r++)
{
for (int c = 0; c < 9; c++)
{
log += sudoList[r][c].value + " ";
}

log += "\n ";
}

Debug.Log(log);
}

//构建一个数独链表
public static void ConstructionSudoku(int[][] target)
{
sudoList = new List<List<SudokuItem>>();
for (int r = 0; r < 9; r++)
{
List<SudokuItem> rList = new List<SudokuItem>();
for (int c = 0; c < 9; c++)
{
SudokuItem newItem = new SudokuItem();
newItem.value = 0;
newItem.expectValueList = new List<int>(new int[9] { 1, 1, 1, 1, 1, 1, 1, 1, 1 });
rList.Add(newItem);
}

sudoList.Add(rList);
}

for (int r = 0; r < 9; r++)
{
for (int c = 0; c < 9; c++)
{
if (target[r][c] > 0)
{
sudoList[r][c].isNormal = true;
sudoList[r][c].value = target[r][c];
sudoList[r][c].expectValueList = new List<int>(new int[9] { 0, 0, 0, 0, 0, 0, 0, 0, 0 });
RemoveExpectValue(r, c, target[r][c]);
}
}
}
}

//去掉由于固定数字导致的该格子对应的行列宫其他格子对该数字的期待
public static void RemoveExpectValue(int rIndex, int cIndex, int value)
{
for (int r = 0; r < 9; r++)
{
for (int c = 0; c < 9; c++)
{
if (r == rIndex || c == cIndex || (r / 3 == rIndex / 3 && c / 3 == cIndex / 3))
{
sudoList[r][c].expectValueList[value - 1] = 0;
}
}
}
}

//开始递归检测
public static bool BeginCalculate(int index)
{
if (index >= 81) return true;

int r = index / 9;
int c = index % 9;

if (sudoList[r][c].isNormal)//是固定数直接跳下一个
{
return BeginCalculate(index + 1);
}

for (int v = 1; v <= 9; v++)
{
if (sudoList[r][c].expectValueList[v - 1] == 0) continue; //该数字不可用跳过

// 先判断数字可不可用,可用则先填到该格子,然后前往下一个格子
if (CheckNumbervalid(r, c, v))
{
sudoList[r][c].value = v;
if (BeginCalculate(index + 1)) return true;
}
}

//所有数字都不可用的话 重置为0 并返回上一层
sudoList[r][c].value = 0;
return false;
}

//检测某个格子是否可用某个数字
public static bool CheckNumbervalid(int rIndex, int cIndex, int value)
{
//行
for (int c = 0; c < 9; c++)
{
if (c != cIndex && sudoList[rIndex][c].value == value)
{
return false;
}
}

//列
for (int r = 0; r < 9; r++)
{
if (r != rIndex && sudoList[r][cIndex].value == value)
{
return false;
}
}

//宫
for (int g = rIndex / 3 * 3; g < rIndex / 3 * 3 + 3; g++)
{
for (int i = cIndex / 3 * 3; i < cIndex / 3 * 3 + 3; i++)
{
if (g != rIndex && i != cIndex && sudoList[g][i].value == value)
{
return false;
}
}
}

return true;
}
}

转载于:https://www.cnblogs.com/Xjl4030/p/5846948.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值