Thread: Help with ncurses: Snake game

  1. #1
    Registered User
    Join Date
    Dec 2013
    Posts
    25

    Unhappy Help with ncurses: Snake game

    Code:
    #include <curses.h>
    #define UP 3
    #define DOWN 2
    #define RIGHT 5
    #define LEFT 4
    
    
    int main(void){
       
      // activate the keypad to read from this terminal
      keypad(initscr(),TRUE);
    
      int pout = 0; //pen on/off (if even/odd)
      int xPos=1;     // initialise the x and y positions of the cursor
      int yPos=2;
      char map[1000][1000];
      char c='\0';  // input character initialise to null
      
              
      while( c!='q'){ // loop while the user has not pressed 'q'
        
            if(pout % 2 == 0){
            mvaddch(yPos,xPos,'*');
            map[yPos][xPos] = '*';
    }
            if(pout % 2 != 0){
            mvaddch(yPos,xPos,' ');
    }
            c=getch();    // read a single character
        
        if (c == 'p'){    //p changes even-->odd etc for toggle
            pout = pout + 1;
            noecho();
    }
       
        switch(c){
        case UP: 
          yPos--;
          break;
        case DOWN:
          yPos++;
          break;
        case LEFT:
          xPos--;
          break;
        case RIGHT:
          xPos++;
    
    }
    } 
    
    mvdelch(yPos,xPos+1);  //delete the q
    xPos = 1;
    yPos = 3;
    
    while( c!='f'){
        mvaddch(yPos,xPos,'O');    //This is the start of snake, snake won't move..
        // read a single character
        c=getch();
        // move according to cursor
        switch(c){
        case UP:
          if (map[yPos-1][xPos]== ' '){
            yPos--;
        map[yPos][xPos] = 'O';
          }
          break;
        case DOWN:
          if (map[yPos+1][xPos]== ' '){
            yPos++;
        map[yPos][xPos] = 'O';
          }
          break;
        case LEFT:
          if (map[yPos][xPos-1]== ' '){
            xPos--;
        map[yPos][xPos] = 'O';
          }
          break;
        case RIGHT:
          if (map[yPos][xPos+1]== ' '){
            xPos++;
        map[yPos][xPos] = 'O';
          }
        }
      }
    }

    You toggle the pen on and off with 'p' to draw a map, or obstacle course. When 'q' is pressed the cursor should return to top left and print 'O', from there its a game of snake (but without the snake food)-so you cant go through the map thats been drawn or your tail.

    It compiles and I can draw the map, but can't get the snake to go..

    Any suggestions? Im noob so it's probably something rediculous.

    I'll also add a move counter once i get the snake to move.

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Every other time you wanted to put a character on the screen you used mvaddch. Why not do it here too? (You never print the map, so changing map won't affect what's on the screen in any way I can see.)

  3. #3
    Registered User
    Join Date
    Dec 2013
    Posts
    25
    Quote Originally Posted by tabstop View Post
    Every other time you wanted to put a character on the screen you used mvaddch. Why not do it here too? (You never print the map, so changing map won't affect what's on the screen in any way I can see.)
    The seond while loop has the mvaddch operator at the top for the snake, the map never prints but the idea was to buil an array thats a mirror image of the screen and can dictate where the cursor can go. I didnt know how else to recognise the obstacles on the screen..

  4. #4
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Yes, changing the values of your variables won't move the snake. You need the equivalent of putchar() to do that.

    When the head has found a valid place to move to, then the entire snake body needs to move so it occupies the former position of the segment in front of it. So it's a quick "wave" action, from head to tail, as the segments of the snake move.

    In a windows text game, it looks like this in a text based game. Here, the user's char is ascii 1, and d is "door", but "door" really means "room". (Don't ask, OK?)

    Code:
      if (GetAsyncKeyState(VK_UP) & 0xf)  // Up! key 
       {
          t = (r - 1);
          Goto(user.x, user.y);
          switch (room[*d][t][c]) {
          case ' ':                // Space.
             //printf("room[y2][x]: %uc\n",room[y2][x]); //getchar();
             room[*d][r][c] = ' ';
             room[*d][t][c] = '\1';
             putchar(' ');
             --r;
             Goto(c, r);   putchar(1);
             break;
    
          case TMD:                // Health Pack.
             room[*d][r][c] = ' ';
             room[*d][t][c] = '\1';
             putchar(' ');
             --r;
             Goto(user.x, r);   putchar(1);
             user.life += 5; 
             break;
          case GOLD:               // Gold!  //bags of gold dust
             room[*d][r][c] = ' ';
             room[*d][t][c] = '\1';
             putchar(' ');
             --r;
             Goto(user.x, r);   putchar(1);
             user.gold++;
             break;
          case '-':
             room[*d][r][c] = ' ';
             putchar(' ');
             if (r == 1)
                r = MAXROW - 2;
             else
                r = r - 2;
             Goto(c, r); putchar(1);
             room[*d][r][c] = 1;
          }
       } else if (GetAsyncKeyState(VK_DOWN) & 0xf)  // Down!
       {
          t = (r + 1);
          Goto(user.x, user.y);
          switch (room[*d][t][c]) {
          case ' ':                // Space.
             room[*d][r][c] = ' ';
             room[*d][t][c] = '\1';
             putchar(' ');
             ++r;
             Goto(c, r);  putchar(1);
             break;
          case TMD:                // Health Pack
             room[*d][r][c] = ' ';
             room[*d][t][c] = '\1';
             putchar(' ');
             ++r;
             Goto(c, r); putchar(1);
             user.life += 5;
             break;
          case GOLD:               // Gold!
             room[*d][r][c] = ' ';
             room[*d][t][c] = '\1';
             putchar(' ');
             ++r;
             Goto(c, r); putchar(1);
             user.gold++;
             break;
          case '-':                // Door
             room[*d][r][c] = ' ';
             putchar(' ');
             if (r == MAXROW - 2)
                r = 1;
             else
                r = r + 2;
             Goto(c, r);
             putchar(1);
             room[*d][r][c] = 1;
          }
       } else if (GetAsyncKeyState(VK_LEFT) & 0xf)  // Left!
       {
          t = (c - 1);
          Goto(user.x, user.y);
          switch (room[*d][r][t]) {
          case ' ':                // Space
             room[*d][r][c] = ' ';
             room[*d][r][t] = '\1';
             putchar(' ');
             --c;
             Goto(c, r);
             putchar(1); //1
             break;
          case TMD:                // Health Pack
             room[*d][r][c] = ' ';
             room[*d][r][t] = '\1';
             putchar(' ');
             --c;
             Goto(c, r);
             putchar(1);
             user.life += 5;
             break;
          case GOLD:               //Gold!
             room[*d][r][c] = ' ';
             room[*d][r][t] = '\1';
             putchar(' ');
             --c;
             Goto(c, r);
             putchar(1);
             user.gold++;
             break;
          case '|':                // Door 
             room[*d][r][c] = ' ';
             putchar(' ');
             if (c == 1) {
                c = MAXCOL - 3;
                (*d)--;              // to a lower door  
                room[*d][r][c] = 1;  // put user into the array
                user.x=c; user.y=r;
                printRoom(*d);
                SetConsoleTextAttribute(hConsole, 0x0E);
             }else
                c -= 2;
             
             room[*d][r][c] = 1;
             Goto(c, r);
             putchar(1);
             break;
          }
       }else if (GetAsyncKeyState(VK_RIGHT) & 0xf)   // Right!
       {
          t = (c + 1);
          Goto(user.x, user.y);
          switch (room[*d][r][t]) {
          case ' ':                // Space
             room[*d][r][c] = ' ';
             room[*d][r][t] = '\1';
             putchar(' ');
             ++c;
             Goto(c, r);
             putchar(1);
             break;
          case TMD:                // Health Pack
             room[*d][r][c] = ' ';
             room[*d][r][t] = '\1';
             putchar(' ');
             ++c;
             Goto(c, r);
             putchar(1);
             user.life += 5;
             break;
          case GOLD:               //Gold!
             room[*d][r][c] = ' ';
             room[*d][r][t] = '\1';
             putchar(' ');
             ++c;
             Goto(c, r);
             putchar(1);
             user.gold++;
             break;
          case '|':                // Door
             room[*d][r][c] = ' ';
             putchar(' ');
             if (c == MAXCOL - 3) {
                c = 2;
                (*d)++;
                room[*d][r][c]= 1;
                user.x=c; user.y=r;
                printRoom(*d);
                SetConsoleTextAttribute(hConsole, 0x0E);
             }else
                c += 2;
    
             room[*d][r][c] = 1;
             Goto(c, r);
             putchar(1);
             break;
          }
       }else if (GetAsyncKeyState(VK_ESCAPE) & 0xf) {
          exit(1);
       }
       user.x = c;
       user.y = r;
    }
    Goto is not like goto in programming - it's like goto(x,y), in text based cursor movement, on the console window.
    Last edited by Adak; 12-19-2013 at 07:00 PM.

  5. #5
    Registered User
    Join Date
    Dec 2013
    Posts
    25
    Quote Originally Posted by Adak View Post
    Yes, changing the values of your variables won't move the snake. You need the equivalent of putchar() to do that.

    When the head has found a valid place to move to, then the entire snake body needs to move so it occupies the former position of the segment in front of it. So it's a quick "wave" action, from head to tail, as the segments of the snake move.
    I wasn't going to do that at this stage, because i don't have 'snake food' to make it grow the snake's tail will stay at the start position while the head stretches away and that's how its going to grow. I may change this later but for now id just like to get it running like this. So itll be the same as the map drawing bit only you wont be able to pass through anything on the scren.

  6. #6
    misoturbutc Hodor's Avatar
    Join Date
    Nov 2013
    Posts
    1,787
    What's stopping the snake "moving" is that your array (char map[1000][1000]) is not initialized as containing all space (' ') characters. So, in the snake "movement" code the if (... = ' ') checks are evaluating to false[1]. I.e. you need to initialize the map

    [1] More precisely the value of the cell, for example, [yPos-1][xPos] is undefined unless it got inititialized by your maze/obstacle part of the code (and for the majority of cells this won't be the case).
    Last edited by Hodor; 12-19-2013 at 08:24 PM.

  7. #7
    Registered User
    Join Date
    Dec 2013
    Posts
    25
    OK- I found that in the seond switch group when checking the map for free space to move to: ' ' should be \0 as the empty array slots are null spaces not ' ' spaces... Thanks for your help guys!

  8. #8
    Registered User
    Join Date
    Dec 2013
    Posts
    25
    Quote Originally Posted by Hodor View Post
    What's stopping the snake "moving" is that your array (char map[1000][1000]) is not initialized as containing all space (' ') characters. So, in the snake "movement" code the if (... = ' ') checks are evaluating to false. I.e. you need to initialize them map
    You got it straight away Hodor! Thanks!

  9. #9
    misoturbutc Hodor's Avatar
    Join Date
    Nov 2013
    Posts
    1,787
    Quote Originally Posted by Camjerlams View Post
    You got it straight away Hodor! Thanks!
    hodor

  10. #10
    Registered User
    Join Date
    Dec 2013
    Posts
    25
    Quote Originally Posted by Hodor View Post
    hodor
    Such wisdom..

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Dat snake game...
    By esrelmantis in forum C++ Programming
    Replies: 3
    Last Post: 05-19-2013, 04:24 AM
  2. Help with a snake game?
    By awr7126 in forum Game Programming
    Replies: 2
    Last Post: 12-06-2010, 06:39 PM
  3. Need help with a snake game (ncurses)
    By Adam4444 in forum C Programming
    Replies: 11
    Last Post: 01-17-2007, 03:41 PM
  4. My Snake Game
    By ()Q() in forum Game Programming
    Replies: 2
    Last Post: 07-23-2002, 03:03 PM
  5. game (snake)
    By nps in forum C Programming
    Replies: 1
    Last Post: 10-09-2001, 10:37 PM

Tags for this Thread