我正在编写数独应用程序,目前正致力于游戏生成算法。我设法找到了如何快速生成解决方案(而不是求解)。然而,我被如何移除一些数字以制作出一个谜题所困扰。我的第一反应是根据难度随机删除某个单元格的数量,但这并不是正确的算法,因为它经常会生成无解或有多个解的谜题。它也可能会生成与请求的难度不符的谜题。
这是我迄今为止的代码。我删除了大部分无关的代码,但如果您想看到下面使用的未实现的内容,请告诉我。如果您愿意,我还可以提供我尝试的“ Puzzlefy”方法,但我选择不立即发布它,因为它明显是错误的(即使它“有效”)。
这是我迄今为止的代码。我删除了大部分无关的代码,但如果您想看到下面使用的未实现的内容,请告诉我。如果您愿意,我还可以提供我尝试的“ Puzzlefy”方法,但我选择不立即发布它,因为它明显是错误的(即使它“有效”)。
using System;
using System.Collections.Generic;
using System.Linq;
namespace Sudoku
{
public class Game
{
public enum Difficulty
{
VeryEasy,
Easy,
Medium,
Difficult,
Evil
}
private readonly int?[,] _currentItems = new int?[9,9];
private readonly int?[,] _solution = new int?[9,9];
private readonly int?[,] _startingItems = new int?[9,9];
private readonly Difficulty _difficulty;
public Game(Difficulty difficulty)
{
_difficulty = difficulty;
GenerateSolution();
Puzzlefy();
}
private void GenerateSolution()
{
var random = new Random();
var availableNumbers = new Stack<List<int?>>(81);
var x = 0;
var y = 0;
availableNumbers.Push(AllowableNumbers(_solution, 0, 0).ToList());
while (x < 9 && y < 9)
{
var currentAvailableNumbers = AllowableNumbers(_solution, x, y).ToList();
availableNumbers.Push(currentAvailableNumbers);
// back trace if the board is in an invalid state
while (currentAvailableNumbers.Count == 0)
{
_solution[x, y] = null;
availableNumbers.Pop();
currentAvailableNumbers = availableNumbers.Peek();
x -= y >= 1 ? 0 : 1;
y = y >= 1 ? y - 1 : 8;
}
var index = random.Next(currentAvailableNumbers.Count);
_solution[x, y] = currentAvailableNumbers[index];
currentAvailableNumbers.RemoveAt(index);
x += y < 8 ? 0 : 1;
y = y < 8 ? y + 1 : 0;
}
}
private void Puzzlefy()
{
CopyCells(_solution, _startingItems);
// remove some stuff from _startingItems
CopyCells(_startingItems, _currentItems);
}
}
}
我不是在寻找代码,而是算法。如何去除解决方案中的数字,使其成为一个谜题?