`#ifndef MY_GAME_H
#define MY_GAME_H
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <curses.h>
#define EMPTY ' '
#define BORDER '*'
#define PLAYER 'P'
#define GOAL 'G'
#define COLLAPSED 'X'
typedef struct position {
int row;
int col;
} Position;
typedef struct node {
Position pos;
char collapsed_color;
struct node* next;
} Node;
typedef struct list {
Node* head;
int size;
} List;
int ROW, COL;
char** map;
Position player, goal;
List history;
void initialize() {
int i, j;
map = (char**)malloc(ROW * sizeof(char*));
for (i = 0; i < ROW; i++) {
map[i] = (char*)malloc(COL * sizeof(char));
for (j = 0; j < COL; j++) {
if (i == 0 || i == ROW - 1 || j == 0 || j == COL - 1) {
map[i][j] = BORDER;
}
else {
map[i][j] = EMPTY;
}
}
}
if (history.size > 0) {
player = history.head->pos;
goal = history.head->next->pos;
} else {
// initialize player and goal to default values
player.row = 1;
player.col = 1;
goal.row = ROW - 2;
goal.col = COL - 2;
}
map[player.row][player.col] = PLAYER;
map[goal.row][goal.col] = GOAL;
}
void print_map() {
int i, j;
for (i = 0; i < ROW; i++) {
for (j = 0; j < COL; j++) {
if (i == player.row && j == player.col) {
attron(COLOR_PAIR(1));
printw("%c ", map[i][j]);
attroff(COLOR_PAIR(1));
}
else if (i == goal.row && j == goal.col) {
attron(COLOR_PAIR(2));
printw("%c ", map[i][j]);
attroff(COLOR_PAIR(2));
}
else if (map[i][j] == COLLAPSED) {
if (i == history.head->pos.row && j == history.head->pos.col) {
attron(COLOR_PAIR(3));
printw("%c ", map[i][j]);
attroff(COLOR_PAIR(3));
}
else {
printw("%c ", map[i][j]);
}
}
else {
printw("%c ", map[i][j]);
}
}
printw("n");
}
}
void collapse_floor() {
int i, j;
Node* new_node = (Node*)malloc(sizeof(Node));
new_node->collapsed_color = 'r';
do {
new_node->pos.row = rand() % (ROW - 2) + 1;
new_node->pos.col = rand() % (COL - 2) + 1;
} while (map[new_node->pos.row][new_node->pos.col] != EMPTY);
new_node->next = history.head;
history.head = new_node;
history.size++;
map[new_node->pos.row][new_node->pos.col] = COLLAPSED;
}
void move_player(int row_offset, int col_offset) {
if (map[player.row + row_offset][player.col + col_offset] == EMPTY) {
map[player.row][player.col] = EMPTY;
player.row += row_offset;
player.col += col_offset;
map[player.row][player.col] = PLAYER;
collapse_floor();
}
else if (map[player.row + row_offset][player.col + col_offset] == GOAL){
map[player.row][player.col] = EMPTY;
player.row += row_offset;
player.col += col_offset;
map[player.row][player.col] = PLAYER;
print_map();
printf("nYou Win!n");
exit(0);
}
}
void undo_move() {
if (history.size > 1) {
Node* old_node = history.head;
history.head = history.head->next;
history.size--;
if (map[player.row][player.col] == COLLAPSED) {
map[player.row][player.col] = EMPTY;
}
player = history.head->pos;
if (map[player.row][player.col] == COLLAPSED) {
map[player.row][player.col] = PLAYER;
map[old_node->pos.row][old_node->pos.col] = COLLAPSED;
} else {
map[player.row][player.col] = PLAYER;
if (map[old_node->pos.row][old_node->pos.col] == COLLAPSED) {
map[old_node->pos.row][old_node->pos.col] = EMPTY;
}
map[old_node->pos.row][old_node->pos.col] = COLLAPSED;
}
free(old_node);
}
}
void end_game() {
printf("Game over!n");
exit(0); // Terminate the program with exit status 0 (success)
}
int main(int argc, char* argv[]) {
int i;
srand(time(NULL));
if (argc != 7) {
printf("Usage: ./game ROW COL player_row player_col goal_row goal_coln");
exit(1);
}
ROW = atoi(argv[1]);
COL = atoi(argv[2]);
player.row = atoi(argv[3]);
player.col = atoi(argv[4]);
goal.row = atoi(argv[5]);
goal.col = atoi(argv[6]);
if (player.row < 0 || player.row >= ROW || player.col < 0 || player.col >= COL ||
goal.row < 0 || goal.row >= ROW || goal.col < 0 || goal.col >= COL) {
printf("Invalid player or goal position.n");
exit(1);
}
history.head = (Node*)malloc(sizeof(Node));
history.head->pos = player;
history.head->collapsed_color = 'r';
history.head->next = NULL;
history.size = 1;
initscr();
start_color();
init_pair(1, COLOR_BLUE, COLOR_BLACK);
init_pair(2, COLOR_YELLOW, COLOR_BLACK);
init_pair(3, COLOR_RED, COLOR_BLACK);
initialize();
print_map();
while (1) {
int ch = getch();
switch (ch) {
case 'w':
move_player(-1, 0);
break;
case 'a':
move_player(0, -1);
break;
case 's':
move_player(1, 0);
break;
case 'd':
move_player(0, 1);
break;
case 'u':
undo_move();
break;
case 'q':
end_game();
break;
}
if (player.row == goal.row && player.col == goal.col) {
end_game();
}
print_map();
}
endwin();
for (i = 0; i < ROW; i++) {
free(map[i]);
}
free(map);
while (history.size > 0) {
undo_move();
}
return 0;
}
#endif /* MY_GAME_H */`
我目前正在一个项目上工作,当我试图用命令行参数运行我的代码时,我在Linux终端上不断弹出分割错误消息,我遇到了一些麻烦。具体来说,当我尝试运行命令:"/escape 7 8 1 1 5 3".
我已经试过调试代码,但不幸的是,我还没能弄清楚是什么导致错误。我最初认为我可能传递了错误数量的命令行参数,但在仔细检查我的代码后,我确认我传递了正确的6个参数。
编译我的代码没有问题,但我被困在这个分割错误信息。我希望有更有经验的人能帮我找出问题的根源。
进入initialize
函数时,history.size
的值为1。因此我们使用if语句的这个分支:
if (history.size > 0) {
player = history.head->pos;
goal = history.head->next->pos; // Problem.
问题是history.head->next
是NULL
,所以代码是通过空指针引用的。
player
和goal
已经在main
中设置了,也许这是重构而initialize
没有更新?