Member 14825085 Ответов: 4

Как мне двигаться в квадрате и что я делаю не так


привет..может ли кто-нибудь объяснить мне, почему, если я нажимаю кнопку s или кнопку d, это вызывает у меня ошибку сегментации, но с кнопкой и кнопкой w это работает нормально.это просто функция для перемещения игрока p в квадрате так же, как змея.

Что я уже пробовал:

void move(){

int i;
int j;
char choice;
scanf("%s",&choice);

for (i = 0; i < rows; ++i) {
	for (j = 0; j < cols; ++j) {
		if(maze[i][j] == 'p' && choice == 'a'){
                   char tmp =  maze[i][j];
                    maze[i][j] = maze[i][j-1];
                    maze[i][j-1] = tmp;
		}

                 if(maze[i][j] == 'p' && choice == 'w'){
                         char tmp =  maze[i][j];
                        maze[i][j] = maze[i-1][j];
                        maze[i-1][j] = tmp;
                }

                if(maze[i][j] == 'p' && choice == 'd'){
                        char tmp = maze[i][j];
                        maze[i][j] = maze[i][j+1];
                        maze[i][j+1] = tmp;
                }

                  if(maze[i][j] == 'p' && choice == 's'){
                        char tmp =  maze[i][j];
                        maze[i][j] = maze[i+1][j];
                        maze[i+1][j] = tmp;
                }
	}
 }

}

jeron1

maze[i][j-1] = tmp;


Что произойдет, если j = 0?

Member 14825085

для этого его хорошо, потому что я создаю границу для игрока(так что он не может пойти туда).проблема заключается в d(справа) и s(вниз).

jeron1

Не уверен, что понимаю это, но.....
нечто подобное может произойти и здесь

maze[i+1][j] = tmp; 

где [i+1] может быть вне зоны досягаемости.

4 Ответов

Рейтинг:
2

Rick York

Первое, что вам нужно сделать, это сделать себе функцию подкачки. Эта последовательность кода :

char tmp = maze[i][j];
maze[i][j] = maze[i][j+1];
maze[i][j+1] = tmp;
повторяется четыре раза с различными аргументами, и это приглашение к ошибкам. Создайте для себя функцию swap, которая принимает четыре аргумента: destination x, destination y, source x и source y. Он должен принимать сам лабиринт в качестве аргумента, но, по-видимому, это глобальная переменная.

Эта функция подкачки будет служить двум целям : она поместит общую функциональность в одно место и даст вам возможность сделать проверку в одном месте. В этой функции вы можете убедиться, что все индексы действительны. Очевидно, что они не действительны в определенных обстоятельствах, и это даст вам одно место для проверки и сообщения об ошибке, когда она будет найдена.


Patrice T

Привет, Рик, S2-это сообщение для тебя.

Рейтинг:
2

KarstenK

Попробуйте упростить свой код таким образом

for (i = 0; i < rows; ++i) {
	for (j = 0; j < cols; ++j) {
		if(maze[i][j] == 'p') 
			continue;

		switch( choice )  {
		  case 'a':
                   swapMaze(i, j, i, j - 1);
                   break;
                   
                   //further cases
		}
	}
 }
Когда у вас есть проблема, чем сделать некоторые выходные данные в функции swapMaze.


Рейтинг:
2

Patrice T

Совет: Научитесь правильно делать отступы в вашем коде, это покажет его структуру и поможет чтению и пониманию. Это также помогает выявлять структурные ошибки.

void move(){

    int i;
    int j;
    char choice;
    scanf("%s",&choice);

    for (i = 0; i < rows; ++i) {
        for (j = 0; j < cols; ++j) {
            if(maze[i][j] == 'p' && choice == 'a'){
                char tmp =  maze[i][j];
                maze[i][j] = maze[i][j-1];
                maze[i][j-1] = tmp;
            }

            if(maze[i][j] == 'p' && choice == 'w'){
                char tmp =  maze[i][j];
                maze[i][j] = maze[i-1][j];
                maze[i-1][j] = tmp;
            }

            if(maze[i][j] == 'p' && choice == 'd'){
                char tmp = maze[i][j];
                maze[i][j] = maze[i][j+1];
                maze[i][j+1] = tmp;
            }

            if(maze[i][j] == 'p' && choice == 's'){
                char tmp =  maze[i][j];
                maze[i][j] = maze[i+1][j];
                maze[i+1][j] = tmp;
            }
        }
    }

}

Стиль отступа - Википедия[^]

Профессиональные редакторы программистов имеют эту функцию и другие, такие как сопоставление скобок и подсветка синтаксиса.
Блокнот++ Главная Страница[^]
личные[^]
-----
Ваш код очень простодушен, это приводит к повторению в основном одного и того же кода.
Во первых вы повторяете одно и то же везде в цикле:
void move(){

	int i;
	int j;
	char choice;
	scanf("%s",&choice);

	for (i = 0; i < rows; ++i) {
		for (j = 0; j < cols; ++j) {
			if(maze[i][j] == 'p'){
				if(choice == 'a'){
					char tmp =  maze[i][j];
					maze[i][j] = maze[i][j-1];
					maze[i][j-1] = tmp;
				}

				if(choice == 'w'){
					char tmp =  maze[i][j];
					maze[i][j] = maze[i-1][j];
					maze[i-1][j] = tmp;
				}

				if(choice == 'd'){
					char tmp = maze[i][j];
					maze[i][j] = maze[i][j+1];
					maze[i][j+1] = tmp;
				}

				if(choice == 's'){
					char tmp =  maze[i][j];
					maze[i][j] = maze[i+1][j];
					maze[i+1][j] = tmp;
				}
			}
		}
	}

}

Этот код быстрее, потому что он тестирует "P" один раз за цикл, а не 4 раза.
возможны и другие варианты оптимизации.
-----
Я предполагаю, что " п " - это игрок.
Проблема в том, что ваш код не проверяет наличие стен.
Проблема в том, что ваш код не проверяет, останется ли игрок в лабиринте.
Задача, при движении вниз или вправо, p перемещается в новое положение, которое будет посещаться петлями и таким образом перемещается снова, пока не переместится после окончания лабиринта.
Совет следите за положением p с 2 переменными px и py, это позволит избежать необходимости в 2 петлях при перемещении p.


Рейтинг:
1

Member 14825085

Эй, Рик Йорк. Как я могу сделать это немного сложнее


Patrice T

Чтобы обсудить с автором, если есть решение, используйте "есть вопрос или комментарий?" кнопка в нижней части решения.

Rick York

No, it is most definitely not complicated. The source x and y are always going to be i and j. The destination depends on which way it is moving. The example I showed was to j+1 in columns. This means the arguments to the function will be (i, j, i, j+1) to move right. Now you need to associate those four arguments with the logic in the example and you will have your function. The key here is those four parameters can be destx, desty, srcx, and srcy so then look how j+1 was used in the example snipped and substitute it with argument srcy that you will pass to it. Then do that with the other three arguments. The first i, paired with (j) will be destx and that lone j will be dest y. The second i which is paired with j+1 becomes srcx.

Я не собираюсь писать это для вас, потому что вы должны это сделать.

Member 14825085

//мое обновление все еще не работает


пустое движение(){

int i;
инт Дж;
выбор char;
scanf ("%c",&choice);


for (i = 0; i < rows-1; ++i) {
для (j = 0; j < cols-1; ++j) {





если(лабиринт[я][Дж] == 'п' &&усилителя; выбор = = "а"){

move2(i,j,i,j-1);

}

если(лабиринт[я][Дж] == 'п' &&усилителя; выбор == 'ж'){

move2(i,j,i-1,j);

}

если(лабиринт[я][Дж] == 'п' &&усилителя; выбор == 'д'){


move2(i,j,i,j+1);

}

если(лабиринт[я][Дж] == 'п' &&усилителя; выбор == 'с'){


move2(i,j,i+1,j);



}



}
}
}

пустота move2(инт srcx,srcy инт,инт destx,desty инт){


char tmp = лабиринт[srcx][srcy];
лабиринт[srcx][srcy] = лабиринт[destx][desty];
лабиринт[destx][desty] = tmp;





}

/////я обновляю свой код так, как вы говорите, но кнопка s и d все еще не работает

Rick York

Это еще не все, что я написал. Я также писал о проверке ошибок в функции перемещения. Убедитесь, что ни один из них не опускается ниже нуля или выше размера лабиринта. Это была другая цель для размещения вещей в одном месте.