c语言综合之基于Ncurses的贪吃蛇
1.运行结果演示
2.游戏代码
#include <stdio.h>
#include <curses.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <pthread.h>
#define RIGHT -1
#define LEFT 1
#define UP -2
#define DOWN 2
struct Snake {
int hang;
int lie;
struct Snake *next;
};
struct Food {
int hang;
int lie;
};
int dir = 0;
struct Snake *head = NULL;
struct Snake *tail = NULL;
struct Food *food = NULL;
int hasDie() {
struct Snake *p = head->next;
if (tail->hang == 0 || tail->hang == 19) {
return 1;
} else if (tail->lie == 0 || tail->lie == 20) {
return 1;
}
while (p->next != tail) {
if ((tail->hang == p->hang) && (tail->lie == p->lie)) {
return 1;
}
p = p->next;
}
return 0;
}
int hasEat() {
if (tail->hang == food->hang && tail->lie == food->lie) {
return 1;
}
return 0;
}
void addNode(int con) {
struct Snake *node = (struct Snake *)malloc(sizeof(struct Snake));
switch (con) {
case RIGHT: {
node->hang = tail->hang;
node->lie = tail->lie + 1;
break;
}
case UP: {
node->hang = tail->hang - 1;
node->lie = tail->lie;
break;
}
case LEFT: {
node->hang = tail->hang;
node->lie = tail->lie - 1;
break;
}
case DOWN: {
node->hang = tail->hang + 1;
node->lie = tail->lie;
break;
}
}
node->next = NULL;
tail->next = node;
tail = node;
}
void delHead() {
struct Snake *p = head;
head = head->next;
free(p);
}
void initFood() {
food = (struct Food *)malloc(sizeof(struct Food));
food->hang = rand() % 18 + 1;
food->lie = rand() % 18 + 1;
}
void initCurses() {
initscr();
keypad(stdscr, 1);
}
void initSnake() {
head = (struct Snake *)malloc(sizeof(struct Snake));
head->lie = 2;
head->hang = 2;
head->next = NULL;
tail = head;
addNode(RIGHT);
addNode(RIGHT);
}
void destory_snake(){
struct Snake *p = head;
while(p){
free(p);
p=p->next;
}
}
int hasNode(int hang, int lie) {
struct Snake *p = head;
while (p) {
if (p->hang == hang && p->lie == lie) {
return 1;
}
p = p->next;
}
return 0;
}
int hasFood(int hang, int lie) {
if (food->hang == hang && food->lie == lie) {
return 1;
}
return 0;
}
int initMap() {
int hang;
int lie;
move(0, 0);
for (hang = 0; hang < 20; hang++) {
if (hang == 0 || hang == 19) {
for (lie = 0; lie < 20; lie++) {
printw("--");
}
printw("\n");
} else {
for (lie = 0; lie <= 20; lie++) {
if (lie == 0 || lie == 20) {
printw("|");
} else if (hasNode(hang, lie)) {
printw("[]");
} else if (hasFood(hang, lie)) {
printw("##");
} else {
printw(" ");
}
}
printw("\n");
}
}
}
void moveSnake() {
addNode(dir);
delHead();
if (hasDie()) {
destory_snake();
initSnake();
dir = RIGHT;
} else if (hasEat()) {
addNode(dir);
initFood();
}
}
void *getCon() {
int c;
while (1) {
c = getch();
switch (c) {
case KEY_DOWN: {
if (abs(dir) != abs(DOWN)) {
dir = DOWN;
}
break;
}
case KEY_UP: {
if (abs(dir) != abs(UP)) {
dir = UP;
}
break;
}
case KEY_RIGHT: {
if (abs(dir) != abs(RIGHT)) {
dir = RIGHT;
}
break;
}
case KEY_LEFT: {
if (abs(dir) != abs(LEFT)) {
dir = LEFT;
}
break;
}
}
}
}
void *Game() {
while (1) {
moveSnake();
initMap();
usleep(100000);
refresh();
}
}
int main() {
pthread_t th1;
pthread_t th2;
initCurses();
initSnake();
initFood();
initMap();
pthread_create(&th1, NULL, Game, NULL);
pthread_create(&th2, NULL, getCon, NULL);
while (1) {
}
getch();
endwin();
return 0;
}