-5

我刚开始学习如何用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();
}
4

2 回答 2

1

由于您的问题没有直接的答案,因此我将发表一些咆哮,希望可以让您摆脱困境。您要求的内容比“我想将其从方法更改为类”要加载得多,主要是因为它不是那么简单

设计一门课程需要大量的计划和理解。我将假设您在上面粘贴的代码没有真正通过它就可以工作,并希望可以从中得出一些示例。

正如其他人已经指出的那样,您不能将方法转换为类,因为类包含方法。但是看看你的代码,你似乎在问“我怎样才能把这个单一的类变成多个”。它本质上是一个设计问题。

A class,在一个非常简单的层面上,通常代表一种现实世界的对象。类的实例是一个object,您可以指向、引用、对其进行操作、创建、销毁或其他方式的东西。在这种情况下,一个类将是 aGame或者更具体地说是 a Puzzle。拼图/游戏有规则,有玩家,有分数,有时间限制,以及你可以代表游戏的任何其他内容。这些东西中的每一个都是您要创建的潜在类/对象。

在您的代码中,您使用多维数组来表示您的游戏板。也许您想将此对象转换为一个类?这有什么好处?它的目的是将您直接在板上执行的操作与其余代码分开。

例如,您有方法existsInColumnexistsInRowexistsInSubGrid。这些方法是直接在游戏网格上操作的东西,应该与游戏执行逻辑的实际实现分开。这种对类的分离有助于简化代码,以提高其可维护性、可读性、可扩展性和许多其他能力。没有什么说你写的代码功能不一样,但是请任何程序员拿起你的代码,看看他们可以改变/改进什么,他们会转身说“我不会经历这一切!”

回到正题……一旦你有了属于的类GameGrid或类似的东西,SudokuPuzzle你就可以开始在拼图中使用网格中的逻辑来制作方法来解决问题。您的游戏的一部分将涉及以一种或另一种形式获取用户输入并将其传递到网格。也许grid.insertNumber(int x, int y, int number)拼图只需要一个电话。然后,该方法可以调用上述存在的函数来确定他们的猜测是对还是错。

现在,显然还有很多可以说的。你需要先坐下来决定如何设计你的游戏。会有Player对象吗?Score? 它是使用调用来构建网格的命令行游戏System.out.print()还是使用像 Swing 这样的库的图形游戏?一旦做出这些决定,您就可以放下一些代码,然后返回需要解决的更具体的问题。

祝你好运!

于 2012-12-12T18:15:06.063 回答
0

您可以让一个类持有一个执行命令,该命令执行该命令应该执行的操作,但您不能直接将方法转换为类。希望这可以帮助 :)

于 2012-12-12T18:01:26.613 回答