Почему мои фрукты возрождаются за пределами границ в игре «змея»?

#c

#c

Вопрос:

Я пытаюсь создать игру со змеей, в которой, если змея съест первый фрукт и через 2 секунды съест второй, то ее счет умножится на 2. Если змея съест второй плод за 1 секунду, то счет умножается на 3. Если змея съест второй фрукт за 3 секунды, то счет увеличивается всего на 1 и так далее … Но после того, как змея съест около 5-6 плодов, 7-й плод возрождается за пределами границ. Это функция «рисования»

 void make_stage() { score = 0; int x = 9, y = 9; int x1 = 8, y1 = 9; int x2 = 7, y2 = 9; int x3 = 6, y3 = 9; int x4 = 5, y4 = 9; char dir = 'd'; char input = 'e'; gotoxy(x, y); printf("a"); gotoxy(x1, y1); printf("*"); gotoxy(x2, y2); printf("*"); gotoxy(x3, y3); printf("*"); gotoxy(x4, y4); printf("*"); for (int i = 1; i lt;= 17; i  ) {  gotoxy(i, 1);  printf("#");  gotoxy(1, i);  printf("#");  gotoxy(17, i);  printf("#");  gotoxy(i, 17);  printf("#"); } srand(time(NULL)); fruitx = rand() % 17; fruity = rand() % 17; gotoxy(fruitx, fruity); printf("@"); }  

И это логическая функция:

 void snake_move() { int x = 9, y = 9; int x1 = 8, y1 = 9; int x2 = 7, y2 = 9; int x3 = 6, y3 = 9; int x4 = 5, y4 = 9; char dir = 'd'; char input = 'e'; while (1) {  srand(time(NULL));  if (x == fruitx amp;amp; y == fruity) {  fruitx = rand() % 17;  fruity = rand() % 17;  score  = 1;  gotoxy(fruitx, fruity);  printf("@");  }  input = _getch();  if ((dir == 'w' amp;amp; input != 's') || (dir == 'a' amp;amp; input != 'd') || (dir == 's' amp;amp; input != 'w') || (dir == 'd' amp;amp; input != 'a')) {  if (input == 'w') {  gotoxy(x4, y4);  printf(" ");  x4 = x3; x3 = x2; x2 = x1; x1 = x;  y4 = y3; y3 = y2; y2 = y1; y1 = y;  y = y - 1;  if (y == 1) {  gameover();  break;  }  if (x == x4 amp;amp; y == y4) {  gameover();  break;  }  gotoxy(x, y);  printf("a");  gotoxy(x1, y1);  printf("*");  gotoxy(x2, y2);  printf("*");  gotoxy(x3, y3);  printf("*");  gotoxy(x4, y4);  printf("*");  dir = 'w';  }  if (input == 'a') {  gotoxy(x4, y4);  printf(" ");  x4 = x3; x3 = x2; x2 = x1; x1 = x;  y4 = y3; y3 = y2; y2 = y1; y1 = y;  x = x - 1;  if (x == 1) {  gameover();  break;  }  if (x == x4 amp;amp; y == y4) {  gameover();  break;  }  gotoxy(x, y);  printf("a");  gotoxy(x1, y1);  printf("*");  gotoxy(x2, y2);  printf("*");  gotoxy(x3, y3);  printf("*");  gotoxy(x4, y4);  printf("*");  dir = 'a';  }  if (input == 's') {  gotoxy(x4, y4);  printf(" ");  x4 = x3; x3 = x2; x2 = x1; x1 = x;  y4 = y3; y3 = y2; y2 = y1; y1 = y;  y = y   1;  if (y == 17) {  gameover();  break;  }  if (x == x4 amp;amp; y == y4) {  gameover();  break;  }  gotoxy(x, y);  printf("a");  gotoxy(x1, y1);  printf("*");  gotoxy(x2, y2);  printf("*");  gotoxy(x3, y3);  printf("*");  gotoxy(x4, y4);  printf("*");  dir = 's';  }  if (input == 'd') {  gotoxy(x4, y4);  printf(" ");  x4 = x3; x3 = x2; x2 = x1; x1 = x;  y4 = y3; y3 = y2; y2 = y1; y1 = y;  x = x   1;  if (x == 17) {  gameover();  break;  }  if (x == x4 amp;amp; y == y4) {  gameover();  break;  }  gotoxy(x, y);  printf("a");  gotoxy(x1, y1);  printf("*");  gotoxy(x2, y2);  printf("*");  gotoxy(x3, y3);  printf("*");  gotoxy(x4, y4);  printf("*");  dir = 'd';  }  }  if (input == 'p') {  gameover();  break;  } } }  

и это весь исходный код на всякий случай!

 #includelt;stdio.hgt;  #includelt;windows.hgt;  #includelt;conio.hgt;  #includelt;time.hgt;  #includelt;stdlib.hgt;  #includelt;process.hgt;  int height = 17, width = 17;  typedef struct RECORD {  char name[100];  int score;  int minute;  int sec;  }record; //이름, 점수, 시간을 저장할 구조체  int score;  int fruitx, fruity;  record nowrec;    int over = 0;   void gotoxy(int x, int y); //Input location void make_stage(); //stage int getCommand(); // Keyboard input void gameover(); //Gameover screen void startscr(); //Start screen void snake_move(); //Snake movements void rank_call(); //Displaying rank void rankrecord(); //personal records  void cursor(int i); //  void stopwatch(); //stop watch     int main(void) {  startscr();  return 0;  }    void gotoxy(int x, int y) {  COORD pos = { 30   x * 2, 10   y };  SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);  }    void make_stage() {  score = 0;  int x = 9, y = 9;  int x1 = 8, y1 = 9;  int x2 = 7, y2 = 9;  int x3 = 6, y3 = 9;  int x4 = 5, y4 = 9;  char dir = 'd';  char input = 'e';  gotoxy(x, y);  printf("a");  gotoxy(x1, y1);  printf("*");  gotoxy(x2, y2);  printf("*");  gotoxy(x3, y3);  printf("*");  gotoxy(x4, y4);  printf("*");  for (int i = 1; i lt;= 17; i  ) {  gotoxy(i, 1);  printf("#");  gotoxy(1, i);  printf("#");  gotoxy(17, i);  printf("#");  gotoxy(i, 17);  printf("#");  }  srand(time(NULL));  fruitx = rand() % 17;  fruity = rand() % 17;  gotoxy(fruitx, fruity);  printf("@");  }    int getCommand() {  if (_kbhit()) {  return _getch();  }  return -1;  }    void cursor(int i) {  CONSOLE_CURSOR_INFO cursorInfo = { 0, };  cursorInfo.dwSize = 1;  cursorInfo.bVisible = i;  SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), amp;cursorInfo);  }    void rank_call() {  FILE* rank;  char reading[100];  if (fopen_s(amp;rank, "rank.txt", "r") != 0) printf("no recordn");  else {  printf("n");  while ((fgets(reading, 100, rank) != NULL)) printf("%s", reading);  fclose(rank);  printf("n");  }    }    void rankrecord() {  printf("npress enter to proceed...n");  while (getchar() != 'n');  printf("nnnnnnpress r to record your ranking...n");  char input = _getch();  if (input == 'r') {  FILE* rank;  fopen_s(amp;rank, "rank.txt", "a");  rerun:  printf("enter your name: ");  gets_s(nowrec.name, sizeof(nowrec.name));  if (strlen(nowrec.name) lt; 3) {  printf("name must be at least 3 words...nn");  goto rerun;  }  while (1) {  printf("your name is %s.nyour score is %d.nyour clear time is %d : %d.nn", nowrec.name, nowrec.score, nowrec.minute, nowrec.sec);  printf("if your name is incorrect, press n to correctnif not, press y to continue...nn");  input = _getch();  if (input == 'n') goto rerun;  else if (input == 'y') break;  else printf("wrong inputnn");  }  fprintf(rank, "%s %d %d : %dn", nowrec.name, nowrec.score, nowrec.minute, nowrec.sec);  fclose(rank);  printf("saved!n");  }  }    void startscr()  {    system("mode con cols=100 lines=40");  start:    system("cls");  printf(" ****** ** * * * * ****** ****** * ** ** ****** n");  printf(" * * * * * * * * * * * * * * * * * n");  printf(" ****** * * * ***** **** ****** * *** ***** * * * * ****** n");  printf(" * * * * * * * * * * * * * * ** * * n");  printf(" ****** * ** * * * * ****** ****** * * * ** * ****** n");  printf("npress s to start gamen");  printf("press r to see rankingn");  printf("press x to exitn:");  char input = _getch();  if (input == 's') {  system("cls");  cursor(0);  make_stage();  HANDLE thread1 = _beginthreadex(NULL, 0, (_beginthreadex_proc_type)stopwatch, NULL, 0, NULL);  Sleep(1);  HANDLE thread2 = _beginthreadex(NULL, 0, (_beginthreadex_proc_type)snake_move, NULL, 0, NULL);  WaitForSingleObject(thread2, INFINITE);    }  else if (input == 'r') {  rank_call();  printf("press enter to continue...");  while (getchar() != 'n');  goto start;  }  else if (input == 'x') exit(0);  else {  printf("wrong inputn");  printf("press enter to continue...");  while (getchar() != 'n');  goto start;  }  }    void gameover() {  over = 1;  system("cls");  printf("nnnnnnnnnn");  printf(" ****** * ** ** ****** **** * * ****** ***** n");  printf(" * * * * * * * * * * * * * * * n");  printf(" * *** ***** * * * * ****** * * * * ****** ***** n");  printf(" * * * * * ** * * * * * * * * * n");  printf(" ****** * * * ** * ****** **** * ****** * * n");  cursor(1);  rankrecord();  printf("press any key to back to title...");  _getch();  startscr();  }    void snake_move() {  int x = 9, y = 9;  int x1 = 8, y1 = 9;  int x2 = 7, y2 = 9;  int x3 = 6, y3 = 9;  int x4 = 5, y4 = 9;  char dir = 'd';  char input = 'e';  while (1) {  srand(time(NULL));  if (x == fruitx amp;amp; y == fruity) {  fruitx = rand() % 17;  fruity = rand() % 17;  score  = 1;  gotoxy(fruitx, fruity);  printf("@");  }  input = _getch();  if ((dir == 'w' amp;amp; input != 's') || (dir == 'a' amp;amp; input != 'd') || (dir == 's' amp;amp; input != 'w') || (dir == 'd' amp;amp; input != 'a')) {  if (input == 'w') {  gotoxy(x4, y4);  printf(" ");  x4 = x3; x3 = x2; x2 = x1; x1 = x;  y4 = y3; y3 = y2; y2 = y1; y1 = y;  y = y - 1;  if (y == 1) {  gameover();  break;  }  if (x == x4 amp;amp; y == y4) {  gameover();  break;  }  gotoxy(x, y);  printf("a");  gotoxy(x1, y1);  printf("*");  gotoxy(x2, y2);  printf("*");  gotoxy(x3, y3);  printf("*");  gotoxy(x4, y4);  printf("*");  dir = 'w';  }  if (input == 'a') {  gotoxy(x4, y4);  printf(" ");  x4 = x3; x3 = x2; x2 = x1; x1 = x;  y4 = y3; y3 = y2; y2 = y1; y1 = y;  x = x - 1;  if (x == 1) {  gameover();  break;  }  if (x == x4 amp;amp; y == y4) {  gameover();  break;  }  gotoxy(x, y);  printf("a");  gotoxy(x1, y1);  printf("*");  gotoxy(x2, y2);  printf("*");  gotoxy(x3, y3);  printf("*");  gotoxy(x4, y4);  printf("*");  dir = 'a';  }  if (input == 's') {  gotoxy(x4, y4);  printf(" ");  x4 = x3; x3 = x2; x2 = x1; x1 = x;  y4 = y3; y3 = y2; y2 = y1; y1 = y;  y = y   1;  if (y == 17) {  gameover();  break;  }  if (x == x4 amp;amp; y == y4) {  gameover();  break;  }  gotoxy(x, y);  printf("a");  gotoxy(x1, y1);  printf("*");  gotoxy(x2, y2);  printf("*");  gotoxy(x3, y3);  printf("*");  gotoxy(x4, y4);  printf("*");  dir = 's';  }  if (input == 'd') {  gotoxy(x4, y4);  printf(" ");  x4 = x3; x3 = x2; x2 = x1; x1 = x;  y4 = y3; y3 = y2; y2 = y1; y1 = y;  x = x   1;  if (x == 17) {  gameover();  break;  }  if (x == x4 amp;amp; y == y4) {  gameover();  break;  }  gotoxy(x, y);  printf("a");  gotoxy(x1, y1);  printf("*");  gotoxy(x2, y2);  printf("*");  gotoxy(x3, y3);  printf("*");  gotoxy(x4, y4);  printf("*");  dir = 'd';  }  }  if (input == 'p') {  gameover();  break;  }  }  }  void stopwatch() {  clock_t s, n;  s = clock();  while (1) {  n = clock();  cursor(0);  gotoxy(14, 0);  printf(" %d : %d", ((n - s) / 1000) / 60, ((n - s) / 1000) % 60);  if (over == 1) {  break;  }  Sleep(1000);  }  gotoxy(14, 0);  printf(" **** ");  nowrec.minute = ((n - s) / 1000) / 60;  nowrec.sec = ((n - s) / 1000) % 60;  return;  }  

Комментарии:

1. Каковы должны быть размеры вашего поля?

2. высота = 17 и ширина = 17.

3. Где вы заявляете score , fruitx , и fruity ? Без всего исходного кода решить проблему будет сложно.

4. Теперь я добавил весь исходный код. Это глобальные переменные.

Ответ №1:

Помните, что

 rand() % x  

даст вам значения в диапазоне [0, x-1].

Имея это в виду, давайте рассмотрим

 fruitx = rand() % 17; fruity = rand() % 17; gotoxy(fruitx, fruity); printf("@");  

Когда вы питаетесь rand() % 17 gotoxy() подобным образом, вы можете ожидать, что goto(0, 0) это возможно.

Я изменил приведенный выше код, чтобы он выглядел следующим образом

 fruitx = rand() % 17; fruity = rand() % 17; gotoxy(0, 0); printf("@");  

чтобы посмотреть, что произойдет, и фрукты оказались за пределами поля в левом верхнем углу.

 void gotoxy(int x, int y) {  COORD pos = { 30   x * 2, 10   y };  SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos); }  

Проблема в том, что ваше определение gotoxy() таково, что подача его (0, 0) в качестве координат для начала выводит курсор за пределы границы. Кроме того, прохождение (1, 1) ставит его в угол, отделяя от стены, что, как я полагаю, также незаконно.

Чтобы исправить это, вам нужно либо скорректировать свою математику, gotoxy() либо создать новую функцию, которая преобразует координаты вашего поля в глобальные координаты. Таким образом, (0, 0) будет соответствовать фактическому верхнему левому краю (только внутри границы) и так далее.

Самое простое решение-просто изменить его так

 fruitx = 2   rand() % 15;  fruity = 2   rand() % 15;  gotoxy(fruitx, fruity);  printf("@");  

Это должно происходить везде, где вы плодитесь.