c语言第一个小游戏:贪吃蛇小游戏06

实现贪吃蛇四方向的风骚走位

实现代码

#include <curses.h>

#include <stdlib.h>

struct snake{

int hang;

int lie;

struct snake *next;

};

struct snake *head;

struct snake *tail;

int key;

int dir; //全局变量

#define UP 1 //这个是宏定义,主要就是让人更好理解 ,也为了后期的方向做了铺垫

#define DOWN -1

#define LEFT 2

#define RIGHT -2

void initNcurse()

{

initscr();

keypad(stdscr,1);

noecho();

}

int hasSnakeNode(int i,int j)

{

struct snake *p;

p = head;

while(p != NULL){

if(p->hang==i && p->lie==j){

return 1;

}

p=p->next;

}

return 0;

}

void gamepic()

{

int hang;

int lie;

move(0,0);

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 if(hasSnakeNode(hang,lie)){

printw("[]");

}

else{

printw(" ");

}

}

printw("\n");

}

if(hang == 19){

for(lie=0;lie<20;lie++){

printw("--");

}

printw("\n");

}

}

printw("by shijintao\n");

printw("key =%d\n",key);

}

void addNode()

{

struct snake *new;

new =(struct snake *)malloc(sizeof(struct snake));

new->next=NULL;

switch(dir){

case UP:

new->hang=tail->hang-1;

new->lie=tail->lie;

tail->next=new;

tail = new;

break;

case DOWN:

new->hang=tail->hang+1;

new->lie=tail->lie;

tail->next=new;

tail = new;

break;

case LEFT:

new->lie=tail->lie-1;

new->hang=tail->hang;

tail->next=new;

tail = new;

break;

case RIGHT:

new->lie=tail->lie+1;

new->hang=tail->hang;

tail->next=new;

tail = new;

break;

}

}

当为dir为up的时候 hang变,lie不变

当为dir为down的时候 hang变,lie不变

当为dir为left的时候 lie变,hang不变

当为dir为right的时候 lie变,hang不变

void initSnake()

{

struct snake *p;

dir = RIGHT; //这边我们设置了一个初始方向 dir是全局变量

while(head != NULL){

p=head;

head=head->next;

free(p);

}

head = (struct snake *)malloc(sizeof(struct snake));

head->hang=2;

head->lie=2;

head->next=NULL;

tail = head;

addNode();

addNode();

}

void deleteNode()

{

struct snake *p;

p = head;

head = head->next;

free(p);

}

void moveSnake()

{

addNode();

deleteNode();

if(tail->hang==0||tail->hang==20||tail->lie==20||tail->lie==0){

initSnake();

}

}

void * changeDir()

{

while(1){

key =getch();

switch(key){ //这个key是全局变量 会通过changeDir函数改变

case KEY_DOWN:

dir = DOWN; //这个DOWN是通过宏定义定义的

break;

case KEY_UP:

dir = UP;

break;

case KEY_RIGHT:

dir = RIGHT;

break;

case KEY_LEFT:

dir = LEFT;

break;

}

}

}

void * gamerefresh()

{

while(1){

moveSnake();

gamepic();

refresh();

usleep(100000);

}

}

int main()

{

pthread_t th1;

pthread_t th2;

initNcurse();

initSnake();

gamepic();

pthread_create(&th2,NULL,gamerefresh,NULL);

pthread_create(&th1,NULL,changeDir,NULL);

while(1);//死循环不能让主线程退出,这样就可以一直玩游戏了

getch();

endwin();

return 0;

}

优化代码(方向相反不能直接走)

#include <curses.h>

#include <stdlib.h>

struct snake{

int hang;

int lie;

struct snake *next;

};

struct snake *head;

struct snake *tail;

int key;

int dir;

#define UP 1

#define DOWN -1

#define LEFT 2

#define RIGHT -2

void initNcurse()

{

initscr();

keypad(stdscr,1);

noecho(); //这个就是ncurse的按键盘的时候会弹出来乱七八糟的符号,输入这个就可以去掉,不然地图很奇怪,很多乱七八糟的符号

}

int hasSnakeNode(int i,int j)

{

struct snake *p;

p = head;

while(p != NULL){

if(p->hang==i && p->lie==j){

return 1;

}

p=p->next;

}

return 0;

}

void gamepic()

{

int hang;

int lie;

move(0,0);

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 if(hasSnakeNode(hang,lie)){

printw("[]");

}

else{

printw(" ");

}

}

printw("\n");

}

if(hang == 19){

for(lie=0;lie<20;lie++){

printw("--");

}

printw("\n");

}

}

printw("by shijintao\n");

printw("key =%d\n",key);

}

void addNode()

{

struct snake *new;

new =(struct snake *)malloc(sizeof(struct snake));

new->next=NULL;

switch(dir){

case UP:

new->hang=tail->hang-1;

new->lie=tail->lie;

tail->next=new;

tail = new;

break;

case DOWN:

new->hang=tail->hang+1;

new->lie=tail->lie;

tail->next=new;

tail = new;

break;

case LEFT:

new->lie=tail->lie-1;

new->hang=tail->hang;

tail->next=new;

tail = new;

break;

case RIGHT:

new->lie=tail->lie+1;

new->hang=tail->hang;

tail->next=new;

tail = new;

break;

}

}

void initSnake()

{

struct snake *p;

while(head != NULL){

p=head;

head=head->next;

free(p);

}

head = (struct snake *)malloc(sizeof(struct snake));

dir = RIGHT;

head->hang=2;

head->lie=2;

head->next=NULL;

tail = head;

addNode();

addNode();

}

void deleteNode()

{

struct snake *p;

p = head;

head = head->next;

free(p);

}

void moveSnake()

{

addNode();

deleteNode();

if(tail->hang==0||tail->hang==20||tail->lie==20||tail->lie==0){

initSnake();

}

}

void turn(int direction)

{

if(abs(dir) != abs(direction)){

dir = direction;

}

}

//这段代码就是更改贪吃蛇不能相反移动的核心了,利用abs绝对值的方法,这个direction是新的方向,这个dir是旧方向 ,在这边我们设置左右上下的值互为相反数,如果他们的绝对值相等的话,那我们就不把新方向替代旧方向,说白了我白说了,只要绝对值相等,那么就不会换方向,只要绝对值不相等,就换方向,这个值取决于你在宏定义里面的设置,就像下面的一样

//#define UP 1

//#define DOWN -1

//#define LEFT 2

//#define RIGHT -2

void * changeDir()

{

while(1){

key =getch();

switch(key){

case KEY_DOWN:

turn(DOWN);

break;

case KEY_UP:

turn(UP);

break;

case KEY_RIGHT:

turn(RIGHT);

break;

case KEY_LEFT:

turn(LEFT);

break;

}

}

}

void * gamerefresh()

{

while(1){

moveSnake();

gamepic();

refresh();

usleep(100000);

}

}

int main()

{

pthread_t th1;

pthread_t th2;

initNcurse();

initSnake();

gamepic();

pthread_create(&th2,NULL,gamerefresh,NULL);

pthread_create(&th1,NULL,changeDir,NULL);

while(1);

getch();

endwin();

return 0;

}

相关推荐
June`22 分钟前
专题三:穷举vs暴搜vs深搜vs回溯vs剪枝(全排列)决策树与递归实现详解
c++·算法·深度优先·剪枝
vlln29 分钟前
适应性神经树:当深度学习遇上决策树的“生长法则”
人工智能·深度学习·算法·决策树·机器学习
我叫珂蛋儿吖1 小时前
[redis进阶六]详解redis作为缓存&&分布式锁
运维·c语言·数据库·c++·redis·分布式·缓存
冲帕Chompa1 小时前
图论part09dijkstra算法
算法·图论
·云扬·1 小时前
【PmHub后端篇】PmHub中基于Redis加Lua脚本的计数器算法限流实现
redis·算法·lua
周Echo周2 小时前
20、map和set、unordered_map、un_ordered_set的复现
c语言·开发语言·数据结构·c++·算法·leetcode·list
zkmall2 小时前
推荐算法工程化:ZKmall模板商城的B2C 商城的用户分层推荐策略
算法·机器学习·推荐算法
安装虚拟机的老师傅2 小时前
【2025最新】Windows系统装VSCode搭建C/C++开发环境(附带所有安装包)
c语言·windows·vscode·其他
矿渣渣2 小时前
AFFS2 的 `yaffs_ext_tags` 数据结构详解
数据结构·算法·文件系统·yaffs2
workflower2 小时前
使用谱聚类将相似度矩阵分为2类
人工智能·深度学习·算法·机器学习·设计模式·软件工程·软件需求