如何解决我的蛇食食物源不循环?

时间:2019-05-07 01:28:45

标签: c

我正在研究蛇,但是食物来源有些问题。我正在尝试这样做,以便在食物生成时以1-9的随机整数生成,但是我的代码一直在从1-9倒数,并且不停留在单个整数值上。知道它与我主循环中的循环有关,该循环不断刷新屏幕,每次都会更改值,但是我不确定该如何处理。

我试图在newfood()函数内部添加if语句以运行rand()数字生成器,但它仍然无法正常工作。还尝试将newfood函数置于循环之外,但仍无法正常工作。任何帮助将不胜感激!

#include <ncurses.h>
#include <unistd.h>
#include <sys/select.h>
#include <stdlib.h>
#include <time.h>
#include <stdio.h>
#include <sys/time.h>
#include <signal.h>

#define MAXWIDTH 79
#define MAXHEIGHT 23

int lenbuf;
int total = 1;

void eatfood(int *snakeArr, int foodX, int foodY, int *foodate, int *snakelen);
void newFood(int* fPosX, int* fPosY, int *foodGrabbed);
int hitWall(int *snakeArr, int snakelen);
void moveSnake(int *snakeArr, int dX, int dY, int speed, int snakelen);
int arrowKeys (void);
void addTail();
void countdown(int signum);
int set_ticker( int n_msecs );

int growthValue = 0;

int main() {

  int snakeArr[100][2];
  for (size_t i = 0; i < 100; i++) {
    for (size_t j = 0; j < 2; j++) {
      snakeArr[i][j] = 0;
    }
  }

  snakeArr[0][0] = (rand() % MAXWIDTH) + 1;
  snakeArr[0][1] = (rand() % MAXHEIGHT) + 1;
  int keyPressed = 0;   /* which key user pressed */
  int dX = 1;        /* direction xy */
  int dY = 0;
  int speed = 10;       /* controls speed of the snake */
  int fPosX = 0;       /* current apple xy position */
  int fPosY = 0;
  int foodGrabbed = 1;   /* is apple eaten? */
  int snakelen = 1;  /* player snakelen */



  initscr();      /* Start curses mode */
  curs_set(false);
  noecho();
  keypad(stdscr, TRUE);

        //newFood(&fPosX, &fPosY, &foodGrabbed);

  /* MAIN LOOP */
  while (!hitWall(&snakeArr[0][0], snakelen)) {
    erase();

    newFood(&fPosX, &fPosY, &foodGrabbed);
    moveSnake(&snakeArr[0][0], dX, dY, speed, snakelen);
    eatfood(&snakeArr[0][0], fPosX, fPosY, &foodGrabbed, &snakelen);

  border(124,124,45,45,47,92,92,47);
    move(LINES-11,1);
    hline('-', COLS-2);

    move(0,0);

    refresh();
    int previous;
    while(arrowKeys()){
        switch(keyPressed = getch()){
                case KEY_UP:
                        dY = -1;
                        dX = 0;
                        if(previous == KEY_DOWN){
                                mvprintw(LINES-10, 1, "You tried going backwards");
                                goto end;
                        }
                        previous = KEY_UP;
                        break;
                case KEY_DOWN:
                        dY = 1;
                        dX = 0;
                        if(previous == KEY_UP){
                                mvprintw(LINES-10, 1, "You tried going backwards");
                                goto end;
                        }
                        previous = KEY_DOWN;
                        break;
                case KEY_LEFT:
                        dY = 0;
                        dX = -1;
                        if(previous == KEY_RIGHT){
                                mvprintw(LINES-10, 1, "You tried going backwards");
                                goto end;
                        }
                        previous = KEY_LEFT;
                        break;
                case KEY_RIGHT:
                        dY = 0;
                        dX = 1;
                        if(previous == KEY_LEFT){
                                mvprintw(LINES-10, 1, "You tried going backwards");
                                goto end;
                        }
                        previous = KEY_RIGHT;
                        break;
        }
   }
  }
  end:  mvprintw(LINES-9,COLS/3,"Game Over! - Your score was: %d", snakelen);
  getch();      /* Wait for user input */
  endwin();     /* End curses mode      */

  return 0;
}



int arrowKeys (void) {
  /* checks if key has been hit or not */
  struct timeval tv;
  fd_set read_fd;

  tv.tv_sec=0; // get seconds
  tv.tv_usec=0; // gets useconds
  FD_ZERO(&read_fd); // clears the set
  FD_SET(0,&read_fd); // adds a given file descriptor from the set

  if(select(1, &read_fd, NULL, NULL, &tv) == -1) /* select allow a program to monitor multiple file descriptors,
                                                    waiting until one or more of the file descriptors become
                                                    "ready" for some class of I/O operation. A file descriptor is
                                                    considered ready if it is possible to perform the corresponding
                                                    I/O operation without blocking. The operation of  */
    return 0;
  // Tests to see if the file descriptor is part of the set
  if(FD_ISSET(0,&read_fd))
    return 1;

  return 0;
}

int hitWall(int *snakeArr, int snakelen) {
  /* checks if snake is colliding with walls */
  int x = *snakeArr;
  int y = *(snakeArr+1);

  if (x <= 0 || x >= COLS-1) {
    return 1;
  }
  else if (y <= 0 || y >= LINES-10) {
    return 1;
  }

  for (size_t i = 2; i < snakelen*2+2; i+=2) {
    if (x == *(snakeArr+i) && y == *(snakeArr+i+1)) {
      return 1;
    }
  }
  return 0;
}

void moveSnake(int *snakeArr, int dX, int dY, int speed, int snakelen) {
  /* moves snake one position to the direction provided also controls the speed
     of the game using usleep function */
  int oldX = 0;
  int oldY = 0;
  int curX = *snakeArr;
  int curY = *(snakeArr+1);
  int newX = curX + dX;
  int newY = curY + dY;

  *(snakeArr) = newX;
  *(snakeArr+1) = newY;
  mvprintw(newY, newX, "0");

  for (int i = 2; i < snakelen*2; i += 2) {
    oldX = curX;
    oldY = curY;
    curX = *(snakeArr+i);
    curY = *(snakeArr+i+1);
    newX = oldX;
    newY = oldY;
    *(snakeArr+i) = newX;
    *(snakeArr+i+1) = newY;

    mvprintw(newY, newX, "0");
  }
  speed = snakelen;
  usleep(200000/speed);
}

void newFood(int* fPosX, int* fPosY, int *foodGrabbed) {
  /* new random apple location if apple is eaten, if not then prints apple at
     previous location */

  int foodnum = (random()%9)+1;
  char foodgrow = (char)(((int)'0')+foodnum);
  growthValue = foodnum;
  while (*foodGrabbed) {
    *foodGrabbed = 0;
    *fPosX = (rand() % MAXWIDTH)+1;
    *fPosY = (rand() % MAXHEIGHT)+1;
  }

  move(*fPosY, *fPosX);
  addch(foodgrow);
}

void eatfood(int *snakeArr, int fPosX, int fPosY, int *foodGrabbed, int *snakelen){
  /* if snake find apple get one point, also sets foodGrabbed to true and
  prints snakelen and debug info */
  int x = *snakeArr;
  int y = *(snakeArr+1);
  if (x == fPosX && y == fPosY) {
    *foodGrabbed = 1;
    *snakelen += growthValue;
    int snakeLen = *snakelen;
    int lastX = *(snakeArr + snakeLen*2-2);
    int lastY = *(snakeArr + snakeLen*2-2+1);
    *(snakeArr + snakeLen*2) = lastX;
    *(snakeArr + snakeLen*2+1) = lastY;
  }

  mvprintw(0,0,"snakelen: %d", *snakelen);
}

运行代码时,蛇会运行,如果吃了,则添加数量。需要创建结果,以便每次产生食物时都将其保持为整数,并且不会继续循环计数。

0 个答案:

没有答案