0

C++ で柔軟な菱形の地形ジェネレーターを作成しています。私の地形の高さの値のタイルのグリッドは、int の巨大な配列として定義されています。これで、このグリッドを別の関数として操作するダイヤモンド スクエア アルゴリズム全体ができましたstdroutine。ユーザーがそのサイズを定義できるようにする必要があるため、グリッドをグローバル変数として宣言することはできません (理由の範囲内で、サイズ チェックはまだ実装されていません)。あまり手間をかけずに連続して複数回呼び出すことができるようにしたいので、 の内容を単に貼り付けたくはありません (最終的には、一部のプリセット ルーチンを実行するために必要になりますstdroutine) 。mainそのため、配列へのポインターを指定しようとしましstdroutineた。これを指定すると、配列が実際にどこにあるかを把握できることを期待しています。stdroutine実際に呼び出す別の関数 、meanこれもグリッドが機能する必要があります。これが私のコードです(ひどく間違っていますが、まあ、よくわかりません):

main.cpp:

#include <stdio.h>
#include <stdlib.h>
#include "mt.h"
#include "diamondsquare.h"

int main () {
    unsigned  long seed = 0, x = 0, y = 0, initial = 0, range = 0;
    int smooth = 0, fail = 1, index1 = 0, index2 = 0;
    char flagchar1 = 'n';
    printf("Welcome to my diamond-square generator! This isn't full-feature yet, so I'm just gonna have you input the variables one by one. ");
    do {
        printf("Please input the seed (this is a positive integer):\n");
        fail = scanf("%lu", &seed);
        while (fail == 0) {
            printf("Try again, smartass.\n");
            fail = scanf("%lu", &seed);
        }
        fail = 1;
        printf("Now input the x, or horizontal, size of your grid:\n");
        fail = scanf("%lu", &x);
        while (fail == 0) {
            printf("An integer. Not a string. An integer. You can do that, can't you?\n");
            fail = scanf("%lu", &x);
        }
        fail = 1;
        printf("Now input the y, or vertical, size of your grid:\n");
        fail = scanf("%lu", &y);
        while (fail == 0) {
            printf("What was that supposed to be? An integer, please.\n");
            fail = scanf("%lu", &y);
        }
        fail = 1;
        printf("Now input about how high you'd like the grid to be (this goes from a scale of 1 to 256):\n");
        fail = scanf("%lu", &initial);
        while (initial == 0 || initial > 256 || fail == 0) {
            printf("ahahahahaha how HIGH do you have to be just to HAVE that hieght........\n");
            fail = scanf("%lu", &initial);
        }
        fail = 1;
        printf("Now input the range of the heights on your grid (this must be equal to or less than 256):\n");
        scanf("%lu", &range);
        while (range >= 256 || fail == 0) {
            printf("What did I say about being equal to or less than 256? Give me something reasonable to work with here.\n");
            fail = scanf("%lu", &range);
        }
        fail = 1;
        printf("Just one more variable to go! Now, I need you to input the smoothness of your grid. Smaller numbers make spikier grids. You can make this negative, but beware!\n");
        fail = scanf("%d", &smooth);
        while (fail == 0) {
            printf("That... was not a number.\n");
            fail = scanf("%d", &smooth);
        }
        fail = 1;
        printf("\nOkay. Are these the values you want? Type Y/n.\n   Seed:       %lu\n   Width:      %lu\n   Length:     %lu\n   Height:     %lu\n   Range:      %lu\n   Smoothness: %d\n", seed, x, y, initial, range, smooth);
        // Ignore remaining characters on current line.
        int ch;
        while( (ch = getchar()) != EOF && ch != '\n')
            ;
        // fetch first character on next line
        flagchar1 = getchar();
    } while (flagchar1 != 'y' && flagchar1 != 'Y' && flagchar1 != '\n');
    printf("Welp, time to get started!\n\n");
    printf("Twisting primes...\n");                  // Initializes the Mersenne twister.
    mt_init(seed);
    printf("Scrawling preliminary etchings...\n");   // Presets as many values on the grid as is called for.
    printf("Creating depth matrix...\n");            // Declares grid.
    int grid [x] [y];
    printf("Nullifying grid constants...\n");        // Sets all values in grid to 0.
    for (index1 = 0; index1 < x; index1++) {
        for (index2 = 0; index2 < y; index2++) {
            grid [index1] [index2] = 0;
        }
    }
    printf("Filling rhombus circumcenters...\n");     // Actually runs the diamond-square algorithm.
    stdroutine(initial, range, smooth, x, y, &grid);
    printf("Inserting strategic aberrations...");     // Runs any postgenerational script a tag needs (currently only needed for "glacier" tag).
    printf("Applying planetary fabrics...\n");        // Sets the materials of all tiles6.
    printf("Scraping irregularities into suface..."); // Simulates erosion.
    printf("Discharging liquids...\n");               // Inserts liquids.
    printf("Populating biosphere...\n");              // Inserts plants, animals.
    printf("Constructing civilized edifices...\n");   // Inserts structures.
}

ダイヤモンド-square.h:

int mean (bool sqd, unsigned long mx, unsigned long my, unsigned long x, unsigned long y, int** grid [x] [y]) {
    int x1 = mx, x2 = mx, x3 = mx, x4 = mx, y1 = my, y2 = my, y3 = my, y4 = my;
    int avg;
    if (sqd == false) {
        do {
            y1++;
        } while (**grid [x1] [y1]);
        do {
            x2++;
        } while (**grid [x2] [y2]);
        do {
            y3--;
        } while (**grid [x3] [y3]);
        do {
            x4--;
        } while (**grid [x4] [y4]);
        avg = (**grid [x1] [y1] + **grid [x2] [y2] + **grid [x3] [y3] + **grid [x4] [y4]) / 4;
        return avg;
    }
    else if (sqd == true) {
        do {
            x1--;
            y1++;
        } while (**grid [x1] [y1]);
        do {
            x2++;
            y2++;
        } while (**grid [x2] [y2]);
        do {
            x3++;
            y3--;
        } while (**grid [x3] [y3]);
        do {
            x4--;
            y4--;
        } while (**grid [x4] [y4]);
        avg = (**grid [x1] [y1] + **grid [x2] [y2] + **grid [x3] [y3] + **grid [x4] [y4]) / 4;
        return avg;
    }
    else
        return 0;
}

void stdroutine (unsigned long i, unsigned long r, int h, unsigned long x, unsigned long y, int* grid [x] [y]) { // LADIES AND GENTLEMEN... THE DIAMOND-SQUARE ALGORITHM.
    *grid [0] [0] = i + ((mt_random() % r) - (r/2)); // Set
    *grid [x] [0] = i + ((mt_random() % r) - (r/2)); // the
    *grid [0] [y] = i + ((mt_random() % r) - (r/2)); // four
    *grid [x] [y] = i + ((mt_random() % r) - (r/2)); // corners.
    int sect = 2;                                    // This is the subdivision and iteration count of our diamond-square algorithm.
    while (x / sect != x || y / sect != y) {
        for (int n = 1; n < sect; n++) // The square algorithm: it finds a point in the middle of every square, and sets it to the mean of the four corners of the square, plus a little offset. In theory, anyway.
            for (int m = 1; m < sect; m++)
                if (*grid [x * (m/sect)] [y * (n/sect)] == 0) // If it's already been given a value, just leave it.
                    *grid [x * (m/sect)] [y * (n/sect)] = mean(true, (x * (m/sect)), (y * (n/sect)), x, y) + ((mt_random() % (r - h)) - ((r - h)/2)); // Randomize the location's height.
        for (int n = 0; n == sect; n++)     // The diamond algorithm: it finds a point in the middle of every diamond, and it sets it to the mean of the four corners of the diamond, plus a little offset. In theory, anyway.
            for (int m = 0; m == sect; m++) {
                if (n % 2 == 0)
                    if (m % 2 == 1)
                        if (*grid [x * (m/sect)] [y * (n/sect)] == 0) // Same deal here. We don't want to overwrite existing stuff.
                            *grid [x * (m/sect)] [y * (n/sect)] = mean (false, (x * (m/sect)), y * (n/sect), x, y, &grid) + ((mt_random() % (r - h)) - ((r - h)/2)); // Randomize the location's height.
                if (n % 2 == 1)
                    if (m % 2 == 0)
                        if (*grid [x * (m/sect)] [y * (n/sect)] == 0) // Again, we only want to change positions that haven't been changed yet.
                    *grid [x * (m/sect)] [y * (n/sect)] = mean (false, (x * (m/sect)), (y * (n/sect)), x, y, &grid) + ((mt_random() % (r - h)) - ((r - h)/2)); // Randomize the location's height.
            }
        sect++; // Increment sect for the next iteration. I am perfectly aware that this could have been done as a for loop.
    }
}

(mt.h には、メルセンヌ ツイスター PRNG をそれぞれ初期化して実行するmt_initとの 2 つのルーチンが含まれているだけです。)mt_random

グリッドへのポインターを、それらを呼び出すすべての関数とうまく連携させるにはどうすればよいですか? 現時点では、Xcode 4.3 から 4 つのエラー、diamond-square.h に 3 つ、「'mean' の呼び出しに一致する関数がありません」、main.cpp に 1 つ、「'stdroutine' の呼び出しに一致する関数がありません」というエラーが発生します。 .

編集:うーん、思ったよりも簡単です。まだ問題がありますが、コメントを参照してください。関連するコード (main.cpp は同じですが、への呼び出しで grid の前のアンパサンドを省略しましたstdroutine):

int mean (bool sqd, unsigned long mx, unsigned long my, unsigned long x, unsigned long y, const int grid [] [y]) {
    int x1 = mx, x2 = mx, x3 = mx, x4 = mx, y1 = my, y2 = my, y3 = my, y4 = my;
    int avg;
    if (sqd) {
        do {
            x1--;
            y1++;
        } while (grid [x1] [y1]);
        do {
            x2++;
            y2++;
        } while (grid [x2] [y2]);
        do {
            x3++;
            y3--;
        } while (grid [x3] [y3]);
        do {
            x4--;
            y4--;
        } while (grid [x4] [y4]);
        avg = (grid [x1] [y1] + grid [x2] [y2] + grid [x3] [y3] + grid [x4] [y4]) / 4;
        return avg;
    }
    else {
        do {
            y1++;
        } while (grid [x1] [y1]);
        do {
            x2++;
        } while (grid [x2] [y2]);
        do {
            y3--;
        } while (grid [x3] [y3]);
        do {
            x4--;
        } while (grid [x4] [y4]);
        avg = (grid [x1] [y1] + grid [x2] [y2] + grid [x3] [y3] + grid [x4] [y4]) / 4;
        return avg;
    }
}

void stdroutine (unsigned long i, unsigned long r, int h, unsigned long x, unsigned long y, int grid [] [y]) { // LADIES AND GENTLEMEN... THE DIAMOND-SQUARE ALGORITHM.
    grid [0] [0] = i + ((mt_random() % r) - (r/2));     // Set
    grid [x-1] [0] = i + ((mt_random() % r) - (r/2));   // the
    grid [0] [y-1] = i + ((mt_random() % r) - (r/2));   // four
    grid [x-1] [y-1] = i + ((mt_random() % r) - (r/2)); // corners.
    int sect = 2;                                        // This is the subdivision and iteration count of our diamond-square algorithm.
    while (x / sect != x || y / sect != y) {
        for (int n = 1; n < sect; n++) // The square algorithm: it finds a point in the middle of every square, and sets it to the mean of the four corners of the square, plus a little offset. In theory, anyway.
            for (int m = 1; m < sect; m++)
                if (grid [x * (m/sect)] [y * (n/sect)] == 0) // If it's already been given a value, just leave it.
                    grid [x * (m/sect)] [y * (n/sect)] = mean(true, (x * (m/sect)), (y * (n/sect)), x, y, grid) + ((mt_random() % (r - h)) - ((r - h)/2)); // Randomize the location's height.
        for (int n = 0; n == sect; n++)     // The diamond algorithm: it finds a point in the middle of every diamond, and it sets it to the mean of the four corners of the diamond, plus a little offset. In theory, anyway.
            for (int m = 0; m == sect; m++) {
                if (n % 2 == 0)
                    if (m % 2 == 1)
                        if (grid [x * (m/sect)] [y * (n/sect)] == 0) // Same deal here. We don't want to overwrite existing stuff.
                            grid [x * (m/sect)] [y * (n/sect)] = mean (false, (x * (m/sect)), y * (n/sect), x, y, grid) + ((mt_random() % (r - h)) - ((r - h)/2)); // Randomize the location's height.
                if (n % 2 == 1)
                    if (m % 2 == 0)
                        if (grid [x * (m/sect)] [y * (n/sect)] == 0) // Again, we only want to change positions that haven't been changed yet.
                    grid [x * (m/sect)] [y * (n/sect)] = mean (false, (x * (m/sect)), (y * (n/sect)), x, y, grid) + ((mt_random() % (r - h)) - ((r - h)/2)); // Randomize the location's height.
            }
        sect++; // Increment sect for the next iteration. I am perfectly aware that this could have been done as a for loop.
    }
    return;
}
4

1 に答える 1

0

もう少し考えて実験してみました。int grid [] [y]y がコンパイル時に既知の定数でない限り、パラメーターを宣言することは合法的な C または C++ ではないと思います。パラメータを asint grid[]にしてから、それを としてインデックス付けすることができますgrid [y * ncolumns +x]。としてメソッドにポインターを渡す必要があります&grid[0][0]

これは、配列の次元をテンプレート パラメーターとして受け取るメソッド テンプレートを使用して行うこともできます。

于 2012-03-08T17:30:07.403 に答える