当结构体包含 char ** 变量时如何撤消堆栈?

发布于 2025-01-09 17:34:20 字数 3583 浏览 0 评论 0原文

下面的代码有点像糖果粉碎游戏,你在一个簇中弹出相似的字母,然后它们就会消失,你就得分。在主要部分,我尝试提前播放它,然后撤消它,并且它有效,因为分数设法撤消(从 0 到某个分数,然后再次回到 0)。但是我就是不明白为什么游戏板不更新?

    typedef struct {
        int rs;
        int cs;
        char **board;
        int score;
    } Instance;
    
with random letters (a, b ,c or d)
    extern Game *create(int nrows, int ncols) {
        if (nrows > MAX_ROWS || ncols > MAX_COLS) {
            return NULL;
        }
        Game *b;
        b->top = 0;
        b->stack[b->top].rs = nrows;
        b->stack[b->top].cs = ncols;
        b->stack[b->top].board = malloc(sizeof(char *) * nrows);
        for (int row = 0; row < nrows; row++) {
            b->stack[b->top].board[row] = malloc(sizeof(char) * ncols);
        }
        srand(time(0));
        for (int row = 0; row < nrows; row++) {
            for (int column = 0; column < ncols; column++) {
                int random = rand() % 4;
                if (random == 0) {
                    b->stack[b->top].board[row][column] = A;
                } else if (random == 1) {
                    b->stack[b->top].board[row][column] = B;
                } else if (random == 2) {
                    b->stack[b->top].board[row][column] = C;
                } else {
                    b->stack[b->top].board[row][column] = D;
                }
            }
        }
        return b;
    }
    
    // Display the current matrix
    extern void display(Game *b) {
        /** Prints top border **/
        printf("   +-");
        for (int top = 0; top < b->stack[b->top].cs; top++) {
            printf("--");
        }
        printf("+\n");
        /** Prints the board **/
        for (int row = 0; row < b->stack[b->top].rs; row++) {
            if (row < 10) {
                printf("0%d | ", row);
            } else {
                printf("%d | ", row);
            }
            for (int column = 0; column < b->stack[b->top].cs; column++) {
                printf("%c ", b->stack[b->top].board[row][column]);
            }
            printf("|\n");
        }
        /** Prints bottom border **/
        printf("   +-");
        for (int bot = 0; bot < b->stack[b->top].cs; bot++) {
            printf("--");
        }
        printf("+\n");
        /** Prints vertical column indices **/
        printf("     ");
        for (int tens = 0; tens < b->stack[b->top].cs; tens++) {
            printf("%d ", tens/10);
        }
        printf("\n");
        printf("     ");
        int count = 0;
        for (int ones = 0; ones < b->stack[b->top].cs; ones++) {
            if (count > 9) {
                count = 0;
            }
            printf("%d ", count);
            count++;
        }
    }
    
    extern int select(Game *b, int r, int c) {
        char colour = b->stack[b->top].board[r][c];
        int n = recursive_helper(b, r, c);
        if (n == 1) {
            b->stack[b->top].board[r][c] = colour;
            return 0;
        }
        b->stack[b->top].score += n*(n-1);
        return n;
    }
 
    
    int main() {
        Game *b = create(5, 10);
    
        display(b);
        printf("\n");
        printf("%d", bp_score(b));
        printf("\n");
    
        select(b, 2, 2);
        display(b);
        printf("\n");
        printf("%d", bp_score(b));
        printf("\n");
    
        b->top--;
        display(b);
        printf("\n");
        printf("%d", bp_score(b));
        printf("\n");
    }

This code below is something like a candy crush game, where you pop similar letters in a cluster, then they'll disappear and you score. On main, I tried to play it one step ahead and then undo it, and it works since the score managed to undo (from 0 to some score then back to 0 again). However, I just can't figure out why the game board isn't updated?

    typedef struct {
        int rs;
        int cs;
        char **board;
        int score;
    } Instance;
    
with random letters (a, b ,c or d)
    extern Game *create(int nrows, int ncols) {
        if (nrows > MAX_ROWS || ncols > MAX_COLS) {
            return NULL;
        }
        Game *b;
        b->top = 0;
        b->stack[b->top].rs = nrows;
        b->stack[b->top].cs = ncols;
        b->stack[b->top].board = malloc(sizeof(char *) * nrows);
        for (int row = 0; row < nrows; row++) {
            b->stack[b->top].board[row] = malloc(sizeof(char) * ncols);
        }
        srand(time(0));
        for (int row = 0; row < nrows; row++) {
            for (int column = 0; column < ncols; column++) {
                int random = rand() % 4;
                if (random == 0) {
                    b->stack[b->top].board[row][column] = A;
                } else if (random == 1) {
                    b->stack[b->top].board[row][column] = B;
                } else if (random == 2) {
                    b->stack[b->top].board[row][column] = C;
                } else {
                    b->stack[b->top].board[row][column] = D;
                }
            }
        }
        return b;
    }
    
    // Display the current matrix
    extern void display(Game *b) {
        /** Prints top border **/
        printf("   +-");
        for (int top = 0; top < b->stack[b->top].cs; top++) {
            printf("--");
        }
        printf("+\n");
        /** Prints the board **/
        for (int row = 0; row < b->stack[b->top].rs; row++) {
            if (row < 10) {
                printf("0%d | ", row);
            } else {
                printf("%d | ", row);
            }
            for (int column = 0; column < b->stack[b->top].cs; column++) {
                printf("%c ", b->stack[b->top].board[row][column]);
            }
            printf("|\n");
        }
        /** Prints bottom border **/
        printf("   +-");
        for (int bot = 0; bot < b->stack[b->top].cs; bot++) {
            printf("--");
        }
        printf("+\n");
        /** Prints vertical column indices **/
        printf("     ");
        for (int tens = 0; tens < b->stack[b->top].cs; tens++) {
            printf("%d ", tens/10);
        }
        printf("\n");
        printf("     ");
        int count = 0;
        for (int ones = 0; ones < b->stack[b->top].cs; ones++) {
            if (count > 9) {
                count = 0;
            }
            printf("%d ", count);
            count++;
        }
    }
    
    extern int select(Game *b, int r, int c) {
        char colour = b->stack[b->top].board[r][c];
        int n = recursive_helper(b, r, c);
        if (n == 1) {
            b->stack[b->top].board[r][c] = colour;
            return 0;
        }
        b->stack[b->top].score += n*(n-1);
        return n;
    }
 
    
    int main() {
        Game *b = create(5, 10);
    
        display(b);
        printf("\n");
        printf("%d", bp_score(b));
        printf("\n");
    
        select(b, 2, 2);
        display(b);
        printf("\n");
        printf("%d", bp_score(b));
        printf("\n");
    
        b->top--;
        display(b);
        printf("\n");
        printf("%d", bp_score(b));
        printf("\n");
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

谢绝鈎搭 2025-01-16 17:34:20

正如评论中指出的,您的 create 函数不会实例化 Game 结构,您需要 b = malloc(sizeof(Game));
另一个错误是您的 malloc 使用 sizeof(int*) 和 sizeof(int) 而不是 sizeof(char*) 和 sizeof(char)。

除此之外,您的问题来自于 b->stack[b->top+1] = b->stack[b->top]; 复制的事实一个结构体,但 board 是一个指针,指向同一个对象!内存中只有一个 char** 指针和一块板。
因此,当您访问另一个结构时执行 b->top-- 时,它仍然指向同一个完全更新的板。
您需要创建一个函数Instance CopyInstance(Instance src),该函数在新结构中创建一个新板,然后将源板中的每个单元复制到新结构中。这样每个实例都会指向不同的板!

As pointed in the comments, your create function doesn't instantiate a Game struct, you need b = malloc(sizeof(Game));
Another error is that your mallocs use sizeof(int*) and sizeof(int) instead of sizeof(char*) and sizeof(char).

Other than that, your problem comes from the fact that b->stack[b->top+1] = b->stack[b->top]; copies a structure, but the board is a pointer and points to the same object! You only have one char** pointer and a single board in memory.
Thus, when you do b->top-- while you do access another struct, it still points to the same fully updated board.
You need to create a function Instance CopyInstance(Instance src) that creates a new board in the new struct and then copies each cell from the source board in the new one. That way each Instance will point to a different board!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文