2013-06-04 2 views
0

Visual Studio 2008을 사용하여 C# 응용 프로그램을 만들려고합니다. Sudoku 퍼즐을 해결합니다. 내 문제는 응용 프로그램에서 새 퍼즐을 생성하는 코드를 파악할 수 없다는 것입니다.새로운 스도쿠 격자 생성 C#

  1. 시작의 요구 수준에 따라
  2. 빈 퍼즐의 모든 세포 세포의 적절한 수의 번호를 생성 빈 퍼즐로 다음과 같이 내가 구현하기 위해 노력하고있어 생각은 어려움
  3. 퍼즐을 해결하십시오
  4. 퍼즐의 점수가 필요한 난이도의 허용 범위 안에 있습니까?

6a. 아니요 -> 퍼즐 재생성 (1로 가십시오)

6b.

//-------------------------------------------------- 
    // Starting a new game menu button 
    //-------------------------------------------------- 
    public void NewToolStripMenuItem_Click(System.Object sender, System.EventArgs e) 
    { 

     if (GameStarted) // this cheking part seems to work (message is displayed and game gets saved if selected) 
     { 
      MsgBoxResult response = (MsgBoxResult)(MessageBox.Show("Doriți salvarea jocului curent?", "Salvează jocul curent...", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question)); 

      if (response == MsgBoxResult.Yes) 
      { 
       SaveGameToDisk(false); 
      } 
      else if (response == MsgBoxResult.Cancel) 
      { 
       return; 
      } 
     } 

     // Changing the cursor while generating 
     System.Windows.Forms.Cursor.Current = Cursors.WaitCursor; 
     ToolStripStatusLabel1.Text = "Se generează un puzzle nou..."; 

     // Creating an instance for the SudokuPuzzle class 
     SudokuPuzzle sp = new SudokuPuzzle(); 
     string puzzle = string.Empty; 

     // Determining the difficulty level selected (from menu objects) 
     if (EasyToolStripMenuItem.Checked) 
     { 
      puzzle = sp.GetPuzzle(1); 
     } 
     else if (MediumToolStripMenuItem.Checked) 
     { 
      puzzle = sp.GetPuzzle(2); 
     } 
     else if (DifficultToolStripMenuItem.Checked) 
     { 
      puzzle = sp.GetPuzzle(3); 
     } 
     else if (ExtremelyDifficultToolStripMenuItem.Checked) 
     { 
      puzzle = sp.GetPuzzle(4); 
     } 
     else if (EmptyPuzzleToolStripMenuItem.Checked) 
     { 
      puzzle = sp.GetPuzzle(5); 
     } 

     // Changing to default cursor 
     System.Windows.Forms.Cursor.Current = Cursors.Default; 

     StartNewGame(); 

     // Initialisation of the grid 
     int counter = 0; 
     for (int row = 1; row <= 9; row++) 
     { 
      for (int col = 1; col <= 9; col++) 
      { 
       if (puzzle[counter].ToString() != "0") 
       { 
        SetCell(col, row, System.Convert.ToInt32(puzzle[counter].ToString()), (short)0); 
       } 
       counter++; 
      } 
     } 
    } 

소위 다음 기능에 대한 코드, GetPuzzle (1) :

//-------------------------------------------------- 
    // Obtaining a new puzzle (of the required level) 
    //-------------------------------------------------- 
    public string GetPuzzle(int level) 
    { 
     int score = 0; 
     string result; 
     do 
     { 
      result = GenerateNewPuzzle(level, ref score); 
      if (result != string.Empty) 
      { 
       // Verify if the generated puzzle is of the selected dificulty 
       switch (level) 
       { 
        // The average for dificutly 1 
        case 1: 
         if (score >= 42 && score <= 46) 
         { 
          goto endOfDoLoop; 
         } 
         break; 
        // The average for dificutly 2 
        case 2: 
         if (score >= 49 && score <= 53) 
         { 
          goto endOfDoLoop; 
         } 
         break; 
        // The average for dificutly 3         case 3: 
         if (score >= 56 && score <= 60) 
         { 
          goto endOfDoLoop; 
         } 
         break; 
        // The average for dificutly 4 
        case 4: 
         if (score >= 112 && score <= 116) 
         { 
          goto endOfDoLoop; 
         } 
         break; 
       } 
      } 
     } while (!false); // loops ending 
    endOfDoLoop: 
     return result; 
    } 
- YES 경우> 퍼즐이 생성

"새 게임"버튼

사용 된 코드 (를 표시)

//-------------------------------------------------- 
    // Generating a new puzzle 
    //-------------------------------------------------- 
    public string GenerateNewPuzzle(int level, ref int score) 
    { 
     int c; 
     int r; 
     string str; 
     int numberofemptycells = 0; 

     // Initializing the entire grid 
     for (r = 1; r <= 9; r++) 
     { 
      for (c = 1; c <= 9; c++) 
      { 
       actual[c, r] = 0; 
       possible[c, r] = string.Empty; 
      } 
     } 

     // Empty the stacks used 
     ActualStack.Clear(); 
     PossibleStack.Clear(); 

     // Complete by solving an empty grid 
     try 
     { 
      // First used logical methods to solve the grid 
      if (!SolvePuzzle()) 
      { 
       // Then use brute force 
       SolvePuzzleByBruteForce(); 
      } 
     } 
     catch (Exception) 
     { 
      // If there’s any error, return emptry string 
      return string.Empty; 
     } 

     // Create a copy for the actual array 
     actual_backup = (int[,])(actual.Clone()); 

     // Set the number of empty cells based on the difficulty level 
     switch (level) 
     { 
      // For difficulty level 1 
      case 1: 
       numberofemptycells = RandomNumber(40, 45); 
       break; 
      // For difficulty level 2 
      case 2: 
       numberofemptycells = RandomNumber(46, 49); 
       break; 
      // For difficulty level 3 
      case 3: 
       numberofemptycells = RandomNumber(50, 53); 
       break; 
      // For difficulty level 4 
      case 4: 
       numberofemptycells = RandomNumber(54, 58); 
       break; 
     } 

     // Empty the stacks used by brute force 
     ActualStack.Clear(); 
     PossibleStack.Clear(); 
     BruteForceStop = false; 

     // Create empty cells 
     CreateEmptyCells(numberofemptycells); 

     // Convert the values from the actual array to string 
     str = string.Empty; 
     for (r = 1; r <= 9; r++) 
     { 
      for (c = 1; c <= 9; c++) 
      { 
       str += (string)(actual[c, r].ToString()); 
      } 
     } 

     // Verrify that the puzzle has only one solution 
     int tries = 0; 
     do 
     { 
      totalscore = 0; 
      try 
      { 
       if (!SolvePuzzle()) 
       { 
        // If puzzle is not solved and difficulty level is 1-3 
        if (level < 4) 
        { 
         // Choose another combination of cells to empty 
         VacateAnotherPairOfCells(ref str); 
         tries++; 
        } 
        else 
        { 
         // Puzzles of difficulty 4 don’t guranty a single solution 
         SolvePuzzleByBruteForce(); 
         goto endOfDoLoop; 
        } 
       } 
       else 
       { 
        // The puzzle has 1 solution 
        goto endOfDoLoop; 
       } 
      } 
      catch (Exception) 
      { 
       return string.Empty; 
      } 

      // If too many tries are executed, exit at 50 
      if (tries > 50) 
      { 
       return string.Empty; 
      } 
     } 
     while (true); 
    endOfDoLoop: 

     // Return the obtained score and the puzzle as a string 
     score = totalscore; 
     return str; 
    } 

그리고 마지막으로 유용한 (내가 생각하는) 기능, VacateAnotherPairOfCells() : 사용

다음 기능은 GenerateNewPuzzle()이다 :

//-------------------------------------------------- 
    // Empty another pair of cells 
    //-------------------------------------------------- 
    private void VacateAnotherPairOfCells(ref string str) 
    { 
     int c; 
     int r; 

     // Search for a pair of cells to empty (the empty cells should be simetrical from the center of the grid) 
     do 
     { 
      c = RandomNumber(1, 9); 
      r = RandomNumber(1, 9); 
     } while (!(int.Parse(str[(c - 1) + (r - 1) * 9].ToString()) == 0)); 

     // Restore the value of the cell from the backup array 
     str = str.Remove(System.Convert.ToInt32((c - 1) + (r - 1) * 9), 1); 
     str = str.Insert(System.Convert.ToInt32((c - 1) + (r - 1) * 9), (string)(actual_backup[c, r].ToString())); 

     // Restore the value of the simetrical cell 
     str = str.Remove(System.Convert.ToInt32((10 - c - 1) + (10 - r - 1) * 9), 1); 
     str = str.Insert(System.Convert.ToInt32((10 - c - 1) + (10 - r - 1) * 9), (string)(actual_backup[10 - c, 10 - r].ToString())); 

     // Search for another pair of cells that can be emptyed 
     do 
     { 
      c = RandomNumber(1, 9); 
      r = RandomNumber(1, 9); 
     } while (!(int.Parse(str[(c - 1) + (r - 1) * 9].ToString()) != 0)); 

     // Delete the cell from the string 
     str = str.Remove(System.Convert.ToInt32((c - 1) + (r - 1) * 9), 1); 
     str = str.Insert(System.Convert.ToInt32((c - 1) + (r - 1) * 9), "0"); 

     // Delete the simetrical cell from the string 
     str = str.Remove(System.Convert.ToInt32((10 - c - 1) + (10 - r - 1) * 9), 1); 
     str = str.Insert(System.Convert.ToInt32((10 - c - 1) + (10 - r - 1) * 9), "0"); 

     // Reinitilisation of the grid 
     short counter = (short)0; 
     for (int row = 1; row <= 9; row++) 
     { 
      for (int col = 1; col <= 9; col++) 
      { 
       if (System.Convert.ToInt32(str[counter].ToString()) != 0) 
       { 
        actual[col, row] = System.Convert.ToInt32(str[counter].ToString()); 
        possible[col, row] = (string)(str[counter].ToString()); 
       } 
       else 
       { 
        actual[col, row] = 0; 
        possible[col, row] = string.Empty; 
       } 
       counter++; 
      } 
     } 
    } 
} } 

나머지 기능과 코드는 다른 모든 기능이 작동하는 데 필자가 필요하다고 생각하지 않았습니다. 빈 퍼즐이나 부분 퍼즐을 가져 오는 경우 응용 프로그램은 자동으로 생성 된 격자를 해결하는 데 사용 된 것과 동일한 방법을 사용하여 자동으로 해결할 수 있습니다. 그러나 메뉴에서 "새 퍼즐"을 클릭하면 응용 프로그램이 오류없이 멈 춥니 다 (프로세스를 종료해야합니다).

아마도 이것은 유효한 보드를 생성하는 가장 쉬운 방법은 아니며 코드 길이에 대해 사과하지만이 문제를 수정하고 사용해야합니다. 나는이 문제를 여러 번 고쳐 봤지만 지난 2 개월 동안 아무런 해결책도 없었다. (이 문제에 대한 나의 무능함에 대한 많은 좌절감) ... 나는 여기에서 얻을 수있는 어떤 종류의 도움에 감사하곤한다.

+1

Sudokus를 생성하는 데 관한 많은 문헌이 없습니까? – Patashu

+0

그래, 그게 내가이 응용 프로그램으로 내가해야 할 다른 문제를 해결하는 방법이다. 그러나 이것은 내가 가지고 있었고 아직 2 개월 정도 후에 (많은 포럼과 책을 확인한 후) 그것을 고정하지 않은 첫 번째 문제이다. . 문제는, 내가 다른 방법을 사용할 수 없다,이 하나를 고칠 필요가 ... : ( – Gab

+0

[이 질문에 대한 답변 (http://stackoverflow.com/questions/9295537/sudoku-generator-algorithm) 도움이 내가 비슷한 프로그램을 만들었을 때 많이 꺼내. 스도쿠 생성 알고리즘에 대해 많이 읽으면 좋을 것 같다.보다 복잡한 문제가 생긴다. – Wilson

답변

0

문제가 해결되었습니다.

실제로 위의 코드에는 아무런 문제가 없지만 "SolvePuzzleByBruteForce()"함수에서 코딩 실수가 있었다는 사실에 문제가있었습니다. 문제의 함수는 여기에 게시되지 않았으므로 위의 코드는 수정이 필요하지 않고 올바르게 작동합니다.

누군가가 원한다면 "SolvePuzzleByBruteForce()"를 넣을 수 있습니다.하지만 아무 것도 특별하지 않고 인터넷에 그러한 함수가 가득하다는 사실을 고려할 때 관련이 없다는 것을 알았습니다.

댓글에 회신하려면 : @HighCore goto의 사용은 내 질문과 관련이 없습니다.

@ 마크 Lakata 질문은 모호하지 않았다. 나는 문제와 그것이해야 할 일, 코드를 언급했다. 그리고 학교에 다니지 않아서 숙제 문제가 아니었고 숙제를하기 위해 2 달을 보지도 않았습니다.

@ 윌슨 귀하의 의견에 감사드립니다, 그것은 아래로 추적하고 나쁜 기능의 문제를 파악하는 데 도움이.