我正在研究蛇,但是食物来源有些问题。我正在尝试这样做,以便在食物生成时以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);
}
运行代码时,蛇会运行,如果吃了,则添加数量。需要创建结果,以便每次产生食物时都将其保持为整数,并且不会继续循环计数。