我刚开始学习如何用java编写代码。我想将代码分解为类,以便每个方法都是一个类。下面的代码从解决方案生成数独游戏。谢谢你的帮助。
通过暴力生成数独谜题
import java.util.Random;
public class SudokuPuzzle
{
public int[][] puzzle = new int[9][9]; // Generated puzzle.
public int[][] solved_puzzle = new int[9][9]; // The solved puzzle.
private int[][] _tmp_grid = new int[9][9]; // For the solver
private Random rand = new Random();
private short solution_count; // Should be 1
/**
* Constructor generates a new puzzle, and its solution
*/
public SudokuPuzzle()
{
generateSolvedPuzzle(0);
generatePuzzle();
}
/**
* Finds a solved puzzle through depth-first search
*/
private boolean generateSolvedPuzzle(int cur_cell)
{
if (cur_cell > 80)
return true;
int col = cur_cell % 9;
int row = cur_cell / 9;
// create a sequence of the integers {1,...,9} of random order
int [] numbers = new int[9];
for (int i=0; i < 9; i++)
numbers[i] = 1+i;
shuffle_array(numbers);
for (int i=0; i < 9; i++)
{
int n = numbers[i]; // for the next number in the array
// if number is acceptable by Sudoku rules
if (!existsInColumn(solved_puzzle, n, col)
&& !existsInRow(solved_puzzle, n, row)
&& !existsInSubGrid(solved_puzzle, n, row, col))
{
// attempt to fill in the next cell with the current cell set to number
solved_puzzle[row][col] = n;
if (generateSolvedPuzzle(cur_cell + 1))
return true;
solved_puzzle[row][col] = 0; // didn't work, reset cell and try the next number in sequence
}
}
return false; // unreachable (since search is exhaustive and a solved puzzle must exist)
}
/**
* Solves the Sudoku puzzle through depth-first, exhaustive search, and store the number of
* solutions in solution_count. Currently, we want to use this only to detect if two solutions
* exist. Hence, we stop the search as soon as two solutions have been found.
*
*
*/
private boolean _solvePuzzle(int cur_cell)
{
if (cur_cell > 80)
{
solution_count++;
if (solution_count > 1) // two solutions detected. notify caller to abort search
return true;
return false;
}
int col = cur_cell % 9;
int row = cur_cell / 9;
if (_tmp_grid[row][col] == 0) // if cell is unfilled
{
for (int n=1; n <= 9; n++) // for each number
{
// if number is acceptable by Sudoku rules
if (!existsInColumn(_tmp_grid, n, col)
&& !existsInRow(_tmp_grid, n, row)
&& !existsInSubGrid(_tmp_grid, n, row, col))
{
// attempt to fill in the next cell with the current cell set to number
_tmp_grid[row][col] = n;
if (_solvePuzzle(cur_cell + 1)) // notified of two solutions being detected
return true; // notify caller to abort search
_tmp_grid[row][col] = 0; // try with other numbers
}
}
}
else
if (_solvePuzzle(cur_cell + 1)) // notified of two solutions being detected
return true; // notify caller to abort search
return false;
}
private void shuffle_array(int array[])
{
// swap the first size elements with other elements from the whole array
for (int i = 0; i < array.length; i++)
{
// find an index j (i<j<=array_length) to swap with the element i
int j = i + rand.nextInt(array.length - i);
int t = array[j];
array[j] = array[i];
array[i] = t;
}
}
/**
* Returns whether a given number exists in a given column.
*
* @param col column to check.
* @param number number to check.
* @return true iff number exists in row.
*/
private boolean existsInColumn(int[][] puzzle, int number, int col)
{
for (int row = 0; row < 9; row++)
if (puzzle[row][col] == number)
return true;
return false;
}
/**
* Returns whether a given number exists in a given row.
*
* @param row row to check.
* @param number number to check.
* @return true iff number exists in row.
*/
private boolean existsInRow(int[][] puzzle, int number, int row)
{
for (int col = 0; col < 9; col++)
if (puzzle[row][col] == number)
return true;
return false;
}
/**
* Returns whether if the 3x3 sub-grid which includes (row, col) contains a
* cell with the given number.
*
* @param row a row in the sub-grid.
* @param col a col in the sub-grid.
* @param number number to check.
* @return true iff sub-grid contains number.
*/
private boolean existsInSubGrid(int[][] puzzle, int number, int row, int col)
{
int sub_grid_start_row = (row / 3)*3;
int sub_grid_start_col = (col / 3)*3;
for (int _row = sub_grid_start_row; _row < sub_grid_start_row + 3; _row++)
for (int _col = sub_grid_start_col; _col < sub_grid_start_col + 3; _col++)
if (puzzle[_row][_col] == number)
return true;
return false;
}
/**
* Generates a Sudoku puzzle from a solved puzzle by setting up to 64 cells to 0.
* (We cannot set more than 64 cells to 0.
*/
private void generatePuzzle()
{
// copy solved_puzzle to puzzle
for (int row = 0; row < 9; row++)
for (int col = 0; col < 9; col++)
puzzle[row][col] = solved_puzzle[row][col];
// create a sequence of the integers {0,...,80} of random order
int [] cell_sequence = new int[81];
for (int i=0; i < 81; i++)
cell_sequence[i] = i;
shuffle_array(cell_sequence);
// attempt to set each cell in the sequence to 0
int count_set_to_zero = 0;
for (int i=0; i < 81 && count_set_to_zero < 64; i++)
{
int cur_cell = cell_sequence[i];
int col = cur_cell % 9;
int row = cur_cell / 9;
int sav = puzzle[row][col];
puzzle[row][col] = 0;
solution_count = 0;
// copy puzzle to _tmp_grid for the solver to work on
for (int r = 0; r < 9; r++)
for (int c = 0; c < 9; c++)
_tmp_grid[r][c] = puzzle[r][c];
if (_solvePuzzle(0)) // Puzzle allows more than 1 solution
puzzle[row][col] = sav; // Revert to original puzzle
else
count_set_to_zero++;
}
}
public void showSolution()
{
for (int row = 0; row < 9; row++)
{
System.out.print(" ");
for (int col = 0; col < 9; col++)
System.out.print(" " + solved_puzzle[row][col]);
System.out.println();
}
}
public void show()
{
for (int row = 0; row < 9; row++)
{
System.out.print(" ");
for (int col = 0; col < 9; col++)
System.out.print(" " + puzzle[row][col]);
System.out.println();
}
}
public static void main(String[] args)
{
SudokuPuzzle sudoku_puzzle = new SudokuPuzzle();
System.out.println("Puzzle:");
sudoku_puzzle.show();
System.out.println();
System.out.println("Solution:");
sudoku_puzzle.showSolution();
}
答案 0 :(得分:1)
由于你的问题没有直接的答案,我只会张贴一些咆哮,希望能让你离开。你要求的是更多的加载,然后“我想将它从一个方法改为一个类”,主要是因为它不是那么简单。
设计课程需要大量的计划和理解。我将假设您上面粘贴的代码在没有真正完成的情况下工作,希望可以从中得出一些示例。
正如其他人已经指出的那样,您无法将类转换为类包含方法。但是看看你的代码,你似乎在问“我怎么能把这个单一的课程变成多个”。它本质上是一个设计问题。
class
,在非常简单的层面上,通常代表一种真实世界的对象。类的实例是object
,您可以指向,引用,操作,创建,销毁或其他方式。在这种情况下,类可以是Game
,也可以更具体地是Puzzle
。拼图/游戏有规则,他们有玩家,他们有分数,他们有时间限制和你可以代表游戏的任何其他东西。这些东西中的每一个都是您可以创建的潜在类/对象。
在您的代码中,您使用多维数组来表示您的游戏板。也许你想将这个对象转换成一个类?这有什么好处?它的作用是将您在板上执行的操作直接与代码的其余部分分开。
例如,您有方法existsInColumn
,existsInRow
和existsInSubGrid
。这些方法是直接在游戏网格上运行的东西,应该与游戏执行逻辑的实际实现分开。这种分离有助于简化代码,以提高其可维护性,可读性,可扩展性和一堆其他能力。没有什么可以说你编写的代码功能不同,但要求任何程序员拿起你的代码,看看他们可以改变/改进什么,他们会拒绝评论“我不会经历所有这些!”< / p>
回到这一点......一旦你有一个属于GameGrid
的{{1}}类或类似的东西,你就可以开始在Puzzle中制作方法,使用网格中的逻辑来解决问题。游戏的一部分将涉及以一种或另一种形式获取用户输入并将其传递给网格。也许只需要SudokuPuzzle
调用就可以获得益智。然后,该方法可以调用上面的存在函数来确定他们的猜测是对还是错。
现在,显然还有很多可以说的。您需要先坐下来决定如何设计您的游戏。会有grid.insertNumber(int x, int y, int number)
个对象吗? Player
?它是使用Score
调用来构建网格或使用像Swing这样的库的图形化游戏的命令行游戏吗?做出这些决定之后,您可以放下一些代码,然后回过头来解决您需要解决的更具体的问题。
答案 1 :(得分:0)
您可以创建一个包含执行命令的类,该命令执行该命令应该执行的操作,但您无法直接将方法转换为类。希望这会有所帮助:)