Игра "Змейка". Бесконечный цикл и прочите проблемы

Не могу понять, почему цикл работает бесконечно, при том, что я обозначил ему, когда останавливаться -- когда введу клавишу 'f' в функции input(x,y), но программа не дает мне ввести что-либо в поток ввода, чтобы продолжить игру или завершить ее вовсе.

Кстати, в редакторе кода visual studio code нет этого бесконечного цикла, то есть все работает более-менее корректно (по крайне мене с циклом больше проблем нет).

#include <stdio.h>
#include <string.h>
#include <windows.h>

#define UP      1
#define DOWN    2
#define LEFT    3
#define RIGHT   4

#define STOP 100


#define HEIGHT 10
#define WIDTH 20

int picture[HEIGHT][WIDTH];

int input(int, int);
void printSnake(void);

void initialization(void){
    extern int picture[HEIGHT][WIDTH];
    for(int index1 = 0; index1 < HEIGHT; index1++)
        for(int index2 = 0; index2 < WIDTH; index2++) 
            picture[index1][index2] = ' ';
}
void apples(void){
    extern int picture[HEIGHT][WIDTH];

    picture[HEIGHT-4][WIDTH-4] = '.';
    picture[HEIGHT-8][WIDTH-10] = '.';
}
void draw(void){
    
    extern int picture[HEIGHT][WIDTH];

    initialization();
    
    int i = 0 , j = 0;
    for(int i = 0; i < HEIGHT; i++){
        for(int j = 0; j < WIDTH; j++){
            if(i == 0)picture[i][j] = '#';
            if(i == HEIGHT - 1) picture[i][j] = '#';
            if(j == WIDTH - 1) picture[i][j] = '|';        
        }
        picture[i][j] = '\n';
    }

    for(int a = 0; a < HEIGHT; a++)
        picture[a][1] = '|';
    
    apples();
}
int input(int x, int y){
    extern int picture[HEIGHT][WIDTH];

    char operation;

    printf("%s\n","Enter (UP,DOWN,RIGHT,LEFT):");
    scanf("%c",&operation);
    switch (operation)
    {
    case 'w':
        picture[--x][y] = '0';
        return UP;
    case 's':
        picture[++x][y] = '0';
        return DOWN;
    case 'a':
        picture[x][--y] = '0';
        return LEFT;
    case 'd':
        picture[x][++y] = '0';
        return RIGHT;
    case 'f':
        return STOP;
    default:
        return 0;
    }
}
void printSnake(void){
    extern int picture[HEIGHT][WIDTH];
    for(int index1 = 0; index1 < HEIGHT; index1++)
        for(int index2 = 0; index2 < WIDTH; index2++)
            printf("%c",picture[index1][index2]);
}
int main(void){
    int x = 5, y = 9;
    while(1){
        draw();
        int cnt = input(x, y);
        if (cnt == UP) --x;
        else if (cnt == DOWN) ++x;
        else if (cnt == LEFT) --y;
        else if (cnt == RIGHT) ++y;
        else if (cnt == STOP) break;
        printSnake();
    }
    printf("\n%s","END");
    return 0;
}

И да, еще, помогите пожалуйста исправить повторяющиеся рисунок. Он вырисовывается дважды, перед тем, когда нужно ввести символ (движение: 'w','s','d','e').

p.s. у меня windows


Ответы (1 шт):

Автор решения: Solt

Ну очень много лишнего написано.

  1. Глобальные переменные не надо объявлять как extern в функциях, если они в этом же модуле.
  2. Циклы, делающие одно и то же выполняются множество раз.
  3. Вывод текста нерационально делать посимвольно. Достаточно в массиве указать последним символом 0 и выводить всю строку сразу. Для этого и массив не нужен int, раз он содержит символы - достаточно char.
#include <stdio.h>
#include <string.h> 
#include <windows.h>

#define UP      1
#define DOWN    2
#define LEFT    3
#define RIGHT   4

#define STOP 100

#define HEIGHT 10
#define WIDTH 20



char picture[HEIGHT][WIDTH+1];

int input(int, int); 
void printSnake(void);

void apples(void){
    picture[HEIGHT-4][WIDTH-4] = '.';
    picture[HEIGHT-8][WIDTH-10] = '.';
}

void draw(void){
    for(int i = 0; i < HEIGHT; i++){
        for(int j = 0; j < WIDTH; j++){
            if(j==0 || j == WIDTH - 1) picture[i][j] = '|';
            else if(i == 0 || i == HEIGHT - 1)picture[i][j] = '#';
            else picture[i][j] = ' ';
        }
        picture[i][WIDTH] = '\n';
    }
    picture[HEIGHT-1][WIDTH] = 0;
    apples(); 
}

int input(int x, int y){
    char operation;
    printf("%s\n","Enter (UP,DOWN,RIGHT,LEFT):");
    scanf("%c",&operation);
    switch (operation)
    {
    case 'w':
        picture[--x][y] = '0';
        return UP;
    case 's':
        picture[++x][y] = '0';
        return DOWN;
    case 'a':
        picture[x][--y] = '0';
        return LEFT;
    case 'd':
        picture[x][++y] = '0';
        return RIGHT;
    case 'f':
        return STOP;
    default:
        return 0;
    } 
} 

void printSnake(void){
    printf("\033[%d;%df",1,1); //Возврат курсора в начало экрана
    printf("%s\n",(char*)picture); 
} 


int main(void){
    int x = 5, y = 9;
    while(1){
        draw();
        int cnt = input(x, y);
        if (cnt == UP) --x;
        else if (cnt == DOWN) ++x;
        else if (cnt == LEFT) --y;
        else if (cnt == RIGHT) ++y;
        else if (cnt == STOP) break;
        printSnake();
    }
    printf("\n%s","END");
    return 0;
}
→ Ссылка