當前位置: 華文星空 > 知識

用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,寫程式碼也不容易