Example #1
0
File: main.c Project: Touzen/snake
int tick() {
    // Handle user input
    Direction in = get_direction();
    if (in != NO_DIRECTION) {
        push_move(move_list, in);
    }
    
    // Handle snake movement
    update_direction(snake, move_list);
    move_snake(snake);

    // Draw everything
    draw_frame(snake, food_list);

    Collision collision = find_collision(snake, food_list, screen);
    switch(collision){
        case SNAKE:
        case SCREEN:
            return 0;
        
        case FOOD:
            grow_snake();
            new_food();
            break;

        case NONE:
            break;
    }
    
    snake_sleep();
    return 1;
}
Example #2
0
void gameloop(int nrow, int ncol) {
    timeout(1000 / SAMPLING_RATE);
    const clock_t checkpoint = (clock_t) (CLOCKS_PER_SEC/GAME_SPEED);
    clock_t last_update = clock();
    struct snake * snake = new_snake(ncol/2, nrow/2);
    struct point food_pos = generate_food(nrow, ncol, snake);
    redraw(snake, food_pos);
    for (;;) {
        struct point tail_pos = snake->tail->pos;
        int ch;
        if ((ch = getch()) != ERR) {
            switch (ch) {
            case KEY_UP:
            case KEY_DOWN:
            case KEY_LEFT:
            case KEY_RIGHT:
                if (to_dir(ch) == reverse_dir(snake->heading)) {
                    break;
                }
                else {
                    snake->heading = to_dir(ch);
                    step_snake(snake);
                    tail_pos = snake->tail->pos;
                    redraw(snake, food_pos);
                }
                break;
            default:
                break;
            }
        }
        if (clock() - last_update >= checkpoint) {
            step_snake(snake);
            tail_pos = snake->tail->pos;
            redraw(snake, food_pos);
            last_update = clock();
        }
        if (point_equal(snake->head->pos, food_pos)) {
            grow_snake(snake, tail_pos);
            food_pos = generate_food(nrow, ncol, snake);
            redraw(snake, food_pos);
        }
        if (out_of_border(snake->head->pos, nrow, ncol)
                || eat_self(snake)) {
            display_lose(nrow, ncol);
            return;
        }
        if (snake->length == (nrow-2)*(ncol-2)) {
            display_win(nrow, ncol);
            return;
        }
    }
}
Example #3
0
File: game.c Project: posva/msnake
void run() {
  int ch = 0, ich, i, current_columns, current_rows, success = 1;

  // some variables for the timer (inclusive the interval)
  struct timespec last_time              = {};
  struct timespec current_time           = {};
  long long default_interval             = 40000000;
  long long interval                     = default_interval;
  long long res;
  char playername[HIGHSCORE_NAME_LENGTH] = {};

  int range_counter = 0;

  // create the game struct
  GAME game = {};

  // set the eat range to 1
  game.snake.eat_range = 1;

  // helper variable to keep track of how long we've paused
  time_t pause_start;

  // get the dimensions of the terminal and store them in the GAME struct
  getmaxyx(stdscr, game.rows, game.columns);

  // clear the whole screen
  clear();

  // draw the walls
  draw_border(&game);

  // show the newly created walls
  refresh();

  // place the snake in the middle of the game field
  grow_snake(&game.snake, game.rows / 2, game.columns / 2);
  game.snake.dir = DIR_LEFT;

  // create some fruits on the screen
  // NOM, NOM, NOM
  for(i = 0; i < 50; i++) {
    grow_fruit(&game);
  }
  
  // get the time when the game started
  time(&game.started);
  // get the current time
  current_utc_time(&last_time);

  // start the event loop
  while((ich = getch()) && success) {
    // key typed?
    if(ich == ERR) {
    } else if(ich == '0') {
      // reset the speed
      interval = default_interval;
    } else if(ich == '8') {
      // speed up
      interval *= 1.1;
    } else if(ich == '9') {
      // slow down
      interval *= 0.9;
    } else {
      // use this key as a direction
      ch = ich;
    }
    // check if we have an overrun
    current_utc_time(&current_time);

    // calculate the dirrence between the last snake move and the current time
    res = timeval_diff(&last_time, &current_time);

    // is the interval over?
    if(res > interval) {
      // has an effect on the eat_range ?
      if(game.snake.eat_range > 1) {
        // every 200th field, decrease the range
        range_counter = (range_counter + 1) % 150;
        // it turns to 0 after the 200th field
        if(range_counter == 0) {
          game.snake.eat_range--; // so, decrease it!
        }
      }
      // new direction? 
      if((ch == KEY_UP || ch == 'w') && game.snake.dir != DIR_DOWN) {
        game.snake.dir = DIR_UP;
      } else if((ch == KEY_LEFT || ch == 'a') && game.snake.dir != DIR_RIGHT) {
        game.snake.dir = DIR_LEFT;
      } else if((ch == KEY_RIGHT || ch == 'd') && game.snake.dir != DIR_LEFT) {
        game.snake.dir = DIR_RIGHT;
      } else if((ch == KEY_DOWN || ch == 's') && game.snake.dir != DIR_UP) {
        game.snake.dir = DIR_DOWN;
      }
      // move the snake
      success = move_snake(&game);

      // refresh the screen
      refresh();

      // display the status bar (top-right)
      status_display(&game);

      // update the time when we last moved the snake
      last_time = current_time;
    }
    
    getmaxyx(stdscr, current_rows, current_columns);
    // 'p' pressed || size of the terminal changed
    if(ich == 'p' || (current_rows != game.rows || current_columns != game.columns)) {
      // use the terminal new size
      game.rows = current_rows;
      game.columns = current_columns;

      // get the time
      time(&pause_start);

      // show the pause dialog
      switch(pause_dialog()) {
        case 2:
          // leave the game if '2' is pressed
          success = 0;
        default:
          // redraw the screen on resume
          game.paused += time(NULL) - pause_start;
          redraw_game(&game);
          break;
      }
    }
  }

  // get the time when the game has ended
  time(&game.ended);

  // display the highscore dialog & let the player enter his name
  display_highscore(&game, playername, HIGHSCORE_NAME_LENGTH);

  // has a name been entered? if not don't create a highscore entry
  if(playername[0]) {
    add_highscore(playername, game.highscore, game.ended - game.started - game.paused);
  }

  // free all the resources reserved in the game struct
  kill_game(&game);
}
Example #4
0
// move the snake
int move_snake(GAME *game) {
  int success = 1, i;

  // some variables containing positions of certain things
  int curx, cury, tmpy, tmpx;

  // callbacks to check collisions
  int (*collision_checks[EVENTS])(GAME*, int, int) = {
    check_self_collision,
    check_extended_border_collision,
    check_fruit_collision
  };

  // callbacks which will be called automaticly if a collision is detected
  // the callback at position 1 in the array belongs to the check-function
  // at position 1 from the array above
  int (*collision_handlers[EVENTS])(GAME*, int, int) = {
    check_self_collision_handler,
    check_border_collision_handler,
    check_fruit_collision_handler
  };


  // difference on x-axis according to the direction
  int xdiff = game->snake.dir == DIR_LEFT ? -1 : (game->snake.dir == DIR_RIGHT ? 1 : 0);
  // difference on y-axis according to the direction
  int ydiff = game->snake.dir == DIR_UP ? -1 : (game->snake.dir == DIR_DOWN ? 1 : 0);

  // the position of the snake head
  getbegyx(game->snake.parts[0], cury, curx);

  // make a copy
  tmpy = cury;
  tmpx = curx;

  // calculate the new position and prevent from exceeding the size of the screen
  cury = (cury + ydiff) % game->rows;
  curx = (curx + xdiff) % game->columns;
  // the values have to be positive
  cury = cury < 0 ? game->rows + cury : cury;
  curx = curx < 0 ? game->columns + curx : curx;

  // check for collisons and execute the handlers if a collision occured
  for(i = 0; i < EVENTS && success; i++) {
    // collision?
    if((collision_checks[i](game, cury, curx))) {
      // should we end the game because of the collision?
      if(!collision_handlers[i](game, cury, curx)) {
        success = 0;
      }
    }
  }

  // no collisions ?
  if(success) {
    // set the direction of the head
    mvwprintw(game->snake.parts[0], 0, 0, "%c", game->snake.dir);
    // move the window
    mvwin(game->snake.parts[0], cury, curx);

    // copy values back
    cury = tmpy;
    curx = tmpx;

    // iterate through each part of the snake
    for(i = 1; i < game->snake.length; i++) {
      // get the position of the current part
      getbegyx(game->snake.parts[i], tmpy, tmpx);

      // move the part to the position of the previous one
      mvwin(game->snake.parts[i], cury, curx);

      // make a copy
      cury = tmpy;
      curx = tmpx;
    }

    // grow?
    if(game->snake.grow > 0) {
      // grow the snake
      grow_snake(&game->snake, cury, curx);

      // decrease the grow counter (number of times the snake will grow in the future)
      game->snake.grow--;
    } else {
      // is the snake head on the same position as the last part of the snake was before?
      getbegyx(game->snake.parts[0], tmpy, tmpx);
      if(!(tmpy == cury && tmpx == curx)) {
        // if no print a space at this position
        WINDOW *cur = newwin(1, 1, cury, curx);
        wprintw(cur, "%c", ' ');
        wrefresh(cur);
        delwin(cur);
      }
    }

    // redraw the snake on the screen
    redraw_snake(&game->snake);
  } else {
    SDL_LockAudio();
    oamlPlaySfx("lose");
    SDL_UnlockAudio();
  }
  return success;
}