当前位置: 华文星空 > 知识

用C语言,能在100行之内实现贪吃蛇吗?

2019-12-13知识

这段代码会发生内存泄漏,特此备注。

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

没学到一个小小的贪吃蛇会有怎么多赞,当时想能有100个赞已经很不错了,这个完全超出我的预期啊,啊啊啊~飘了飘了~

小声bb:其实这个代码写得不咋地,有些函数为了能用 return 语句,故意写了一个返回值,但是返回值没有用到,还有就是 Run 这个函数本来不应该接受一个参数,但是为了省一行的代码,把init写进去,才出此下策。这样写的后果就是代码不符合我的预期,不这样写的话又不符合题主的要求,两难啊。所以我才会比较郁闷,说了点脏话,实在抱歉 。(可能自己水平不够,代码还有很多优化空间,我看别的答主根本就用不到100行)

继续努力吧 ~

~~~~~~~~~~~~原答案~~~~~~~~~~~

我本来怀着很好的心情来写这个100的贪吃蛇的,不过写到后面就出口成脏了。

mmp,写到后面很是郁闷。有图为证。

忍不住说脏话了

刚刚好一百行代码,我去,这是那我之前写的350多行代码压缩的得到的。

写得很垃圾,有些东西就是乱写一通,就为了压缩一两行逻辑代码。

然后UI部分,这个也没办法压缩,能压缩的都在核心代码上面了。

尽量体现出来格式,但是难受啊

贪吃蛇的核心代码就在这个switch里面了,10行。也就是占比 1/10。其实还可以...

最后的效果图是这个

按空格开始和暂停

直接贴代码吧。

#include <Windows.h> #include <stdio.h> #include <conio.h> #include <time.h> #define PANIC(err) (fprintf(stderr,"PANIC Line %d : %s",__LINE__,err),exit(-1),1) #define PANICIFNULL(EXP) ((EXP)==NULL && PANIC("NULL")) typedef enum { EMPTY = 0 , WALL , BODY , FOOD } MAP ; typedef int POSITION ; struct { int color ; const char * shape ; } UI [] = { { 2 , "■" },{ 4 , "□" },{ 6 , "★" },{ 4 , "●" } }; struct { int WIDTH , HEIGHT , direction , delay ; MAP * map ; POSITION * body , head , tail , len ; } C ; void initConsole ( int width , int height ) { char cmd [ 100 ]; sprintf_s ( cmd , 100 , "mode con cols=%d lines=%d && title C语言贪吃蛇 By dreamer2q %s" , width , height , __DATE__ ); system ( cmd ); HANDLE handle = GetStdHandle ( STD_OUTPUT_HANDLE ); CONSOLE_CURSOR_INFO cur_info ; GetConsoleCursorInfo ( handle , & cur_info ); cur_info . bVisible = FALSE ; SetConsoleCursorInfo ( handle , & cur_info ); } void updatePosition ( POSITION pos ) { HANDLE handle = GetStdHandle ( STD_OUTPUT_HANDLE ); COORD coord = { ( pos % ( C . WIDTH )) * 2 , pos / ( C . WIDTH ) }; SetConsoleCursorPosition ( handle , coord ); SetConsoleTextAttribute ( handle , UI [ C . map [ pos ]]. color ); printf ( "%s" , UI [ C . map [ pos ]]. shape ); } MAP food ( int t ) { POSITION pos = ( rand () % (( C . WIDTH - 2 ) * ( C . HEIGHT - 2 ))) + C . WIDTH + 1 ; if ( C . map [ pos ]) return food ( t ); else return ( C . map [ pos ] = FOOD ) ? updatePosition ( pos ), BODY : BODY ; } int init () { C . WIDTH = C . HEIGHT = 30 ; initConsole ( C . WIDTH * 2 , C . HEIGHT ); PANICIFNULL ( C . map = ( MAP * ) malloc (( C . WIDTH ) * ( C . HEIGHT ) * sizeof ( MAP ))); PANICIFNULL ( C . body = ( POSITION * ) malloc ( C . WIDTH * C . HEIGHT * sizeof ( POSITION ))); C . head = ( C . len = 3 ) - 1 ; C . direction = ( C . tail = 0 ) + 1 ; C . delay = - 150 ; memset ( C . map , EMPTY , ( C . WIDTH ) * ( C . HEIGHT ) * sizeof ( MAP )); for ( int i = 0 ; i < ( C . WIDTH ) * ( C . HEIGHT ); i ++ ) { i < C . WIDTH && ( C . map [ i ] = C . map [ C . WIDTH * ( C . HEIGHT - 1 ) + i ] = WALL ); i < C . HEIGHT && ( C . map [ C . WIDTH * i ] = C . map [ C . WIDTH * i + C . WIDTH - 1 ] = WALL ); i < C . len && ( C . map [ C . body [ i ] = C . WIDTH * C . HEIGHT / 2 + C . WIDTH / 2 - 1 + i ] = BODY ); updatePosition ( i ); } srand ( time ( NULL )); return food ( 0 ); } int Run ( int shit ) { int prv = 77 ; while ( 1 ) { if ( _kbhit ()) { int t = _getch (); if (( prv + t ) == 152 ) continue ; switch ( t ) { case 72 : C . direction = - C . WIDTH ; break ; case 80 : C . direction = C . WIDTH ; break ; case 75 : C . direction = - 1 ; break ; case 77 : C . direction = 1 ; break ; case ' ' : C . delay = - C . delay ; break ; default : continue ; } prv = t ; } #define INC(p) (((p)+1)%(C.WIDTH*C.HEIGHT)) if ( C . delay > 0 ) Sleep ( C . delay ); else continue ; switch ( C . map [ C . body [ INC ( C . head )] = C . body [ C . head ] + C . direction ]) { case FOOD : food ( C . len = - C . len - 1 ); case EMPTY : C . map [ C . body [ C . head = INC ( C . head )]] = BODY ; updatePosition ( C . body [ C . head ]); if ( C . len > 0 ) updatePosition (( C . map [ C . body [ C . tail ]] = EMPTY ) ? BODY : C . body [ C . tail ]), C . tail = INC ( C . tail ); else C . len = - C . len ; break ; case WALL : case BODY : return - 1 ; //dead } } } int main () { while ( 1 ) { initConsole ( 25 , 10 ); printf ( " \n\t C语言贪吃蛇 \n\n 1. 开始游戏 \n 2. 关于 \n q. 退出 \n %" ); switch ( _getch ()) { case 'q' : return 0 ; case '2' : MessageBoxA ( GetConsoleWindow (), "100行代码?" , "有病吧你?" , MB_OK | MB_ICONASTERISK ); continue ; case '1' : Run ( init ()); MessageBoxA ( GetConsoleWindow (), "你死了。有病去看看吧" , "SHIT" , MB_OK | MB_ICONERROR ); } } }

觉得还行就thumbup,写代码也不容易