Visual Studio 2008을 사용하여 C# 응용 프로그램을 만들려고합니다. Sudoku 퍼즐을 해결합니다. 내 문제는 응용 프로그램에서 새 퍼즐을 생성하는 코드를 파악할 수 없다는 것입니다.새로운 스도쿠 격자 생성 C#
- 시작의 요구 수준에 따라
- 는
- 빈 퍼즐의 모든 세포 세포의 적절한 수의 번호를 생성 빈 퍼즐로 다음과 같이 내가 구현하기 위해 노력하고있어 생각은 어려움
- 퍼즐을 해결하십시오
- 퍼즐의 점수가 필요한 난이도의 허용 범위 안에 있습니까?
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 개월 동안 아무런 해결책도 없었다. (이 문제에 대한 나의 무능함에 대한 많은 좌절감) ... 나는 여기에서 얻을 수있는 어떤 종류의 도움에 감사하곤한다.
Sudokus를 생성하는 데 관한 많은 문헌이 없습니까? – Patashu
그래, 그게 내가이 응용 프로그램으로 내가해야 할 다른 문제를 해결하는 방법이다. 그러나 이것은 내가 가지고 있었고 아직 2 개월 정도 후에 (많은 포럼과 책을 확인한 후) 그것을 고정하지 않은 첫 번째 문제이다. . 문제는, 내가 다른 방법을 사용할 수 없다,이 하나를 고칠 필요가 ... : ( – Gab
[이 질문에 대한 답변 (http://stackoverflow.com/questions/9295537/sudoku-generator-algorithm) 도움이 내가 비슷한 프로그램을 만들었을 때 많이 꺼내. 스도쿠 생성 알고리즘에 대해 많이 읽으면 좋을 것 같다.보다 복잡한 문제가 생긴다. – Wilson