数组元素消失

Array element disappears

我正在尝试用 x 标记他们的位置来跟踪玩家的位置。当玩家输入字符串时,我会相应地增加坐标。但是,当玩家位于距离边界 space 处,然后尝试移动到地图边缘时,玩家会消失。

示例:

.....  
...x.  
.....  
.....  
.....

玩家位于'x'

如果玩家输入字符串 "right" 并且我移动 player_loc,数组简单 returns:

.....  
.....  
.....  
.....  
.....

我试图通过增加数组的大小来添加一种缓冲区。没有运气。我已经坚持了将近一个星期了。任何帮助,将不胜感激。我为混乱的代码道歉。我在这方面完全是个新手,我真的只是在黑暗中摸索着所有这些东西。我已经在此处的论坛中对此进行了研究,但尚未找到解决方案。如果您知道我可能(可能)遗漏的内容,请随时指出我的方向。

#include <stdio.h>
#include <string.h>
char map[6][6];
char player_loc = 'x';
int row;
int col;

void init_map()
{
    for (int i = 0; i < 5; i++) {
        for (int j = 0; j < 5; j++) {

        map[i][j] = '.';

        }
    }
}

void print_map()
{
        for (int i = 0; i < 5; i++) {
            for (int j = 0; j < 5; j++) {

                printf("%c", map[i][j]);

            }
        printf("\n");
        }
}

int get_player_loc()
{
    for (int j = 0; j < 5; j++) {
        for (int k = 0; k < 5; k++) {
            if(map[j][k] == player_loc)
            {
                row = k;
                col = j;
            }
        }
    }
    return row;
    return col;
}

void init_player_loc()
{
    int check = 1;
    for (int g = 0; g < 5; g++) {
        for (int h = 0; h < 5; h++) {
            if (map[g][h] == 'x') {
                check = 0;
            }

        }   
    }
    if(check == 1) {
        map[0][0] = player_loc;
    } else {
        get_player_loc();
    }

}

void move_left()
{
    for (int i = 0; i < 5; i++) {
        for (int j = 0; j < 5; j++) {
            if (map[i][j] == player_loc) {
                map[i][j-1] = player_loc;
                map[i][j] = '.';
            }
        }
    }

}

void move_right()
{
    for (int i = 0; i < 5; i++) {
        for (int j = 0; j < 5; j++) {
            if (map[i][j] == player_loc) {
                map[i][j+1] = player_loc;
                map[i][j] = '.';
            }
        }
    }
}




int main(int argc, char* argv[])
{
    char input[15];
    printf("You enter a room...you can go left, right, or straight. Which way do you go?\n");

    int done = 0;

    init_map();
    map[3][3] = player_loc;
    //init_player_loc();
    print_map();

    while (!done)  {
        scanf("%s", input);

            if (strcmp("left", input) == 0) {
                move_left();
                printf("You go left...\n");
                print_map();
                get_player_loc();
                printf("%d %d\n", row, col);
                done = 1;
            } 
            else if (strcmp("right", input) == 0) {
                move_right();
                printf("You go right...\n");
                print_map();
                get_player_loc();
                printf("%d %d\n", row, col);
                done = 1;
            }
            else if (strcmp("straight", input) == 0) {
                printf("You go straight...");
                done = 1;
            }
            else {
                printf("Sorry, can't do that.\n");
            }
        }
}

您的循环允许检查位置两次,一次在 i,j,然后在 i,(j+1)(或其他变体)。这可能不是您想要的。找到播放器后,您应该进行更新,然后跳出循环。

此外,理论上,代码允许索引越过数组的边界。也不是所希望的。您可以考虑边界检查。我不知道当玩家向右移动并且右边有一堵墙时会发生什么。他不动吗?环绕? LR 角可能会像现在这样导致段错误。

如果找到播放器位置,则必须打破循环,例如

void move_right()
{
    for (int i = 0; i < 5; i++) {
        for (int j = 0; j < 5; j++) {
            if (map[i][j] == player_loc) {
                map[i][j+1] = player_loc;
                map[i][j] = '.';
                return;
            }
        }
    }
}

在您的代码中,您将玩家向右移动,下一个循环将在新位置找到玩家并再次向右移动,直到永远。

此外,在您的代码中您没有处理二维矩阵的边界:j+1 仅在 j<5 时有效。 那么更好的代码应该是

void move_right()
{
    for (int i = 0; i < 4; i++) {
        for (int j = 0; j < 4; j++) {
            if (map[i][j] == player_loc) {
                map[i][j+1] = player_loc;
                map[i][j] = '.';
                return;
            }
        }
    }
}

问题是您的 move_right 函数拾取玩家并将他们完全移出地图。假设您的播放器位于 [0, 2] 并单步执行代码。

for (int j = 0; j < 5; j++) {
    if (map[i][j] == player_loc) {
        map[i][j+1] = player_loc;
        map[i][j] = '.';
    }
}
  • [0, 0]这里没有玩家,继续前进
  • [0, 1]这里没有玩家,继续前进
  • [0, 2]找到玩家了!将它们向右移至 [0, 3]
  • [0, 3]找到玩家了!将它们右移到 [0, 4]
  • [0, 4]找到玩家了!将它们向右移至 [0, 5]

在 5,循环结束。由于您添加的缓冲区,您的数组是 6x6,因此播放器隐藏在机翼中而不会导致程序崩溃。您应该做几件事:

  • 找到并移动玩家后,breakreturn 所以他们只会移动一次。
  • 将阵列设为 5x5(或全部打印 6x6),这样您就可以看到所有内容。
  • 做一些边界检查,这样玩家就不能从 j = 5 向右移动。
  • 注意 move_up 中的相同错误,当您递增 i 时会发生这种错误。

您似乎在 get_player_loc 函数中进行了行和列索引的调换,以及有两个 return 语句(编译器应该警告您有关无法访问的代码),这两者都不是必需的或由调用代码使用。

开始时,初始化rowcol变量。 (取自您的 main 的值。)

int row = 3;
int col = 3;

更改 get_player_loc 函数,使其仅更新全局变量 rowcol。如果找不到播放器,它会将 rowcol 设置为 0,与原来的一样。

void get_player_loc(void)
{
    for (int j = 0; j < 5; j++) {
        for (int k = 0; k < 5; k++) {
            if(map[j][k] == player_loc)
            {
                // The meaning of row and col is set by how they are used
                // to index the array in the move and print functions.  Keep
                // the same order and meaning here.
                row = j;
                col = k;
                return;
            }
        }
    }
    // Set row and col to 0 if the location is not found.
    row = 0;
    col = 0;
    map[0][0] = player_loc;
}

当它们到达边缘时,您仍然会遇到问题,因为数组的索引在移动函数中越界,但这是一个不同的问题。