2
    import processing.core.PApplet;

    public class gl extends PApplet {

    static int neighborCount;
    static int screenRows;
    int tNC; // Temporary Neighbor Count
    int newState;

    int columns = 960;
    int rows = 477;

    int[][] cells = new int[columns][rows];
    int[][] newGen = new int[columns][rows];

    public static void main(String[] args) {
        PApplet.main("gl");
    }

    public void settings() {
        size(1920, 955);
    }

    public void setup() {
        // Set background white and all of cells[][] to 0 or 1
        screenRows = 0;
        background(255);
        for (int j = 0; j < (rows / 2); j++) {
            for (int i = 0; i < (columns / 2); i++) {
                cells[i][j] = (int) random(0, 2);
            }
        }
    }

    public void draw() {
        // If program has finished generating this frame, reset everything and set cells[][] equal to newGen[][]
        if (screenRows > (height / 2)) {
            screenRows = 0;
            System.out.println("End of generation reached");
            background(255);
            cells = newGen.clone();
            for (int i = 0; i < columns; i++) {
                for (int j = 0; j < rows; j++) {
                    newGen[i][j] = 0;
                }
            }
        }
        // Go through every element in cells[][], determine it's value, and display it
        for (int x = 1; x < (width / 2) - 1; x++) {
            for (int y = 1; y < (height / 2) - 1; y++) {

                printCell(x, y);
            }
        }
        screenRows++;

    }

    public void printCell(int x, int y) {
        setCellState(x, y);

        if (newGen[x][y] == 0) {
            stroke(255);
            fill(255);

        } else if (newGen[x][y] == 1) {
            stroke(0);
            fill(0);

        }
        System.out.println(x + ", " + y);
        rect(x, y, 2, 2);
    }

    public void setCellState(int x, int y) {
        tNC = getNeighborCount(x, y);
        neighborCount = 0;
        System.out.println(tNC);

        if (tNC < 2) { // If less than 2 neighbors, cell dead
            newGen[x][y] = 0;

        } else if (tNC > 3) { // If more than 3 neighbors, cell dead
            newGen[x][y] = 0;

        } else if ((tNC == 2 || tNC == 3) && cells[x][y] == 1) { // If 2 or 3 neighbors and cell is alive, do nothing (unnecessary statement but makes visualizing easier)

        } else if (tNC == 3 && cells[x][y] == 0) { // If 3 neighbors and cell is dead, cell is alive
            newGen[x][y] = 1;

        } else if (tNC == 2 && cells[x][y] == 0) { // If 2 neighbors and cel is dead, do nothing (also unnecessary)

        } else {
            System.out.println("Error in setCellState(int, int);"); // In event of none of the conditions being met
        }
        tNC = 0; // Reset variable (probably unnecessary but might as well)
    }

    public int getNeighborCount(int x, int y) {
        // Go through each cell adjacent or diagonal to the cell and add it's value (0 or 1) to neighborCount
        for (int i = -1; i < 2; i++) {
            for (int j = -1; j < 2; j++) {
                neighborCount += cells[i + x][j + y];
            }
        }
        // Subtract the value of the cell being evaluated from neighborCount as that is not a factor in the sum of the neighbors
        neighborCount -= cells[x][y];
        return neighborCount;
    }
}

ペーストビン

今のところ、速度よりも機能性を重視しています。

Eclipse での処理を使用して、コンウェイのライフ ゲームをコーディングしようとしています。上記のコードは、複数の点で機能不全です。

表示された世代は、私が望むよりもはるかに小さくウィンドウに表示されます。各セルを 2x2 ピクセルにし、行数と列数をウィンドウの高さと幅の半分にすることでこれを相殺する努力にもかかわらず、ウィンドウの一部しか占有しません。

また、数秒後に最初の世代が表示された後、ウィンドウで世代が更新されないように見えます。

変数 tNC は、0 から 7 までの任意の数値に等しくなければならないときに、多くの場合 0 に等しいことに気付きました。

4

1 に答える 1

2

3 つの主な問題があります。

問題 1:セルをレンダリングするときに次世代を生成しているように見えますが、これは問題ないかもしれませんが、screenRowsロジック (関数内のifステートメント) で何をしていますか?draw()

私があなたなら、ロジックを 2 つのセクションに分割します。ボードを描画する 1 つの関数と、現在のボードに基づいて新しいボードを返す別の関数を記述します。現在の世代を描いているときに次の世代を計算しようとするのはやめましょう。

また、配列を切り替えるためのロジックが正しいとは思いません。現在の世代を保持する配列と、次世代を保持する配列はどれですか? 本気ですか?

問題 2:ピクセル サイズと配列座標を切り替えているようです。たとえば、配列インデックス座標で各セルを描画していますが、それらを2x2四角形として描画しています。とにかく次のセルでその上に描画するだけなので、これはあまり意味がありません。widthここでも、ロジックを分離します。ウィンドウとheight、配列の位置、および配列の長さに基づいてセルを描画する関数を作成します。

問題 3: print ステートメントがフレームレートを殺しています。print ステートメントは非常に遅いことで知られています。実行しているすべての計算のために、フレームレートはすでにかなり遅いですが、フレームごとに (960*477*2) のものを印刷するとさらに遅くなります。これは実際には論理エラーではありませんが、プログラムが何を行っているかを正確に把握することが難しくなります。

解決策:問題を解決するには、コードをかなりリファクタリングすることをお勧めします。もし私があなたなら、新しいプログラムからやり直すでしょう。それで:

ステップ 1:描画ロジックを次の世代を計算するためのロジックから分離します。2 つの関数を作成します。1 つは描画用で、もう 1 つは現在の配列に基づいて新しい配列を返します。

ステップ 2:描画コードでは、配列インデックスとピクセル位置を必ず分離してください。セルの位置を取得し、ウィンドウ サイズと配列サイズに基づいて四角形を描画する別の関数を作成することもできます。

PS:この人と同じクラスですか?Daniel Shiffman のコードも使用していますか?

于 2016-07-13T13:21:30.993 に答える