Linux下控制台版贪吃蛇
2015-06-20 17:17
537 查看
学了些Uinux C的知识,一时兴起而做,基本功能实现后又懒得休憩,因此美观方面也就很将就了,也没大量测试,应该也有不少BUG,仅当学习所用了。也是一种总结
设计思路:
1. 蛇体主要以结构体形式实现
2. 用计时器来在规定时间间隔内不断激发SIGALRM信号,再自定义函数来控制蛇体不断移动
难点:
1. 获取键盘命令
2. 使蛇体不断移动
缺点:
1. 界面粗糙
2. 代码繁杂,冗余。感觉很多可以更为简练。
3. 逻辑设计不够清晰,代码应用不够灵活
4. 码部分代码时候输入法有问题,注释用英文,太烂,语法错误多多,懒得改
游戏界面:
游戏说明:
'w' 's' 'a' 'd'分别控制上下左右
‘q'为退出 'length‘表示蛇的长度 level表示等级,等级越高,移动速度越快
————————————————————————————————
多文件-代码:
头文件:
main 函数:
界面文件:
初始化、收尾及判断函数:
蛇体移动:
设计思路:
1. 蛇体主要以结构体形式实现
2. 用计时器来在规定时间间隔内不断激发SIGALRM信号,再自定义函数来控制蛇体不断移动
难点:
1. 获取键盘命令
2. 使蛇体不断移动
缺点:
1. 界面粗糙
2. 代码繁杂,冗余。感觉很多可以更为简练。
3. 逻辑设计不够清晰,代码应用不够灵活
4. 码部分代码时候输入法有问题,注释用英文,太烂,语法错误多多,懒得改
游戏界面:
游戏说明:
'w' 's' 'a' 'd'分别控制上下左右
‘q'为退出 'length‘表示蛇的长度 level表示等级,等级越高,移动速度越快
————————————————————————————————
多文件-代码:
头文件:
#ifndef __SNAKE_H_ #define __SNAKE_H_ #include <stdio.h> #include <stdlib.h> #include <signal.h> #define S_FOOD -1 #define S_NONT 0 #define S_HEAD 1 #define S_BODY 2 #define S_TAIL 3 //define coordinate typedef struct { int x; int y; }Coord; //define snake typedef struct node { int x; int y; struct node *next; }Snake; extern Snake *head, *tail; extern Coord food; extern int arr[100][100]; extern int row, col; extern Coord dirct; extern int s_len; extern int level; //创建蛇的节点 Snake *crt_snake(void); //初始化 void init_set(void); //打印界面 void print_show(void); //蛇体移动 void s_move(void); //键盘获取命令 void init_ter(int mode); //投放食物 void set_food(void); //判断游戏是否结束 void judge(void); //创建计时器 void set_itime(void); #endif // __SNAKE_H_
main 函数:
#include "snake.h" int main(void) { init_set(); set_itime(); get_order(); return 0; }
界面文件:
#include "snake.h" //just print a line void print_line(void) { int i = 0; for (i =0; i <col +2; i++) { printf("- "); } printf("\n"); } //print the interface void print_show(void) { system("clear"); int i = 0, j = 0; printf("\n \e[34mlevel: %d\e[m\n", level); print_line(); for (i =0; i <row; i++) { printf("| "); for (j =0; j <col; j++) { if (S_NONT == arr[i][j]) { printf(" "); } else if (S_BODY == arr[i][j]) { printf("* "); } else if (S_HEAD == arr[i][j]) { printf("+ "); } else if (S_TAIL == arr[i][j]) { printf("- "); } else { printf("$ "); } } printf(" |\n"); } print_line(); printf("Quit: 'Q' length:%d\n", s_len); }
初始化、收尾及判断函数:
// initialize all kinds of set #include "snake.h" #include <time.h> #include <sys/time.h> #include <termios.h> #include <unistd.h> //define arr for printing the interface int arr[100][100]; //define the head and tail of snake Snake *head, *tail; //define the food by Coord struct Coord food; int row, col; //record the snake length int s_len; //set the level of the game int level; void init_ter(int mode) { static struct termios old; if (1 == mode) { tcgetattr(0, &old); // 获取之前属性 struct termios new = old; //临时修改属性 new.c_lflag &= ~ICANON; //开启非标准模式 new.c_lflag &= ~ECHO; // 屏蔽回显 new.c_cc[VMIN] = 0; // 立即接收 new.c_cc[VTIME] = 1; //受min影响 0秒 //把临时设置到标准输入0,改变标准输入的特征 tcsetattr(0, TCSANOW, &new); } if (0 == mode) { tcsetattr(0, TCSANOW, &old); } } void judge(void) { //胜利的判断 if (s_len == (row * col / 2)) { printf("GREAT! YOU WIN!\n"); exit(0); } //撞边框失败,碰到自身的判断在s_move函数 if (head->x >= row || head->x <0 || head->y >= col || head->y <0) { printf("YOU LOSE \n"); exit(0); } } //when receive the signal of alarm void fa(int signo) { static cnt = 0; cnt++; s_move(); judge(); print_show(); if (0 == cnt % 60 && level < 10) { level++; set_itime(); } // printf("(%d,%d)\n", dirct.x, dirct.y); } //create snake node Snake *crt_snake(void) { Snake *p = (Snake *)malloc(sizeof(Snake)); p->x = 0; p->y = 0; p->next = NULL; return p; } //set food for snake void set_food(void) { srand((unsigned)time(0)); while(1) { food.x = rand() % row; food.y = rand() % col; if (!arr[food.x][food.y]) { arr[food.x][food.y] = S_FOOD; break; } } } //当结束时执行的函数,释放内存 void destroy(void) { init_ter(0); if (tail == NULL) { return; } while (tail != NULL) { Snake *p = tail; tail = tail->next; free(p); p = NULL; } } //set the interval timer void set_itime(void) { struct itimerval it; it.it_interval.tv_sec = 0; it.it_interval.tv_usec = 999999 / level; it.it_value.tv_sec = 1; it.it_value.tv_usec = 0; int res = setitimer(ITIMER_REAL, &it, NULL); if(-1 == res) { perror("settimer"), exit(-1); } } //initialize the interface and snake void init_set(void) { atexit(destroy); printf("please input the size of the face\n"); while((2 != scanf("%d%d", &row, &col)) || row <5 || col <5 || row >100 || col >100) { printf("incorrect input, input again!\n"); scanf("%*[\n]"); scanf("%*c"); } //init the snake, make it in centre head = crt_snake(); tail = crt_snake(); head->x = row / 2; head->y = col /2; head->next = NULL; tail->x = head->x -1; tail->y = head->y; tail->next = head; arr[head->x][head->y] = S_HEAD; arr[tail->x][tail->y] = S_TAIL; set_food(); //active the function fa when the recive the sigalrm form itimer signal(SIGALRM, fa); // snake length of starting s_len = 2; level = 1; }
蛇体移动:
#include "snake.h" //初始化移动方向 Coord dirct = {1, 0}; //获取键盘移动命令 void get_order(void) { char ch = 0; init_ter(1); while (1) { read(0, &ch, 1); switch(ch) { case 'w': case 'W': if (dirct.x != 1) { dirct.x = -1; dirct.y = 0; } break; case 's': case 'S': if (dirct.x != -1) { dirct.x = 1; dirct.y = 0; } break; case 'a': case 'A': if (dirct.y != 1) { dirct.x = 0; dirct.y = -1; } break; case 'd': case 'D': if (dirct.y != -1) { dirct.x = 0; dirct.y = 1; } break; case 'q': case 'Q': exit(0); default: break; } } } //蛇体移动 void s_move(void) { //定义两坐标暂存蛇头、蛇尾坐标 Coord co_h, co_t; co_h.x = head->x; co_h.y = head->y; co_t.x = tail->x; co_t.y = tail->y; //吃到食物情况 if ((food.x == head->x + dirct.x ) && (food.y == head->y + dirct.y)) { Snake *ps = crt_snake(); ps->x = food.x; ps->y = food.y; head->next = ps; head = ps; arr[head->x][head->y] = S_HEAD; arr[co_h.x][co_h.y] = S_BODY; //蛇体长度加1 s_len++; set_food(); } else { Snake *ps = tail; while (ps->next != NULL) { ps->x = ps->next->x; ps->y = ps->next->y; ps = ps->next; } head->x += dirct.x; head->y += dirct.y; //是否碰到蛇身的判断 if (S_BODY == arr[head->x][head->y] || S_TAIL == arr[head->x][head->y]) { printf("YOU LOSE\n"); exit(0); } arr[head->x][head->y] = S_HEAD; arr[co_h.x][co_h.y] = S_BODY; arr[tail->x][tail->y] = S_TAIL; arr[co_t.x][co_t.y] = S_NONT; } }
相关文章推荐
- Linux笔记(鸟哥的私房菜)
- bottle框架学习(三)之模版的使用
- Linux字符设备驱动(二)
- Linux中Kill进程的N种方法
- Linux驱动发开,usb设备的probe全过程
- Centos上的屏幕保护
- Linux查看CPU信息 (
- linux程序设计——MySQL管理(第八章)
- Win7安装CENTOS
- Hadoop集群(第1期)_CentOS安装配置
- linux安全策略!
- LAMP环境搭建
- linux账号管理及相关命令和操作
- linux 常见服务端口
- linux防止sshd被爆破(安装denyhosts)
- 傻瓜突破linux--rootpassword
- linux命令
- linux命令
- activemq安装和启动
- windows下如何远程连接Linux电脑