1

I'm trying to write a snake clone, and I've just begun writing the code, but I have some problems in getting the keypad to work. It seems to not be getting the signal when I click the arrows keys. This is my code

#include <iostream>
#include <unistd.h>
#include <ncurses.h>

struct Snake{
    int x, y;
    char s = 'O'; // logo
} snake;

int main()
{

    initscr();
    noecho();
    curs_set(0);
    keypad(stdscr, true);
    nodelay(stdscr, true);
    start_color();
    init_pair(1, COLOR_MAGENTA, COLOR_BLACK );
    attron(COLOR_PAIR(1));
    int HEIGHT, WIDTH;

    getmaxyx(stdscr, HEIGHT, WIDTH);

    for (int x = 0; x < WIDTH-1; x++)
        mvaddch(0, x, '*');

    for (int y = 0; y < HEIGHT-2; y++)
        mvaddch(y, WIDTH-1, '*');

    for (int x = 0; x < WIDTH-1; x++)
        mvaddch(HEIGHT-2, x, '*');

    for (int y = 0; y < HEIGHT-2; y++)
        mvaddch(y, 0, '*');


    snake.x = WIDTH/2;
    snake.y = HEIGHT/2;
    mvaddch(snake.y, snake.x, snake.s);
    refresh();


    char key;
    while((key = getch()) != 'q')
    {
        mvaddch(snake.y, snake.x, ' ');
        switch(key)
        {
        case KEY_RIGHT:
            snake.x +=1;    
            break;

        case KEY_LEFT:
            snake.x -=1;    
            break;

        case KEY_UP:
            snake.y -=1;    
            break;

        case KEY_DOWN:
            snake.y +=1; 
            break;
        }

        mvaddch(snake.y, snake.x, snake.s);

        usleep(100000);
        refresh();
    }

    getch();
    erase();
    endwin();
}
Mokosha
  • 2,737
  • 16
  • 33
MathGuy1991
  • 57
  • 1
  • 6
  • 3
    You should *always* compile with `-Wall` (at least). Had you done that, the compiler would have warned you that a `char` (`key`) is not big enough to hold the value of the cases `KEY_RIGHT` etc. – rici Apr 21 '14 at 03:07

2 Answers2

2

Use wchar_t instead char, to store arrow key codes.

Take a look at this: char vs wchar_t when to use which data type.

The bottom line in, that char is guaranteed enough space for ASCII character set, because its quantity abut to 256 bits. But, Unicode encoding requires more space, than char can afford.

Kassi
  • 151
  • 2
  • 12
0

char is not big enough to hold KEY_RIGHT, because it is part of a set of characters beginning after the range of char.

Likewise, wchar_t is big enough, but (read the manpage) int or chtype is the right type for the example given, as the compiler would tell you (when asked).

(int and chtype are not the same size, either, but for practical purposes, any int used by a curses library will fit in an int).

Thomas Dickey
  • 51,086
  • 7
  • 70
  • 105