2013-02-13 3 views
3

나는 스도쿠 응용 프로그램을 작성 중이며 현재 게임 생성 알고리즘을 작업 중입니다. 나는 해결책을 신속하게 생성하는 방법을 알아 냈다. 그래도 실제로 퍼즐로 만들 숫자의 일부를 제거하는 방법에 난처한 있습니다. 내 첫 번째 성향은 난이도에 따라 임의의 수의 셀을 무작위로 제거하는 것이었지만, 해결할 수없는 퍼즐을 렌더링하거나 여러 솔루션을 가지고 있기 때문에 올바른 알고리즘이 아닙니다. 또한 요청 된 어려움을 반영하지 않는 퍼즐을 생성 할 수도 있습니다.퍼즐을 만들기 위해 스도쿠 솔루션에서 셀 제거

여기 제가 지금까지 가지고있는 코드입니다. 관련성이없는 코드는 대부분 제거했지만 구현되지 않았지만 아래에서 사용 된 것을보고 싶다면 알려 주시기 바랍니다. 원한다면 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); 
     } 
    } 
} 

나는 코드가 아니라 알고리즘을 찾고 있습니다. 솔루션에서 숫자를 제거하여 퍼즐로 만들려면 어떻게해야합니까? 여기

+0

경우 솔루션의 수가 1보다 큰 경우 추가 및 역 추적 유지 이것은 전혀 도움이 될지 확실하지 않지만 "적절한"스도쿠는 대칭 적이라고 가정합니다. 제공된 (또는 제거 된) 셀은 무작위가 아니며 왼쪽에서 오른쪽, 위에서 아래로 또는 다음과 같은 패턴을 따릅니다. 미러링. 이것이 작업 퍼즐을 생성 할 가능성에 영향을 미치는지 아닌지는 잘 모르겠습니다. – GalacticCowboy

+0

동의합니다. 비대칭 퍼즐에 근본적으로 잘못된 것은 없지만 심미적으로 불쾌합니다. 무작위 추출은 보통 대칭성이 너무 끔찍하지는 않지만 이론적으로 모든 구석을 같은 구석에 만들 수 있음을 발견했습니다. –

답변

2

난 당신이 항상 하나의 가능한 해결책이 있다고도 같은 방식으로 솔루션을 사용할 수, 다음 빼기 숫자의 수를 계산하는 스도쿠 솔버를해야한다는 생각 paper on sudoku generation

입니다.

당신은 그리드에 번호를 추가로 동일한 방법을 적용 할 수있는, 다음 가능한 솔루션의 수를 확인하고 솔루션의 숫자가 나는 '0

+0

나는 실제로 그것도보고 있었지만 세포를 제거한 다음 다른 방법 대신 어려움을 결정하는 방법을 간략하게 설명합니다. 원하는 난이도의 퍼즐이 달성 될 때까지 그런 식으로 반복적으로 수행하면 매우 비효율적 인 알고리즘이 생성됩니다. –