play snake on windows

今天和人吃晚饭突然想起来

之前西佳佳老师说小学期会要求两星期撸一个小游戏

有人已经撸完一个俄罗斯方块了...

菜逼我决定从最简单的贪吃蛇玩起...

我是直接参考的这个博客

算是相当简单而且很Low的实现了

在我看来

 

开始和结束界面不是重点

自己随意设计一下吧

 

然后贪吃蛇的活动问题

由定时清屏再输出字符矩阵来解决

果实位置当然由随机数获得

 

定时问题直接用ctime函数来计算

这里的开始界面也用到了

清屏再输出的方式进行了倒计时

 

对蛇身的记录可以使用双端队列deque

操作不是很多也可以手写

 

获取键盘读入的问题

可以用键盘扫描码来解决

上下左右分别为72 80 75 77

_kbhit()函数判断是否有键盘输入

默认除“上下左右”以外的输入直接导致游戏结束

另一个可行的方案就是使用WASD来控制方向

就不必使用键盘扫描码了

 

然后代码里虽然同时使用了getch 和 _getch

但其实这似乎只是不同库里的功能一样的函数...

 

最后放上相当简陋的代码(我好懒就没写注释)

  1 #include<ctime>
  2 #include<cstdio>
  3 #include<conio.h>
  4 #include<cstdlib>
  5 
  6 #define map(pos) map[pos.x][pos.y]
  7 
  8 char map[30][30];
  9 
 10 struct point {
 11     int x, y;
 12     
 13     void _rand() {
 14         x = rand() % 20 + 1;
 15         y = rand() % 20 + 1;
 16     }
 17     
 18     bool operator == (const point &a) const {
 19         return x == a.x && y == a.y;
 20     } 
 21     
 22 };
 23 
 24 int head, tail;
 25 point snake[500], food, next;
 26 int dir, grade, length, uptime;
 27 
 28 inline void find_food() {
 29     do {
 30         food._rand();
 31     }while(map(food) != ' ');
 32     map(food) = '*';
 33 }
 34 
 35 inline void update() {
 36     system("cls");
 37     puts("");
 38     for(int i = 0;i < 22;i ++) {
 39         putchar('\t');
 40         for(int j = 0;j < 22;j ++)
 41             putchar(map[i][j]), putchar(' ');
 42         if(i == 0) printf("\t等级为:%d", grade);
 43         if(i == 2) printf("\t长度为:%d", length);
 44         if(i == 6) printf("\t自动前进时间");
 45         if(i == 8) printf("\t间隔为:%d ms", uptime);
 46         puts("");
 47     }
 48 }
 49 
 50 inline bool GO() {
 51     bool timeover = 1;
 52     double start = (double) clock() / CLOCKS_PER_SEC;
 53     while((timeover = (double) clock() / CLOCKS_PER_SEC <= start + uptime / 1000.0) && !_CRTIMP::_kbhit());
 54     if(timeover) {
 55         _getch();
 56         dir = _getch();
 57     }
 58     next = snake[head];
 59     switch (dir) {
 60         case 72:next.x -= 1;break;
 61         case 80:next.x += 1;break;
 62         case 75:next.y -= 1;break;
 63         case 77:next.y += 1;break;
 64         default:
 65             puts("\tGame over!");
 66             return 0;
 67     }
 68     if(!next.x || next.x == 21 || !next.y || next.y == 21) {
 69         puts("\tGame over!");
 70         return 0;
 71     }
 72     if(map(next) != ' ' && !(next == food)) {
 73         puts("\tGame over!");
 74         return 0;
 75     }
 76     if(length == 400) {
 77         puts("\tGood game!");
 78         return 0;
 79     }
 80     return 1;
 81 }
 82 
 83 int main() {
 84     srand(19980320);
 85     for(int i = 1;i <= 20;i ++)
 86         for(int j = 1;j <= 20;j ++)
 87             map[i][j] = ' ';
 88     for(int i = 0;i < 22;i ++)
 89         map[i][0] = map[21][i] = map[0][i] = map[i][21] = '!';
 90     map[1][1] = map[1][2] = 'o', map[1][3] = '@';
 91     snake[0] = (point){1, 1};
 92     snake[1] = (point){1, 2};
 93     snake[2] = (point){1, 3};
 94     head = 2, tail = 0, grade = 1, length = 3, uptime = 500;
 95     find_food(), dir = 77;
 96     
 97     puts("\n\n\n\t\t\t即将开始玩蛇!");
 98     double start;
 99     for(int i = 3;i >= 0;i --) {
100         start = (double)clock() / CLOCKS_PER_SEC;
101         while((double)clock() / CLOCKS_PER_SEC <= start + 1);
102         if(i > 0) {
103             system("cls");
104             printf("\n\n\n\t\t\t进入倒计时:%d\n", i);
105         }
106         else {
107             update();
108         }
109     }
110     
111     while(1) {
112         if(GO()) {
113             if(next == food) {
114                 length ++;
115                 if(length % 10 == 0) {
116                     grade ++;
117                     if(uptime >= 100) uptime -= 50; 
118                 }
119                 map(next) = '@';
120                 map(snake[head]) = 'o';
121                 head = (head + 1) % 500;
122                 snake[head] = next;
123                 find_food(), update();
124             }
125             else {
126                 map(snake[tail]) = ' ';
127                 tail = (tail + 1) % 500;
128                 map(next)  = '@';
129                 map(snake[head]) = 'o';
130                 head = (head + 1) % 500;
131                 snake[head] = next;
132                 update();
133             }
134         }
135         else break;
136     }
137     getch();
138     return 0;
139 }

 

没有使用图形

开始界面还能接受

结束界面没有再来一局的提示

也没有最终分数的显示

有待改进

 

另外想写一个自动玩这个游戏的程序

不考虑最短路径的话

在nm不全为奇数的情况下是有必胜策略的

而这是比较好实现的

但还要考虑一下怎么把它自己玩的过程展现出来?

直接把游戏代码嵌入进去?那岂不是很蠢?

 

而考虑同等分数下的最少按键次数或最少移动次数呢?

似乎可以尝试用机器学习的方法来搞一搞?

都忘记到底是深度学习还是强化学习了...

但这似乎可能又与随机出来的果实位置有关?

机器学习的话,可以直接尝试让它自己学着玩这个游戏?

......

看上去比上一个想法更有实现的意义?

 

先到此为止

posted @ 2017-06-05 20:42  ztztyyy  阅读(287)  评论(0编辑  收藏  举报