文章目录
项目的目的
熟练掌握C语言,并非要精通Ncurse
Ncurse的输入输出
#include <curses.h>
int main(){
initscr();//ncurse界面的初始化
printw("hello world\n");//这是ncurse模式下的printf
getch();//等待用户输入,如果没有这句话,程序就退出了,看不到运行的结果,也就是看不到上面那句话
endwin();//程序退出,调用该函数来回复shell终端的显示,如果没有这句话,shell终端字乱码,坏掉。
return 0;
}
编译指令
vi cursedemo.c
gcc cursedemo.c -lcurses
./a.out
要改名的话
gcc cursedemo.c -lcurses -o cursedemo
./cursedemo
Ncurse上下左右键获取
#include <curses.h>
int main(){
int key;//因为用char表示的话是1字节8位最大值是128,小于curses.h中定义的方向值
initscr();
keypad(stdscr,1);//想要获取方向键必须写的函数
while(1){
key = getch();
switch(key){
case KEY_DOWN:
printw("DOWN\n");
break;
case KEY_UP:
printw("UP\n");
break;
case KEY_LEFT:
printw("LEFT\n");
break;
case KEY_RIGHT:
printw("RIGHT\n");
break;
}
}
endwin();
return 0;
}
地图规划
大小20x20或40x40
地图竖直方向上的边界“|”
地图水平方向上的边界“–”
贪吃蛇的身子“[]”
贪吃蛇的食物“##”
地图实现
第1和最后一行画“–”,其它行首列和最后一列画“|”,其余画空格
//初始化ncurse
//画地图
#include <curses.h>
void initNcurse(){
initscr();
keypad(stdscr,1);
}
void gamePic(){
int hang;
int lie;
for(hang=0;hang<20;hang++){
if(hang == 0){
for(lie=0;lie<20;lie++){
printw("--");
}
printw("\n");
}
if(hang>=0 && hang<=19){
for(lie=0;lie<=20;lie++){
if(lie==0 || lie==20){
printw("|");
}else{
printw(" ");
}
}
printw("\n");
}
if(hang == 19){
for(lie=0;lie<20;lie++){
printw("--");
}
printw("\n");
printw("By Aaron\n");
}
}
}
int main()
{
initNcurse();
gamePic();
getch();
endwin();
return 0;
}
画蛇的身子
用链表作蛇身,当蛇身的坐标与地图上的坐标相等,画蛇身
//定义蛇身
//初始化蛇身
//添加蛇身
//画蛇身
#include <curses.h>
#include <stdlib.h>
typedef struct Snake{
int row;
int column;
struct Snake *next;
}Snake;
Snake *head;
Snake *tail;
void initNcurse(){
initscr();
keypad(stdscr,1);
}
int hasSnakeNode(int row,int column){
Snake *p = head;
while(p != NULL){
if(p->row == row && p->column == column){
return 1;
}
p = p->next;
}
return 0;
}
void gamePic(){
int row;
int column;
for(row=0;row<20;row++){
if(row == 0 || row == 19){
for(column=0;column<20;column++){
printw("--");
}
printw("\n");
}
if(row>0 && row<19){
for(column=0;column<=20;column++){
if(column==0 || column==20){
printw("|");
}else if(hasSnakeNode(row,column)){
printw("[]");
}else{
printw(" ");
}
}
printw("\n");
}
}
}
void addNode(){
Snake *newNode = (Snake *)malloc(sizeof(Snake));
newNode->row = tail->row;
newNode->column = tail->column + 1;
newNode->next = NULL;
tail->next = newNode;
tail = newNode;
}
void initSnake(){
head = (Snake *)malloc(sizeof(Snake));
head->row = 2;
head->column = 2;
head->next = NULL;
tail = head;
addNode();
addNode();
addNode();
}
int main()
{
initNcurse();
initSnake();
gamePic();
getch();
endwin();
return 0;
}
让蛇向右移动
蛇向右移就是在蛇的尾部添加一个节点并删除头部节点
//判断按键如果向右
//蛇向右移动
注意在画图的方法中添加move(0,0);
#include <curses.h>
#include <stdlib.h>
typedef struct Snake{
int row;
int column;
struct Snake *next;
}Snake;
Snake *head;
Snake *tail;
void initNcurse(){
initscr();
keypad(stdscr,1);
}
int hasSnakeNode(int row,int column){
Snake *p = head;
while(p != NULL){
if(p->row == row && p->column == column){
return 1;
}
p = p->next;
}
return 0;
}
void gamePic(){
int row;
int column;
move(0,0);
for(row=0;row<20;row++){
if(row == 0 || row == 19){
for(column=0;column<20;column++){
printw("--");
}
printw("\n");
}
if(row>0 && row<19){
for(column=0;column<=20;column++){
if(column==0 || column==20){
printw("|");
}else if(hasSnakeNode(row,column)){
printw("[]");
}else{
printw(" ");
}
}
printw("\n");
}
}
}
void addNode(){
Snake *newNode = (Snake *)malloc(sizeof(Snake));
newNode->row = tail->row;
newNode->column = tail->column + 1;
newNode->next = NULL;
tail->next = newNode;
tail = newNode;
}
void initSnake(){
head = (Snake *)malloc(sizeof(Snake));
head->row = 2;
head->column = 2;
head->next = NULL;
tail = head;
addNode();
addNode();
addNode();
}
void deleteNode(){
Snake *p;
p = head;
head = head->next;
free(p);
}
void moveSnake(){
addNode();
deleteNode();
}
int main()
{
int control;
initNcurse();
initSnake();
gamePic();
while(1){
control = getch();
if(control == KEY_RIGHT){
moveSnake();
gamePic();
}
}
getch();
endwin();
return 0;
}
蛇向右移动撞墙
如果蛇的坐标到了墙的地方就初始化蛇
#include <curses.h>
#include <stdlib.h>
typedef struct Snake{
int row;
int column;
struct Snake *next;
}Snake;
Snake *head = NULL;
Snake *tail = NULL;
void initNcurse(){
initscr();
keypad(stdscr,1);
}
int hasSnakeNode(int row,int column){
Snake *p = head;
while(p != NULL){
if(p->row == row && p->column == column){
return 1;
}
p = p->next;
}
return 0;
}
void gamePic(){
int row;
int column;
move(0,0);
for(row=0;row<20;row++){
if(row == 0 || row == 19){
for(column=0;column<20;column++){
printw("--");
}
printw("\n");
}
if(row>0 && row<19){
for(column=0;column<=20;column++){
if(column==0 || column==20){
printw("|");
}else if(hasSnakeNode(row,column)){
printw("[]");
}else{
printw(" ");
}
}
printw("\n");
}
}
}
void addNode(){
Snake *newNode = (Snake *)malloc(sizeof(Snake));
newNode->row = tail->row;
newNode->column = tail->column + 1;
newNode->next = NULL;
tail->next = newNode;
tail = newNode;
}
void initSnake(){
Snake *p = NULL;
while(head != NULL){
p = head;
head = head->next;
free(p);
}
head = (Snake *)malloc(sizeof(Snake));
head->row = 2;
head->column = 2;
head->next = NULL;
tail = head;
addNode();
addNode();
addNode();
}
void deleteNode(){
Snake *node = head;
head = head->next;
free(node);
}
void moveRight(){
addNode();
deleteNode();
if(tail->row == 0 || tail->row == 20 || tail->column == 0 || tail->column == 20){
initSnake();
}
}
int main()
{
initNcurse();
initSnake();
gamePic();
int control;
while(1){
control = getch();
if(control == KEY_RIGHT){
moveRight();
gamePic();
}
}
getch();
endwin();
return 0;
}
向右自动移动
去掉按键判断,将向右移动放在死循环中每隔一段时间刷新一次
#include <curses.h>
#include <stdlib.h>
typedef struct Snake{
int row;
int column;
struct Snake *next;
}Snake;
Snake *head = NULL;
Snake *tail = NULL;
void initNcurse(){
initscr();
keypad(stdscr,1);
}
int hasSnakeNode(int row,int column){
Snake *p = head;
while(p != NULL){
if(p->row == row && p->column == column){
return 1;
}
p = p->next;
}
return 0;
}
void gamePic(){
int row;
int column;
move(0,0);
for(row=0;row<20;row++){
if(row == 0 || row == 19){
for(column=0;column<20;column++){
printw("--");
}
printw("\n");
}
if(row>0 && row<19){
for(column=0;column<=20;column++){
if(column==0 || column==20){
printw("|");
}else if(hasSnakeNode(row,column)){
printw("[]");
}else{
printw(" ");
}
}
printw("\n");
}
}
}
void addNode(){
Snake *newNode = (Snake *)malloc(sizeof(Snake));
newNode->row = tail->row;
newNode->column = tail->column + 1;
newNode->next = NULL;
tail->next = newNode;
tail = newNode;
}
void initSnake(){
Snake *p = NULL;
while(head != NULL){
p = head;
head = head->next;
free(p);
}
head = (Snake *)malloc(sizeof(Snake));
head->row = 2;
head->column = 2;
head->next = NULL;
tail = head;
addNode();
addNode();
addNode();
}
void deleteNode(){
Snake *node = head;
head = head->next;
free(node);
}
void moveRight(){
addNode();
deleteNode();
if(tail->row == 0 || tail->row == 20 || tail->column == 0 || tail->column == 20){
initSnake();
}
}
int main()
{
initNcurse();
initSnake();
gamePic();
int control;
while(1){
moveRight();
gamePic();
refresh();
usleep(100000);
}
getch();
endwin();
return 0;
}
开启一条新线程运行2个while(1)
#include <stdio.h>
#include <pthread.h>
void* func1(){
while(1){
printf("this is func1\n");
sleep(1);
}
}
void* func2(){
while(1){
printf("this is func2\n");
sleep(1);
}
}
int main()
{
pthread_t th1;
// start a new thread th1 to run func1
pthread_create(&th1,NULL,func1,NULL);
func2();
return 0;
}
保存代码
gcc threadDemo -lpthread
./a.out
使用线程实现蛇向4个方向移动
初步实现开启2个新线程
一个线程不停移动蛇,一个线程不断接收方向按键变化
#include <curses.h>
#include <stdlib.h>
#include <pthread.h>
typedef struct Snake{
int row;
int column;
struct Snake *next;
}Snake;
Snake *head = NULL;
Snake *tail = NULL;
void initNcurse(){
initscr();
keypad(stdscr,1);
}
int hasSnakeNode(int row,int column){
Snake *p = head;
while(p != NULL){
if(p->row == row && p->column == column){
return 1;
}
p = p->next;
}
return 0;
}
void gamePic(){
int row;
int column;
move(0,0);
for(row=0;row<20;row++){
if(row == 0 || row == 19){
for(column=0;column<20;column++){
printw("--");
}
printw("\n");
}
if(row>0 && row<19){
for(column=0;column<=20;column++){
if(column==0 || column==20){
printw("|");
}else if(hasSnakeNode(row,column)){
printw("[]");
}else{
printw(" ");
}
}
printw("\n");
}
}
}
void addNode(){
Snake *newNode = (Snake *)malloc(sizeof(Snake));
newNode->row = tail->row;
newNode->column = tail->column + 1;
newNode->next = NULL;
tail->next = newNode;
tail = newNode;
}
void initSnake(){
Snake *p = NULL;
while(head != NULL){
p = head;
head = head->next;
free(p);
}
head = (Snake *)malloc(sizeof(Snake));
head->row = 2;
head->column = 2;
head->next = NULL;
tail = head;
addNode();
addNode();
addNode();
}
void deleteNode(){
Snake *node = head;
head = head->next;
free(node);
}
void moveRight(){
addNode();
deleteNode();
if(tail->row == 0 || tail->row == 20 || tail->column == 0 || tail->column == 20){
initSnake();
}
}
void refreshPic(){
while(1){
moveRight();
gamePic();
refresh();
usleep(100000);
}
}
void changeDir(){
int key;
while(1){
key = getch();
switch(key){
case KEY_DOWN:
printw("DOWN\n");
break;
case KEY_UP:
printw("UP\n");
break;
case KEY_LEFT:
printw("LEFT\n");
break;
case KEY_RIGHT:
printw("RIGHT\n");
break;
}
}
}
int main()
{
initNcurse();
initSnake();
gamePic();
pthread_t th1;
pthread_t th2;
pthread_create(&th1,NULL,refreshPic,NULL);
pthread_create(&th2,NULL,changeDir,NULL);
while(1);
getch();
endwin();
return 0;
}
gcc moveFourDirection.c -lcurses -lpthread
./a.out
初步实现蛇向4个方向移动
#include <curses.h>
#include <stdlib.h>
#include <pthread.h>
# define UP 1
# define DOWN 2
# define LEFT 3
# define RIGHT 4
typedef struct Snake{
int row;
int column;
struct Snake *next;
}Snake;
Snake *head = NULL;
Snake *tail = NULL;
int direction;
void initNcurse(){
initscr();
keypad(stdscr,1);
}
int hasSnakeNode(int row,int column){
Snake *p = head;
while(p != NULL){
if(p->row == row && p->column == column){
return 1;
}
p = p->next;
}
return 0;
}
void gamePic(){
int row;
int column;
move(0,0);
for(row=0;row<20;row++){
if(row == 0 || row == 19){
for(column=0;column<20;column++){
printw("--");
}
printw("\n");
}
if(row>0 && row<19){
for(column=0;column<=20;column++){
if(column==0 || column==20){
printw("|");
}else if(hasSnakeNode(row,column)){
printw("[]");
}else{
printw(" ");
}
}
printw("\n");
}
}
}
void addNode(){
Snake *newNode = (Snake *)malloc(sizeof(Snake));
newNode->next = NULL;
switch(direction){
case UP:
newNode->row = tail->row - 1;
newNode->column = tail->column;
break;
case DOWN:
newNode->row = tail->row + 1;
newNode->column = tail->column;
break;
case LEFT:
newNode->row = tail->row;
newNode->column = tail->column - 1;
break;
case RIGHT:
newNode->row = tail->row;
newNode->column = tail->column + 1;
break;
}
tail->next = newNode;
tail = newNode;
}
void initSnake(){
Snake *p = NULL;
direction = RIGHT;
while(head != NULL){
p = head;
head = head->next;
free(p);
}
head = (Snake *)malloc(sizeof(Snake));
head->row = 2;
head->column = 2;
head->next = NULL;
tail = head;
addNode();
addNode();
addNode();
}
void deleteNode(){
Snake *node = head;
head = head->next;
free(node);
}
void moveRight(){
addNode();
deleteNode();
if(tail->row == 0 || tail->row == 20 || tail->column == 0 || tail->column == 20){
initSnake();
}
}
void refreshPic(){
while(1){
moveRight();
gamePic();
refresh();
usleep(100000);
}
}
void changeDir(){
int key;
while(1){
key = getch();
switch(key){
case KEY_DOWN:
direction = DOWN;
break;
case KEY_UP:
direction = UP;
break;
case KEY_LEFT:
direction = LEFT;
break;
case KEY_RIGHT:
direction = RIGHT;
break;
}
}
}
int main()
{
initNcurse();
initSnake();
gamePic();
pthread_t th1;
pthread_t th2;
pthread_create(&th1,NULL,refreshPic,NULL);
pthread_create(&th2,NULL,changeDir,NULL);
while(1);
getch();
endwin();
return 0;
}
用绝对值方式解决不合理走位
蛇能转向的根本是尾部朝不同方向添加新节点,头部删除节点
要让蛇方向改变的同时朝相应的方向自动移动,实时接收方向变化的指令->写在死循环里,自动移动->不断移动->写在死循环里,同时执行->开启2个线程
//实时改变方向
//按不同方向改变添加节点的坐标
//刷新画面让蛇不停移动
//开启2个线程分别执行变方向和刷新画面
#include <curses.h>
#include <stdlib.h>
#include <pthread.h>
# define UP 1
# define DOWN -1
# define LEFT 2
# define RIGHT -2
typedef struct Snake{
int row;
int column;
struct Snake *next;
}Snake;
Snake *head = NULL;
Snake *tail = NULL;
int direction;
void initNcurse(){
initscr();
keypad(stdscr,1);
noecho();
}
int hasSnakeNode(int row,int column){
Snake *p = head;
while(p != NULL){
if(p->row == row && p->column == column){
return 1;
}
p = p->next;
}
return 0;
}
void gamePic(){
int row;
int column;
move(0,0);
for(row=0;row<20;row++){
if(row == 0 || row == 19){
for(column=0;column<20;column++){
printw("--");
}
printw("\n");
}
if(row>0 && row<19){
for(column=0;column<=20;column++){
if(column==0 || column==20){
printw("|");
}else if(hasSnakeNode(row,column)){
printw("[]");
}else{
printw(" ");
}
}
printw("\n");
}
}
}
void addNode(){
Snake *newNode = (Snake *)malloc(sizeof(Snake));
newNode->next = NULL;
switch(direction){
case UP:
newNode->row = tail->row - 1;
newNode->column = tail->column;
break;
case DOWN:
newNode->row = tail->row + 1;
newNode->column = tail->column;
break;
case LEFT:
newNode->row = tail->row;
newNode->column = tail->column - 1;
break;
case RIGHT:
newNode->row = tail->row;
newNode->column = tail->column + 1;
break;
}
tail->next = newNode;
tail = newNode;
}
void initSnake(){
Snake *p = NULL;
direction = RIGHT;
while(head != NULL){
p = head;
head = head->next;
free(p);
}
head = (Snake *)malloc(sizeof(Snake));
head->row = 2;
head->column = 2;
head->next = NULL;
tail = head;
addNode();
addNode();
addNode();
}
void deleteNode(){
Snake *node = head;
head = head->next;
free(node);
}
void moveRight(){
addNode();
deleteNode();
if(tail->row == 0 || tail->row == 20 || tail->column == 0 || tail->column == 20){
initSnake();
}
}
void refreshPic(){
while(1){
moveRight();
gamePic();
refresh();
usleep(100000);
}
}
void turn(int newDirection){
if(abs(direction) != abs(newDirection)){
direction = newDirection;
}
}
void changeDir(){
int key;
while(1){
key = getch();
switch(key){
case KEY_DOWN:
turn(DOWN);
break;
case KEY_UP:
turn(UP);
break;
case KEY_LEFT:
turn(LEFT);
break;
case KEY_RIGHT:
turn(RIGHT);
break;
}
}
}
int main()
{
initNcurse();
initSnake();
gamePic();
pthread_t th1;
pthread_t th2;
pthread_create(&th1,NULL,refreshPic,NULL);
pthread_create(&th2,NULL,changeDir,NULL);
while(1);
getch();
endwin();
return 0;
}
做贪吃蛇的食物
初步实现
//随机定义食物位置
//画食物
//蛇移动吃食物就随机产生下一个
#include <curses.h>
#include <stdlib.h>
#include <pthread.h>
# define UP 1
# define DOWN -1
# define LEFT 2
# define RIGHT -2
typedef struct Snake{
int row;
int column;
struct Snake *next;
}Snake;
Snake *head = NULL;
Snake *tail = NULL;
int direction;
Snake food;
void initFood(){
static int x = 4;
static int y = 5;
food.row = x;
food.column = y;
x+=2;
y+=2;
}
void initNcurse(){
initscr();
keypad(stdscr,1);
noecho();
}
int hasSnakeNode(int row,int column){
Snake *p = head;
while(p != NULL){
if(p->row == row && p->column == column){
return 1;
}
p = p->next;
}
return 0;
}
int hasFood(int row,int column){
if(food.row == row && food.column == column){
return 1;
}
return 0;
}
void gamePic(){
int row;
int column;
move(0,0);
for(row=0;row<20;row++){
if(row == 0 || row == 19){
for(column=0;column<20;column++){
printw("--");
}
printw("\n");
}
if(row>0 && row<19){
for(column=0;column<=20;column++){
if(column==0 || column==20){
printw("|");
}else if(hasSnakeNode(row,column)){
printw("[]");
}else if(hasFood(row,column)){
printw("##");
}else{
printw(" ");
}
}
printw("\n");
}
}
}
void addNode(){
Snake *newNode = (Snake *)malloc(sizeof(Snake));
newNode->next = NULL;
switch(direction){
case UP:
newNode->row = tail->row - 1;
newNode->column = tail->column;
break;
case DOWN:
newNode->row = tail->row + 1;
newNode->column = tail->column;
break;
case LEFT:
newNode->row = tail->row;
newNode->column = tail->column - 1;
break;
case RIGHT:
newNode->row = tail->row;
newNode->column = tail->column + 1;
break;
}
tail->next = newNode;
tail = newNode;
}
void initSnake(){
Snake *p = NULL;
direction = RIGHT;
while(head != NULL){
p = head;
head = head->next;
free(p);
}
initFood();
head = (Snake *)malloc(sizeof(Snake));
head->row = 2;
head->column = 2;
head->next = NULL;
tail = head;
addNode();
addNode();
addNode();
}
void deleteNode(){
Snake *node = head;
head = head->next;
free(node);
}
void moveRight(){
addNode();
if(hasFood(tail->row,tail->column){
initFood();
}else{
deleteNode();
}
if(tail->row == 0 || tail->row == 20 || tail->column == 0 || tail->column == 20){
initSnake();
}
}
void refreshPic(){
while(1){
moveRight();
gamePic();
refresh();
usleep(100000);
}
}
void turn(int newDirection){
if(abs(direction) != abs(newDirection)){
direction = newDirection;
}
}
void changeDir(){
int key;
while(1){
key = getch();
switch(key){
case KEY_DOWN:
turn(DOWN);
break;
case KEY_UP:
turn(UP);
break;
case KEY_LEFT:
turn(LEFT);
break;
case KEY_RIGHT:
turn(RIGHT);
break;
}
}
}
int main()
{
initNcurse();
initSnake();
gamePic();
pthread_t th1;
pthread_t th2;
pthread_create(&th1,NULL,refreshPic,NULL);
pthread_create(&th2,NULL,changeDir,NULL);
while(1);
getch();
endwin();
return 0;
}
吃掉食物让食物随机产生
#include <curses.h>
#include <stdlib.h>
#include <pthread.h>
# define UP 1
# define DOWN -1
# define LEFT 2
# define RIGHT -2
typedef struct Snake{
int row;
int column;
struct Snake *next;
}Snake;
Snake *head = NULL;
Snake *tail = NULL;
int direction;
Snake food;
void initFood(){
int x = rand()%20;
int y = rand()%20;
food.row = x;
food.column = y;
}
void initNcurse(){
initscr();
keypad(stdscr,1);
noecho();
}
int hasSnakeNode(int row,int column){
Snake *p = head;
while(p != NULL){
if(p->row == row && p->column == column){
return 1;
}
p = p->next;
}
return 0;
}
int hasFood(int row,int column){
if(food.row == row && food.column == column){
return 1;
}
return 0;
}
void gamePic(){
int row;
int column;
move(0,0);
for(row=0;row<20;row++){
if(row == 0 || row == 19){
for(column=0;column<20;column++){
printw("--");
}
printw("\n");
}
if(row>0 && row<19){
for(column=0;column<=20;column++){
if(column==0 || column==20){
printw("|");
}else if(hasSnakeNode(row,column)){
printw("[]");
}else if(hasFood(row,column)){
printw("##");
}else{
printw(" ");
}
}
printw("\n");
}
}
}
void addNode(){
Snake *newNode = (Snake *)malloc(sizeof(Snake));
newNode->next = NULL;
switch(direction){
case UP:
newNode->row = tail->row - 1;
newNode->column = tail->column;
break;
case DOWN:
newNode->row = tail->row + 1;
newNode->column = tail->column;
break;
case LEFT:
newNode->row = tail->row;
newNode->column = tail->column - 1;
break;
case RIGHT:
newNode->row = tail->row;
newNode->column = tail->column + 1;
break;
}
tail->next = newNode;
tail = newNode;
}
void initSnake(){
Snake *p = NULL;
direction = RIGHT;
while(head != NULL){
p = head;
head = head->next;
free(p);
}
initFood();
head = (Snake *)malloc(sizeof(Snake));
head->row = 2;
head->column = 2;
head->next = NULL;
tail = head;
addNode();
addNode();
addNode();
}
void deleteNode(){
Snake *node = head;
head = head->next;
free(node);
}
void moveRight(){
addNode();
if(hasFood(tail->row,tail->column){
initFood();
}else{
deleteNode();
}
if(tail->row == 0 || tail->row == 20 || tail->column == 0 || tail->column == 20){
initSnake();
}
}
void refreshPic(){
while(1){
moveRight();
gamePic();
refresh();
usleep(100000);
}
}
void turn(int newDirection){
if(abs(direction) != abs(newDirection)){
direction = newDirection;
}
}
void changeDir(){
int key;
while(1){
key = getch();
switch(key){
case KEY_DOWN:
turn(DOWN);
break;
case KEY_UP:
turn(UP);
break;
case KEY_LEFT:
turn(LEFT);
break;
case KEY_RIGHT:
turn(RIGHT);
break;
}
}
}
int main()
{
initNcurse();
initSnake();
gamePic();
pthread_t th1;
pthread_t th2;
pthread_create(&th1,NULL,refreshPic,NULL);
pthread_create(&th2,NULL,changeDir,NULL);
while(1);
getch();
endwin();
return 0;
}
修复贪吃蛇往上不到墙就死和咬不死自己的问题
//如果蛇撞到墙或咬到自己就初始化蛇身
#include <curses.h>
#include <stdlib.h>
#include <pthread.h>
# define UP 1
# define DOWN -1
# define LEFT 2
# define RIGHT -2
typedef struct Snake{
int row;
int column;
struct Snake *next;
}Snake;
Snake *head = NULL;
Snake *tail = NULL;
int direction;
Snake food;
void initFood(){
int x = rand()%20;
int y = rand()%20;
food.row = x;
food.column = y;
}
void initNcurse(){
initscr();
keypad(stdscr,1);
noecho();
}
int hasSnakeNode(int row,int column){
Snake *p = head;
while(p != NULL){
if(p->row == row && p->column == column){
return 1;
}
p = p->next;
}
return 0;
}
int hasFood(int row,int column){
if(food.row == row && food.column == column){
return 1;
}
return 0;
}
void gamePic(){
int row;
int column;
move(0,0);
for(row=0;row<20;row++){
if(row == 0 || row == 19){
for(column=0;column<20;column++){
printw("--");
}
printw("\n");
}
if(row>0 && row<19){
for(column=0;column<=20;column++){
if(column==0 || column==20){
printw("|");
}else if(hasSnakeNode(row,column)){
printw("[]");
}else if(hasFood(row,column)){
printw("##");
}else{
printw(" ");
}
}
printw("\n");
}
}
}
void addNode(){
Snake *newNode = (Snake *)malloc(sizeof(Snake));
newNode->next = NULL;
switch(direction){
case UP:
newNode->row = tail->row - 1;
newNode->column = tail->column;
break;
case DOWN:
newNode->row = tail->row + 1;
newNode->column = tail->column;
break;
case LEFT:
newNode->row = tail->row;
newNode->column = tail->column - 1;
break;
case RIGHT:
newNode->row = tail->row;
newNode->column = tail->column + 1;
break;
}
tail->next = newNode;
tail = newNode;
}
void initSnake(){
Snake *p = NULL;
direction = RIGHT;
while(head != NULL){
p = head;
head = head->next;
free(p);
}
initFood();
head = (Snake *)malloc(sizeof(Snake));
head->row = 2;
head->column = 2;
head->next = NULL;
tail = head;
addNode();
addNode();
addNode();
}
void deleteNode(){
Snake *node = head;
head = head->next;
free(node);
}
int ifSnakeDie(){
Snake *node = head;
if(tail->row < 0 || tail->row == 20 || tail->column == 0 || tail->column == 20){
return 1;
}
while(node->next != NULL){
if(node->row == tail->row && node->column == tail->column){
return 1;
}
node = node->next;
}
}
void moveRight(){
addNode();
if(hasFood(tail->row,tail->column){
initFood();
}else{
deleteNode();
}
if(ifSnakeDie()){
initSnake();
}
}
void refreshPic(){
while(1){
moveRight();
gamePic();
refresh();
usleep(100000);
}
}
void turn(int newDirection){
if(abs(direction) != abs(newDirection)){
direction = newDirection;
}
}
void changeDir(){
int key;
while(1){
key = getch();
switch(key){
case KEY_DOWN:
turn(DOWN);
break;
case KEY_UP:
turn(UP);
break;
case KEY_LEFT:
turn(LEFT);
break;
case KEY_RIGHT:
turn(RIGHT);
break;
}
}
}
int main()
{
initNcurse();
initSnake();
gamePic();
pthread_t th1;
pthread_t th2;
pthread_create(&th1,NULL,refreshPic,NULL);
pthread_create(&th2,NULL,changeDir,NULL);
while(1);
getch();
endwin();
return 0;
}
完整贪吃蛇思路
简洁版:
//初始化nurse
//画地图
//初始化画蛇身
//开启2个线程分别实时变向和根据方向自动移动
//初始化随机位置食物
//蛇吃食物就产生下一个随机食物并且变长
//蛇撞墙或咬到自己就重新开始
详细版:
//初始化ncurse
//画地图
//定义蛇身
//初始化蛇身
//添加蛇身
//画蛇身
//判断按键如果向右
//蛇向右移动
注意在画图的方法中添加move(0,0);
如果蛇的坐标到了墙的地方就初始化蛇
去掉按键判断,将向右移动放在死循环中每隔一段时间刷新一次
//实时改变方向
//按不同方向改变添加节点的坐标
//刷新画面让蛇不停移动
//开启2个线程分别执行变方向和刷新画面
//随机定义食物位置
//画食物
//蛇移动吃食物就随机产生下一个
//如果蛇撞到墙或咬到自己就初始化蛇身