当结构包含 char ** 变量时如何撤消堆栈?
How to undo a stack when the struct contains a char ** variable?
下面的代码有点像糖果美眉游戏,您可以在其中弹出一组相似的字母,然后它们就会消失,您就得分了。在主要方面,我尝试向前播放一步然后撤消它,并且它有效,因为分数设法撤消(从 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");
}
正如评论中指出的,您的创建函数没有实例化 Game 结构,您需要 b = malloc(sizeof(Game));
另一个错误是您的 mallocs 使用 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)
以在新结构中创建一个新板,然后将源板中的每个单元格复制到新结构中。这样每个实例都会指向不同的板!
下面的代码有点像糖果美眉游戏,您可以在其中弹出一组相似的字母,然后它们就会消失,您就得分了。在主要方面,我尝试向前播放一步然后撤消它,并且它有效,因为分数设法撤消(从 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");
}
正如评论中指出的,您的创建函数没有实例化 Game 结构,您需要 b = malloc(sizeof(Game));
另一个错误是您的 mallocs 使用 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)
以在新结构中创建一个新板,然后将源板中的每个单元格复制到新结构中。这样每个实例都会指向不同的板!