-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

あなたの質問に対する直接的な答えはないので、うまくいけばあなたが軌道に乗ることができるように、ちょっとした暴言を投稿します. あなたが求めているのは、「メソッドからクラスに変更したい」よりもはるかに多くの負荷がかかることです

クラスを設計するには、十分な計画と理解が必要です。上記で貼り付けたコードは、実際に実行しなくても機能していると仮定し、うまくいけば、そこからいくつかの例を引き出すことができます.

他の人がすでに指摘しているように、クラスにはメソッドが含まれているため、メソッドをクラスに変換することはできません。しかし、あなたのコードを見ると、「この単一のクラスを複数にする方法」を尋ねているようです。それは本質的に設計上の問題です。

は、非常に単純なclassレベルで、多くの場合、現実世界のオブジェクトのタイプを表します。クラスのインスタンスは、objectポイント、参照、操作、作成、破棄などを実行できるものです。この場合、クラスは 、Gameまたはより具体的には になりPuzzleます。パズル/ゲームにはルールがあり、プレイヤーがいて、スコアがあり、時間制限があり、ゲームについて表現できるものは何でもあります。これらのそれぞれが、作成する潜在的なクラス/オブジェクトです。

コードでは、多次元配列を使用してゲーム ボードを表します。おそらく、このオブジェクトをクラスに変換したいと思いませんか? これはどのような利点がありますか? これは、ボード上で実行する操作を残りのコードから直接分離する目的に役立ちます。

たとえば、メソッドexistsInColumnexistsInRow、および がありexistsInSubGridます。これらのメソッドは、ゲーム グリッド上で直接動作するものであり、ゲームの実行ロジックの実際の実装から分離する必要があります。このクラスへの分離は、コードを単純化して、保守性、可読性、拡張性、およびその他の機能を向上させるのに役立ちます。あなたが書いたコードが同じように機能しないということは何もありませんが、プログラマーにあなたのコードを手に取ってもらい、彼らが何を変更/改善できるかを確認するように依頼してください。

要点に戻ります... に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 に答える