• 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('	');
     40         for(int j = 0;j < 22;j ++)
     41             putchar(map[i][j]), putchar(' ');
     42         if(i == 0) printf("	等级为:%d", grade);
     43         if(i == 2) printf("	长度为:%d", length);
     44         if(i == 6) printf("	自动前进时间");
     45         if(i == 8) printf("	间隔为:%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("	Game over!");
     66             return 0;
     67     }
     68     if(!next.x || next.x == 21 || !next.y || next.y == 21) {
     69         puts("	Game over!");
     70         return 0;
     71     }
     72     if(map(next) != ' ' && !(next == food)) {
     73         puts("	Game over!");
     74         return 0;
     75     }
     76     if(length == 400) {
     77         puts("	Good 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("
    
    
    			即将开始玩蛇!");
     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("
    
    
    			进入倒计时:%d
    ", 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不全为奇数的情况下是有必胜策略的

    而这是比较好实现的

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

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

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

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

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

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

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

    ......

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

    先到此为止

  • 相关阅读:
    头信息已输出的报错信息位置定位
    阅读<php程序设计>笔记
    include、ruquire使用相对路径总结
    php中未定义的变量使用技巧
    Oracle官方教材(9i、10G及App 11i)
    Vista的软件兼容性
    轻松找回Vista序列号
    oralce定时执行存储过程任务设置步骤详细
    今天做了内存测试,发现真的是内存问题导致的一连串的问题
    网络邮盘(GMailStore) V3.0.2
  • 原文地址:https://www.cnblogs.com/ytytzzz/p/6946957.html
Copyright © 2020-2023  润新知