c语言 俄罗斯方块源码
#include <windows.h> #include <stdio.h> #include <stdlib.h> #include <time.h> #include <conio.h> #include <stdbool.h> /* ¹ÜµÀ¾ä±úµÄ¶¨Òå */ HANDLE hStdOutput = INVALID_HANDLE_VALUE; HANDLE hStdError = INVALID_HANDLE_VALUE; const WORD COLOR_A = FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_INTENSITY; /* Ô˶¯ÖеÄÑÕÉ« */ const WORD COLOR_B = FOREGROUND_GREEN; /* ¹Ì¶¨²»¶¯µÄÑÕÉ« */ const WORD COLOR_C = FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE; /* ¿Õ°×´¦µÄÑÕÉ« */ bool voice = true; /* ±³¾°ÒôÀÖ */ int score = 0; /* µÃ·Ö */ int level = 0; /* µÈ¼¶ */ char data[19][11] = { 0 }; /* ÓÎÏ·´°¿ÚµÄ״̬ */ int next = -1; /* ¼Ç¼ÏÂÒ»¸öͼÐεÄËæ»úÐÅÏ¢ */ int x = 4, y = -2, c = -1, z = 0; /* x×ø±ê,×ø±ê,µ±Ç°·½¿é,·½Ïò */ /* ³ÌÐò¿ªÊ¼Îª¾ä±ú³õʼ»¯ */ bool Open( void ) { hStdOutput = GetStdHandle( STD_OUTPUT_HANDLE ); hStdError = GetStdHandle( STD_ERROR_HANDLE ); return INVALID_HANDLE_VALUE!=hStdOutput && INVALID_HANDLE_VALUE!=hStdError; } /* ÉèÖñêÌâ */ bool SetTitle( char* title ) { return TRUE==SetConsoleTitle(title); } /* È¥´¦¹â±ê */ bool RemoveCursor( void ) { CONSOLE_CURSOR_INFO cci; /* ¹â±êÐÅÏ¢ */ /* ±ê×¼Êä³ö¾ä±ú»ñÈ¡ÐÅÏ¢³ö´í¾Í·µ»Ø´íÎó */ if( !GetConsoleCursorInfo( hStdOutput, &cci ) ) { return false; } cci.bVisible = false; /* ±ê×¼Êä³ö¾ä±úÉèÖÃÐÅÏ¢³ö´í¾Í·µ»Ø´íÎó */ if( !SetConsoleCursorInfo( hStdOutput, &cci ) ) { return false; } /* ´íÎóÊä³ö¾ä±ú»ñÈ¡ÐÅÏ¢³ö´í¾Í·µ»Ø´íÎó */ if( !GetConsoleCursorInfo( hStdError, &cci ) ) { return false; } cci.bVisible = false; /* ´íÎóÊä³ö¾ä±úÉèÖÃÐÅÏ¢³ö´í¾Í·µ»Ø´íÎó */ if( !SetConsoleCursorInfo( hStdError, &cci ) ) { return false; } return true; } /* ÉèÖô°Ìå³ß´ç */ bool SetWindowRect( short x, short y ) { /* ¶¨ÒåÓÃÓÚÈ¡µÃconsole³ÌÐòµÄ´°¿Ú´óСµÄ½á¹¹ */ SMALL_RECT wrt = { 0, 0, x, y }; /* ±ê×¼Êä³öÉèÖÃʧ°Ü */ if( !SetConsoleWindowInfo( hStdOutput, TRUE, &wrt ) ) { return false; } /* ´íÎóÊä³öÉèÖÃʧ°Ü */ if( !SetConsoleWindowInfo( hStdError, TRUE, &wrt ) ) { return false; } return true; } /* ÉèÖûº³å³ß´ç */ bool SetBufSize( short x, short y ) { /* ¶¨ÒåÓÃÓÚ»ñÈ¡×ø±ê½á¹¹Ìå */ COORD coord = { x, y }; /* ÉèÖñê×¼Êä³öʧ°Ü */ if( !SetConsoleScreenBufferSize( hStdOutput, coord ) ) { return false; } /* ÉèÖôíÎóÊä³öʧ°Ü */ if( !SetConsoleScreenBufferSize( hStdError, coord ) ) { return false; } return true; } /* Òƶ¯¹â±ê */ bool GotoXY( short x, short y ) { /* ¶¨ÒåÓÃÓÚ»ñÈ¡×ø±ê½á¹¹Ìå */ COORD coord = { x, y }; /* ÉèÖñê×¼Êä³öÊó±êλÖÃʧ°Ü */ if( !SetConsoleCursorPosition( hStdOutput, coord ) ) { return false; } /* ÉèÖôíÎóÊä³öÊó±êλÖÃʧ°Ü */ if( !SetConsoleCursorPosition( hStdError, coord ) ) { return false; } return true; } /* ÉèÖÃÇ°¾°É«/±³¾°É« */ bool SetColor( WORD color ) { /* ±³¾°ÑÕÉ«±ê×¼Êä³öʧ°Ü */ if( !SetConsoleTextAttribute( hStdOutput, color ) ) { return false; } /* ±³¾°ÑÕÉ«´íÎóÊä³öʧ°Ü */ if( !SetConsoleTextAttribute( hStdError, color ) ) { return false; } return true; } /* Êä³ö×Ö·û´® */ bool OutputString( const char* pstr, size_t len ) { /* 32bit ÎÞ·ûºÅÕûÊý */ DWORD n = 0; /* Êä³öµ½¿ØÖÆ̨ */ return TRUE == WriteConsole( hStdOutput, pstr, len?len:strlen(pstr), &n, NULL ); } /* Êä³ö×Ö·û´® */ bool OutputStringNoMove( short x, short y, const char* pstr, size_t len) { /* ¶¨ÒåÓÃÓÚ»ñÈ¡×ø±ê½á¹¹Ìå */ COORD coord = { x, y }; /* 32bit ÎÞ·ûºÅÕûÊý */ DWORD n = 0; return TRUE == WriteConsoleOutputCharacter( hStdOutput, pstr, len?len:strlen(pstr), coord, &n ); } /* ´°¿Ú½çÃæÏÔʾ */ /* ¹¹½¨11*19µÄÓÎÏ·´°¿Ú */ const char bg[] = "©³©¥©¥©¥©¥©¥©¥©¥©¥©¥©¥©¥©· " "©§¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö©§ ¡û¡ý¡ú ¡ü " "©§¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö©§ Begin " "©§¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö©§ Voice = Yes" "©§¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö©§ Sleep " "©§¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö©§ Quit " "©§¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö©§ " "©§¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö©§ " "©§¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö©§ £Î£Å£Ø£Ô " "©§¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö©§©³©¥©¥©¥©¥©·" "©§¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö©§©§¡¡¡¡¡¡¡¡©§" "©§¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö©§©§¡¡¡¡¡¡¡¡©§" "©§¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö©§©»©¥©¥©¥©¥©¿" "©§¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö©§ £Ì£Å£Ö£Å£Ì " "©§¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö©§©³©¥©¥©¥©¥©·" "©§¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö©§©§ 0 ©§" "©§¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö©§©»©¥©¥©¥©¥©¿" "©§¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö©§ £Ó£Ã£Ï£Ò£Å " "©§¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö©§©³©¥©¥©¥©¥©·" "©§¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö©§©§ 00000 ©§" "©»©¥©¥©¥©¥©¥©¥©¥©¥©¥©¥©¥©¿©»©¥©¥©¥©¥©¿"; /* ÆßÖÖͼÐεĸ÷ÖÖÇé¿ö */ /* µÚһάΪͼÐÎÖÖÀ࣬µÚ¶þάΪͼÐεķ½Ïò£¬ÈýËÄάΪͼÐεÄ4*4µÄÌî³ä·½Ê½ */ const char bk[7][4][4][4] = { { { { 0,1,1,0 },{ 1,1,0,0 },{ 0,0,0,0 },{ 0,0,0,0 } }, { { 1,0,0,0 },{ 1,1,0,0 },{ 0,1,0,0 },{ 0,0,0,0 } }, { { 0,1,1,0 },{ 1,1,0,0 },{ 0,0,0,0 },{ 0,0,0,0 } }, { { 1,0,0,0 },{ 1,1,0,0 },{ 0,1,0,0 },{ 0,0,0,0 } } } , { { { 1,1,0,0 },{ 0,1,1,0 },{ 0,0,0,0 },{ 0,0,0,0 } }, { { 0,1,0,0 },{ 1,1,0,0 },{ 1,0,0,0 },{ 0,0,0,0 } }, { { 1,1,0,0 },{ 0,1,1,0 },{ 0,0,0,0 },{ 0,0,0,0 } }, { { 0,1,0,0 },{ 1,1,0,0 },{ 1,0,0,0 },{ 0,0,0,0 } } } , { { { 1,1,1,0 },{ 1,0,0,0 },{ 0,0,0,0 },{ 0,0,0,0 } }, { { 1,0,0,0 },{ 1,0,0,0 },{ 1,1,0,0 },{ 0,0,0,0 } }, { { 0,0,1,0 },{ 1,1,1,0 },{ 0,0,0,0 },{ 0,0,0,0 } }, { { 1,1,0,0 },{ 0,1,0,0 },{ 0,1,0,0 },{ 0,0,0,0 } } } , { { { 1,1,1,0 },{ 0,0,1,0 },{ 0,0,0,0 },{ 0,0,0,0 } }, { { 1,1,0,0 },{ 1,0,0,0 },{ 1,0,0,0 },{ 0,0,0,0 } }, { { 1,0,0,0 },{ 1,1,1,0 },{ 0,0,0,0 },{ 0,0,0,0 } }, { { 0,1,0,0 },{ 0,1,0,0 },{ 1,1,0,0 },{ 0,0,0,0 } } } , { { { 1,1,0,0 },{ 1,1,0,0 },{ 0,0,0,0 },{ 0,0,0,0 } }, { { 1,1,0,0 },{ 1,1,0,0 },{ 0,0,0,0 },{ 0,0,0,0 } }, { { 1,1,0,0 },{ 1,1,0,0 },{ 0,0,0,0 },{ 0,0,0,0 } }, { { 1,1,0,0 },{ 1,1,0,0 },{ 0,0,0,0 },{ 0,0,0,0 } } } , { { { 0,1,0,0 },{ 1,1,1,0 },{ 0,0,0,0 },{ 0,0,0,0 } }, { { 0,1,0,0 },{ 1,1,0,0 },{ 0,1,0,0 },{ 0,0,0,0 } }, { { 1,1,1,0 },{ 0,1,0,0 },{ 0,0,0,0 },{ 0,0,0,0 } }, { { 1,0,0,0 },{ 1,1,0,0 },{ 1,0,0,0 },{ 0,0,0,0 } } } , { { { 1,1,1,1 },{ 0,0,0,0 },{ 0,0,0,0 },{ 0,0,0,0 } }, { { 1,0,0,0 },{ 1,0,0,0 },{ 1,0,0,0 },{ 1,0,0,0 } }, { { 1,1,1,1 },{ 0,0,0,0 },{ 0,0,0,0 },{ 0,0,0,0 } }, { { 1,0,0,0 },{ 1,0,0,0 },{ 1,0,0,0 },{ 1,0,0,0 } } } }; /* ¿ØÖÆÉùÒô¿ªÆôº¯Êý */ void VoiceBeep( void ) { if( voice ) /* Èç¹ûÉùÒô¿ªÆôÁË */ Beep( 1760, 10 ); /* µ÷ÓÃϵͳÉùÒô */ } /* »æÖÆµÃ·Ö */ void DrawScoreLevel( void ) { char tmp[6]; /* Êä³öµÃ·Ö */ sprintf( tmp, "%05d", score ); OutputStringNoMove( 31, 19, tmp, 5 ); /* Êä³öµÈ¼¶ */ sprintf( tmp, "%1d", level ); OutputStringNoMove( 35, 15, tmp, 1 ); } /* »æÖÆÉùÒôµÄ¿ª¹Ø */ void DrawVoice( void ) { OutputStringNoMove( 35, 3, voice?"Yes":"No ", 0 ); } /* »æÖÆ "next¿ò" ÖеÄͼÐÎ */ void DrawNext( void ) { int i, j; /* next¿òÓÉ2*4µÄ¸ñ×Ó×é³É£¬»æÖÆbkÖÐÿÖÖͼÐεĵÚÒ»¸öÐÎ×´ */ for( i=0; i<2; ++i ) { for( j=0; j<4; ++j ) { OutputStringNoMove( 28+j*2, 10+i, bk[next][0][i][j]== 0?" ":"¡ö", 2 ); } } } /* ÓÎÏ·½áÊø */ void DrawOver( void ) { OutputStringNoMove( 28, 10, "£Ç£Á£Í£Å", 0 ); OutputStringNoMove( 28, 11, "£Ï£Ö£Å£Ò", 0 ); } /* »æÖÆͼÐÎ */ void Draw( WORD color ) { int i, j; for( i = 0; i < 4; ++i ) { /* ÅжÏÊÇ·ñ»æÖƳö½ç */ if( (y + i < 0) || (y + i >= 19) ) { continue; } for( j = 0; j < 4; ++j ) { if( bk[c][z][i][j] == 1 ) { SetColor( color ); /* ÉèÖÃÑÕÉ« */ GotoXY( 2+x*2+j*2, 1+y+i );/* ´Ó×óµ½ÓÒÒÀ´Î»æÖÆ */ OutputString( "¡ö", 2 ); } } } } /* Åжϸø¶¨µÄx,y,c,zÊÇ·ñ¿ÉÐÐ */ bool IsFit( int x, int y, int c, int z ) { int i, j; for( i=0; i<4; ++i ) { for( j=0; j<4; ++j ) { if( bk[c][z][i][j]==1 ) { /* ³ö½ç */ if( y+i < 0 ) { continue; } if( y+i>=19 || x+j<0 || x+j>=11 || data[y+i][x+j]==1 ) { return false; } } } } return true; } /* ÏûÐÐ */ void RemoveRow( void ) { char FULLLINE[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; int linecount = 0; int _score = 0; /* ¼Ó·Ö */ int i, m, n; /* °ÑÕû¸ö´°¿Ú¶¼±éÀúÒ»±é£¬´ÓÉϵ½ÏÂËÑË÷ÂúÐÐ */ for( i=0; i<19; ++i ) { /* ÕÒµ½Ò»¸öÂúÐÐ */ if( 0 == memcmp( data[i], FULLLINE, 11 ) ) { ++linecount; for( m=0; m<11; ++m ) { /* ½«ÂúÐÐÖ®ÉÏËùÓÐÐÐÏÂÒÆ */ for( n=i; n>1; --n ) { data[n][m] = data[n-1][m]; SetColor( data[n][m]==1?COLOR_B:COLOR_C ); GotoXY( 2+m*2, 1+n ); OutputString( "¡ö", 2 ); } data[0][m] = 0;/* Ð޸ĸÃÐеļÇ¼Ϊ¿Õ */ OutputStringNoMove( 2+m*2, 1, "¡ö", 2 );/* »Ö¸´¸ÃÐÐ */ } } } /* ±éÀúÍê³Éºó»Ö¸´ÓÎÏ·´°¿ÚµÄ¼Ç¼ */ char data[19][11] = { 0 }; /* Èç¹ûûÓÐÂúÐÐ */ if( linecount == 0 ) { return; } /* µÃ·Ö·ÖµÈ¼¶ */ switch( linecount ) { case 1: _score = 100; break; case 2: _score = 300; break; case 3: _score = 700; break; case 4: _score = 1500;break; } /* ½«¼Ó·Ö¼ÓÈë×Ü·Ö */ score += _score; /* µÃ·ÖÉÏÏÞΪ99999 */ if( score > 99999 ) { score = 99999; } /* µÈ¼¶ÎªµÃ·Ö³ýÒÔ10000£¬ËùÒÔ×î¸ßΪ9¼¶ */ level = score/10000; /* »æÖƵ÷ֺ͵ȼ¶ */ DrawScoreLevel(); } /* ÄæʱÕë·×ª */ void MoveTrans( void ) { /* ÅжϷתºóÊÇ·ñÊʺϴ°¿Ú */ if( IsFit( x, y, c, (z+1)%4 ) ) { /* ¿ªÆôÉùÒô */ VoiceBeep(); /* »æÖƱ³¾°É« */ Draw( COLOR_C ); /* ±£´æ·½¿é·½ÏòµÄ±ä»¯ */ z = (z + 1) % 4; /* »æÖÆ·½¿éÑÕÉ« */ Draw( COLOR_A ); } } /* Ïò×óÒÆ */ void MoveLeft( void ) { /* ÅжϷתºóÊÇ·ñÊʺϴ°¿Ú */ if( IsFit( x-1, y, c, z ) ) { /* ¿ªÆôÉùÒô */ VoiceBeep(); /* »æÖƱ³¾°É« */ Draw( COLOR_C ); /* ºá×ø±ê¼õÒ» */ --x; /* »æÖÆ·½¿éÑÕÉ« */ Draw( COLOR_A ); } } /* ÏòÓÒÒÆ */ void MoveRight( void ) { /* ÅжϷתºóÊÇ·ñÊʺϴ°¿Ú */ if( IsFit( x+1, y, c, z ) ) { /* ¿ªÆôÉùÒô */ VoiceBeep(); /* »æÖƱ³¾°É« */ Draw( COLOR_C ); /* ºá×ø±ê¼ÓÒ» */ ++x; /* »æÖÆ·½¿éÑÕÉ« */ Draw( COLOR_A ); } } /* ÏòÏÂÒÆ */ void MoveDown( void ) { int i, j; /* ÅжÏÏÂÒƺóÊÇ·ñÊʺϴ°¿Ú */ if( IsFit( x, y+1, c, z ) ) { /* ¿ªÆôÉùÒô */ VoiceBeep(); /* »æÖƱ³¾°É« */ Draw( COLOR_C ); /* ×Ý×ø±ê¼ÓÒ» */ ++y; /* »æÖÆ·½¿éÑÕÉ« */ Draw( COLOR_A ); } /* ·½¿é´¥µ× */ else if( y != -2 ) { /* »æÖÆ·½¿éµÄÑÕɫΪÂÌÉ« */ Draw( COLOR_B ); /* ¼Ç¼´°¿ÚÏÖÔÚµÄÐÅÏ¢ */ for( i=0; i<4; ++i ) { if( y+i<0 ) { continue; } for( j=0; j<4; ++j ) { if( bk[c][z][i][j] == 1 ) { data[y+i][x+j] = 1; } } } /* ÂäÏÂÒ»¿é¾ÍÔËÐÐÒ»´ÎÏûÐк¯Êý */ RemoveRow(); /* ÖØÖÃx£¬y×ø±ê×÷Ϊ·½¿é¿ªÊ¼³öÏֵĵط½£»Í¬Ê±ÖØÖ÷½ÏòºÍÖÖÀà */ x=4, y=-2, c=next, z=0; /* Ëæ»ú³öÏÖ0~6 */ next = rand()%7; /* Ê×ÏÈ»æÖÆnextÌáʾ´°¿ÚµÄͼÐÎ */ DrawNext(); } /* ÓÎÏ·½áÊø */ else { /* »æÖƽáÊø´°¿ÚÐÅÏ¢ */ DrawOver(); } } /* ½ÓÊܼüÅÌÊäÈëÐÅÏ¢º¯Êý */ void MessageDeal( void ) { int cycle = 10 - level; int i; for( ; ; ) { for( i=0; i<cycle; ++i ) { if( _kbhit() ) { switch( _getch() ) { case 'Q': case 'q': /* Í˳ö */ return; break; case 'S': /* ÔÝÍ£ */ case 's': for( ; ; ) { switch( _getch() ) { case 'Q': case 'q': /* Í˳ö */ return; case 'V': /* ÉùÒô */ case 'v': voice = !voice;/* ¸Ä±äÉùÒôÉèÖà */ DrawVoice(); /* »æÖÆÉùÒô´°¿ÚͼÐÎ */ break; case 'S': case 's': goto LABLE_CONTINUE; break; } } LABLE_CONTINUE: break; case 'V': /* ÉùÒô */ case 'v': voice = !voice; DrawVoice(); break; case 0xe0: /* ¡û¡ý¡ú ¡ü */ switch( _getch() ) { case 0x4B: /* ¡û */ MoveLeft(); break; case 0x50: /* ¡ý */ MoveDown(); break; case 0x4d: /* ¡ú */ MoveRight(); break; /* ¡ü ±äÐÎ */ case 0x48: MoveTrans(); default: break; } break; default: break; } } /* ¼õÂý³öÏÖÐÂͼÐεÄʱ¼ä */ Sleep( 55 ); } MoveDown(); } } int main() { char c; Open(); /* ÉèÖñêÌâ */ SetTitle( "¶íÂÞ˹·½¿é made by ËÎÎÄÁÁ" ); /* È¥´¦¹â±ê */ RemoveCursor(); /* ÉèÖô°Ìå³ß´ç */ SetWindowRect( 38-1, 21-1 ); /* ÉèÖûº³å³ß´ç */ SetBufSize( 38, 21 ); /* Êä³ö±³¾°×Ö·û */ OutputStringNoMove( 0,0,bg,0 ); /* ʹÓÃϵͳʱ¼äÉèÖÃËæ»úÖÖ×Ó */ srand( time(0) ); /* ÉèÖÃͼÐÎÖÖÀàµÄËæ»úÊý */ next = rand()%7; /* »æÖÆnext´°¿Ú */ DrawNext(); /* ¿ªÊ¼ Begin */ for( c = (char)_getch(); (c != 'B') &&(c != 'b'); c = (char)_getch() ) { /* ¸ü¸ÄÁåÉù VocieÉèÖà */ if( (c == 'V') || (c == 'v') ) { if( voice ) { voice = false; OutputStringNoMove( 35, 3, "No ", 0 ); } else { voice = true; OutputStringNoMove( 35, 3, "Yes", 0 ); } } } /* »Ö¸´³õʼÊý¾Ý */ x = 4, y = -2, c = next, z = 0; next = rand()%7; DrawNext(); /* ½ÓÊÜÓû§ÊäÈëÐÅÏ¢ */ MessageDeal(); return 0; }