数组元素消失
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,因此播放器隐藏在机翼中而不会导致程序崩溃。您应该做几件事:
- 找到并移动玩家后,
break
或 return
所以他们只会移动一次。
- 将阵列设为 5x5(或全部打印 6x6),这样您就可以看到所有内容。
- 做一些边界检查,这样玩家就不能从
j = 5
向右移动。
- 注意
move_up
中的相同错误,当您递增 i
时会发生这种错误。
您似乎在 get_player_loc
函数中进行了行和列索引的调换,以及有两个 return 语句(编译器应该警告您有关无法访问的代码),这两者都不是必需的或由调用代码使用。
开始时,初始化row
和col
变量。 (取自您的 main
的值。)
int row = 3;
int col = 3;
更改 get_player_loc
函数,使其仅更新全局变量 row
和 col
。如果找不到播放器,它会将 row
和 col
设置为 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;
}
当它们到达边缘时,您仍然会遇到问题,因为数组的索引在移动函数中越界,但这是一个不同的问题。
我正在尝试用 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,因此播放器隐藏在机翼中而不会导致程序崩溃。您应该做几件事:
- 找到并移动玩家后,
break
或return
所以他们只会移动一次。 - 将阵列设为 5x5(或全部打印 6x6),这样您就可以看到所有内容。
- 做一些边界检查,这样玩家就不能从
j = 5
向右移动。 - 注意
move_up
中的相同错误,当您递增i
时会发生这种错误。
您似乎在 get_player_loc
函数中进行了行和列索引的调换,以及有两个 return 语句(编译器应该警告您有关无法访问的代码),这两者都不是必需的或由调用代码使用。
开始时,初始化row
和col
变量。 (取自您的 main
的值。)
int row = 3;
int col = 3;
更改 get_player_loc
函数,使其仅更新全局变量 row
和 col
。如果找不到播放器,它会将 row
和 col
设置为 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;
}
当它们到达边缘时,您仍然会遇到问题,因为数组的索引在移动函数中越界,但这是一个不同的问题。