生活随笔
收集整理的這篇文章主要介紹了
俄罗斯方块-C语言-完整代码
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
效果圖如下
#ifndef _DAY7_H
#define _DAY7_H
#include<windows.h>
#include<time.h>
#include<stdbool.h>
#include<conio.h>
#define COL_BEGIN 2
#define COL_END 14
#define ROW_BEGIN 4
#define ROW_END 26HANDLE Output
;
typedef struct TetrisManager
{unsigned int pool
[28];int x
;int y
;int type
[3];int orientation
[3];unsigned score
;unsigned erasedTotal
;unsigned erasedCount
[4];unsigned tetrisTotal
;unsigned tetrisCount
[7];bool dead
;
}Manager
;
typedef struct TetrisControl
{bool pause
;bool clockwise
;int direction
;int color
[28][16];
}Control
;
static const unsigned int gs_uInitialTetrisPool
[28]=
{0XC003,0XC003,0XC003,0XC003,0XC003,0XC003,0XC003,0XC003,0XC003,0XC003,0XC003,0XC003,0XC003,0XC003,0XC003,0XC003,0XC003,0XC003,0XC003,0XC003,0XC003,0XC003,0XC003,0XC003,0XC003,0XC003,0XFFFF,0XFFFF};
static const unsigned int TetrisTable
[7][4]=
{{ 0x00f0, 0x2222,0x00f0,0x2222 },{ 0x0072, 0x0262,0x0270,0x0232 },{ 0x0223, 0x0074,0x0622,0x0170 },{ 0x0226, 0x0470,0x0322,0x0071 },{ 0x0063, 0x0264,0x0063,0x0264 },{ 0x006c, 0x0462,0x006c,0x0462 },{ 0x0660, 0x0660,0x0660,0x0660 },
};
void printPoolBorder();
void gotoxyWithFullwidth(short x
,short y
);
void printPrompting();
void printScore(const Manager
*manager
);void intiGame(Manager
* manager
,Control
*control
);
void startGame(Manager
*manager
,Control
*control
);
void printNextTetris(const Manager
*manager
);
void printTetrisPool(const Manager
*manager
,Control
*control
);
void initTetris(Manager
*manager
);
void insertTetris(Manager
*manager
);
bool
checkCollision(const Manager
*manager
);
void setPoolColor(const Manager
*manager
,Control
*control
);
void printCurrentTetris(const Manager
*manager
,const Control
*control
);
void removeTetris(Manager
*manager
);
void moveDownTetris(Manager
*manager
, Control
*control
);
void runGame(Manager
*manager
, Control
*control
);
void horzMoveTetris(Manager
*manager
, Control
*control
);
void keydownControl(Manager
*manager
, Control
*control
,int key
);
void rotateTetris(Manager
*manager
, Control
*control
);
void dropDownTetris(Manager
*manager
, Control
*control
);
bool
ifPlayAgain();
bool
checkErasing(Manager
*manager
, Control
*control
);
#endif
#include <stdio.h>
#include <stdlib.h>
#include"day7.h"int main()
{Manager manager
;Control control
;intiGame(&manager
,&control
);do{printPrompting();printPoolBorder();runGame(&manager
,&control
);if(ifPlayAgain()){SetConsoleTextAttribute(Output
,0x07);system("cls") ;startGame(&manager
,&control
);}elsebreak;}while(1);intiGame(&manager
,&control
);CloseHandle(Output
);return 0;
}
void intiGame(Manager
* manager
,Control
*control
)
{Output
=GetStdHandle(STD_OUTPUT_HANDLE
);CONSOLE_CURSOR_INFO info
;info
.bVisible
=FALSE
;info
.dwSize
=1;SetConsoleCursorInfo(Output
,&info
);SetConsoleTitle("俄羅斯方塊");startGame(manager
,control
);
}
void printPoolBorder()
{int y
;SetConsoleTextAttribute(Output
,0xf0);for(y
=4;y
<26;y
++){gotoxyWithFullwidth(10,y
-3);printf("%2s"," ");gotoxyWithFullwidth(23,y
-3);printf("%2s"," ");}gotoxyWithFullwidth(10,y
-3);printf("%28s"," ");}
void gotoxyWithFullwidth(short x
,short y
)
{static COORD cd
;cd
.X
= x
*2;cd
.Y
=y
;SetConsoleCursorPosition(Output
,cd
);}
void printPrompting()
{SetConsoleTextAttribute(Output
,0x0b);gotoxyWithFullwidth(26,10);printf("█控制:");gotoxyWithFullwidth(27,12);printf("□向左移動: ← A 4");gotoxyWithFullwidth(27,13);printf("□向右移動: → D 6");gotoxyWithFullwidth(27,14);printf("□向下移動: ↓ S 2");gotoxyWithFullwidth(27,15);printf("□順時針轉: ↑ W 8 ");gotoxyWithFullwidth(27,16);printf("□逆時針轉: 0 ");gotoxyWithFullwidth(27,17);printf("□直接落地: 空格 ");gotoxyWithFullwidth(27,18);printf("□暫停游戲: 回車 ");gotoxyWithFullwidth(26,23);printf("▉By:briup");
}
void printScore(const Manager
*manager
)
{static const char *tetrisName
="ITLJZSO";int i
;SetConsoleTextAttribute(Output
,0x0E);gotoxyWithFullwidth(2,2);printf("█得分:%u",manager
->score
);gotoxyWithFullwidth(1,6);printf("█消行總數:%u",manager
->erasedTotal
);for(i
=0;i
<4;i
++)
{gotoxyWithFullwidth(2,8+i
);printf("□消%d:%u",i
+1,manager
->erasedCount
[i
]);}gotoxyWithFullwidth(1,15);printf("█方塊總數:%u",manager
->tetrisTotal
);for(i
=0;i
<7;i
++)
{gotoxyWithFullwidth(2,17+i
);printf("□%c形:%u",tetrisName
[i
],manager
->tetrisCount
[i
]);}}
void startGame(Manager
*manager
,Control
*control
)
{memset(manager
,0,sizeof(Manager
));memcpy(manager
->pool
,gs_uInitialTetrisPool
,sizeof(unsigned [28]) );srand((unsigned)time(NULL));manager
->type
[1]=rand()%7;manager
->orientation
[1]=rand()%4;manager
->type
[2]=rand()%7;manager
->orientation
[2]=rand()%3;memset(control
,0,sizeof(Control
));initTetris(manager
);setPoolColor(manager
,control
);
}
void printNextTetris(const Manager
*manager
)
{int i
;unsigned int tetris
;SetConsoleTextAttribute(Output
,0X0f);gotoxyWithFullwidth(26,1);printf("┏━━━━━━━━━┓ ┏━━━━━━━━━┓");gotoxyWithFullwidth(26,2);printf("┃%8s ┃ ┃%8s ┃"," " ," ");gotoxyWithFullwidth(26,3);printf("┃%8s ┃ ┃%8s ┃"," " ," ");gotoxyWithFullwidth(26,4);printf("┃%8s ┃ ┃%8s ┃"," " ," ");gotoxyWithFullwidth(26,5);printf("┃%8s ┃ ┃%8s ┃"," " ," ");gotoxyWithFullwidth(26,6);printf("┗━━━━━━━━━┛ ┗━━━━━━━━━┛");tetris
=TetrisTable
[manager
->type
[1]][manager
->orientation
[1]];SetConsoleTextAttribute(Output
,manager
->type
[1]|8);for(i
=0;i
<16;i
++){ gotoxyWithFullwidth((i
&3)+27,(i
>>2)+2);if((tetris
>>i
)&1)printf("■");elseprintf("%2s","");}tetris
=TetrisTable
[manager
->type
[2]][manager
->orientation
[2]];SetConsoleTextAttribute(Output
,8);for(i
=0;i
<16;i
++){ gotoxyWithFullwidth((i
&3)+33,(i
>>2)+2);if((tetris
>>i
)&1)printf("■");elseprintf("%2s","");}
}
#define gotoxyInPool(x,y) gotoxyWithFullwidth(x+9,y-3)
void printTetrisPool(const Manager
*manager
,Control
*control
)
{int x
,y
;for(y
=ROW_BEGIN
;y
<ROW_END
;y
++){ gotoxyInPool(2,y
);for(x
=COL_BEGIN
;x
<COL_END
;x
++){if((manager
->pool
[y
]>>x
) &1){SetConsoleTextAttribute(Output
,control
->color
[y
][x
]);printf("■");}else{SetConsoleTextAttribute(Output
,0);printf("%2s","");}}
}
}
void initTetris(Manager
*manager
)
{unsigned int tetris
;manager
->type
[0]=manager
->type
[1];manager
->orientation
[0]=manager
->orientation
[1];manager
->type
[1]=manager
->type
[2];manager
->orientation
[1]=manager
->orientation
[2];manager
->type
[2]=rand()%7;manager
->orientation
[2]=rand()%4;tetris
=TetrisTable
[manager
->type
[0]][manager
->orientation
[0]];if(tetris
&0x000F)manager
->y
=0;elsemanager
->y
=(tetris
&0x00FF)?1:2;manager
->x
=6;if(checkCollision(manager
)) manager
->dead
=true
;elseinsertTetris(manager
); manager
->tetrisTotal
++;manager
->tetrisCount
[manager
->type
[0]]++;printNextTetris(manager
);printScore(manager
);}
void insertTetris(Manager
*manager
)
{unsigned int tetris
;tetris
= TetrisTable
[manager
->type
[0]][manager
->orientation
[0]];manager
->pool
[manager
->y
+0]|=(((tetris
>>0x0)&0x0f)<< manager
->x
);manager
->pool
[manager
->y
+1]|=(((tetris
>>0x4)&0x0f)<<manager
->x
);manager
->pool
[manager
->y
+2]|=(((tetris
>>0x8)&0x0f)<< manager
->x
);manager
->pool
[manager
->y
+3]|=(((tetris
>>0xc)&0x0f)<<manager
->x
);
}
void setPoolColor(const Manager
*manager
,Control
*control
)
{int x
,y
,i
;unsigned int tetris
;tetris
=TetrisTable
[manager
->type
[0]][manager
->orientation
[0]];for(i
=0;i
<16;i
++){y
=(i
>>2)+manager
->y
;x
=(i
&3)+manager
->x
;if(y
>ROW_END
)break;if((tetris
>>i
) &1)control
->color
[y
][x
]=(manager
->type
[0]|8);}
}
void printCurrentTetris(const Manager
*manager
,const Control
*control
)
{int x
,y
;y
=(manager
->y
>ROW_BEGIN
)?manager
->y
-1:ROW_BEGIN
;for(;y
<ROW_END
&&y
<manager
->y
+4;y
++){x
=(manager
->x
>COL_BEGIN
)?(manager
->x
-1):COL_BEGIN
;for(;x
<COL_END
&&x
<manager
->x
+5;x
++){gotoxyInPool(x
,y
);if((manager
->pool
[y
]>>x
)&1){SetConsoleTextAttribute(Output
,control
->color
[y
][x
]);printf("▽");}else{SetConsoleTextAttribute(Output
,0);printf("%2s","");}}}
}
bool
checkCollision(const Manager
*manager
)
{ unsigned int dest
=0;unsigned int tetris
;tetris
=TetrisTable
[manager
->type
[0]][manager
->orientation
[0]];dest
|=((((manager
->pool
[manager
->y
+0])>>manager
->x
)<<0x0)&0x000f);dest
|=((((manager
->pool
[manager
->y
+1])>>manager
->x
)<<0x4)&0x00f0);dest
|=((((manager
->pool
[manager
->y
+2])>>manager
->x
)<<0x8)&0x0f00);dest
|=((((manager
->pool
[manager
->y
+3])>>manager
->x
)<<0xc)&0xf000);return ((dest
& tetris
) !=0);
}
void removeTetris(Manager
*manager
)
{unsigned int tetris
;tetris
=TetrisTable
[manager
->type
[0]][manager
->orientation
[0]];manager
->pool
[manager
->y
+0]&=~(((tetris
>>0x0)&0x000f)<<manager
->x
);manager
->pool
[manager
->y
+1]&=~(((tetris
>>0x4)&0x000f)<<manager
->x
);manager
->pool
[manager
->y
+2]&=~(((tetris
>>0x8)&0x000f)<<manager
->x
);manager
->pool
[manager
->y
+3]&=~(((tetris
>>0xc)&0x000f)<<manager
->x
);}
void moveDownTetris(Manager
*manager
, Control
*control
)
{int y
;y
=manager
->y
; removeTetris(manager
);++manager
->y
;if(checkCollision(manager
)){manager
->y
=y
;insertTetris(manager
);if(checkErasing(manager
,control
)) printTetrisPool(manager
,control
);}
else
{insertTetris(manager
);setPoolColor(manager
,control
);printCurrentTetris(manager
,control
);printTetrisPool(manager
,control
);
}}
void runGame(Manager
*manager
, Control
*control
)
{clock_t clocknow
,clocklast
;clocklast
=clock();while(!manager
->dead
){ while(_kbhit()){keydownControl(manager
,control
,getch());}if(!control
->pause
){clocknow
=clock();if(clocknow
-clocklast
>0.45*CLOCKS_PER_SEC
){moveDownTetris(manager
,control
);clocklast
=clocknow
;}}}
}
void horzMoveTetris(Manager
*manager
, Control
*control
)
{int x
=manager
->x
;removeTetris(manager
);if(control
->direction
==0)--manager
->x
; else++manager
->x
; if(checkCollision(manager
)){manager
->x
=x
;insertTetris(manager
);}else{insertTetris(manager
);setPoolColor(manager
,control
);printCurrentTetris(manager
,control
);}
}
void rotateTetris(Manager
*manager
, Control
*control
)
{int ori
=manager
->orientation
[0];removeTetris(manager
);if(control
->clockwise
)manager
->orientation
[0]=(ori
+1)&3;elsemanager
->orientation
[0]=(ori
+3)&3;if(checkCollision(manager
)){manager
->orientation
[0]=ori
;insertTetris(manager
);}else{insertTetris(manager
);setPoolColor(manager
,control
);printCurrentTetris(manager
,control
);}
}
void dropDownTetris(Manager
*manager
, Control
*control
)
{removeTetris(manager
);for (;manager
->y
<ROW_END
;manager
->y
++){if(checkCollision(manager
)){break;}}manager
->y
--; insertTetris(manager
); setPoolColor(manager
,control
); checkErasing(manager
,control
); printTetrisPool(manager
,control
);
}
bool
ifPlayAgain()
{int ch
;SetConsoleTextAttribute(Output
,0xf0); gotoxyWithFullwidth(15, 10);printf("游戲結束");gotoxyWithFullwidth(13,11);printf("按Y重玩,按N退出");do {ch
=getch();if(ch
=='y'||ch
=='Y'){return true
;}else if(ch
=='n'||ch
=='N'){return false
;}}while (1);
}
void keydownControl(Manager
*manager
, Control
*control
,int key
)
{ if (key
== 13) {control
->pause
= !control
->pause
;}if (control
->pause
) {return;}switch(key
){case 's':case 'S':case '2':case 80: moveDownTetris(manager
, control
); break;case 'A':case 'a':case '4':case 75 : control
->direction
=0;horzMoveTetris(manager
, control
);break;case 'D':case 'd':case '6':case 77 ://右移control
->direction
=1;horzMoveTetris(manager
, control
);break;case 'W':case 'w':case '8':case 72 ://上按鍵,順時針control
->clockwise
=true
;rotateTetris(manager
,control
);break;case '0' ://逆時針control
->clockwise
=false
;rotateTetris(manager
,control
);break;case ' ': dropDownTetris(manager
, control
);break;default:break;}
}
bool
checkErasing(Manager
*manager
, Control
*control
)
{static const unsigned scores
[5]={0,10,30,90,100};int count
=0;int y
=manager
->y
+3;do{if(y
<ROW_END
&&manager
->pool
[y
]==0xffff){count
++;memmove(manager
->pool
+1,manager
->pool
,sizeof(unsigned int)*y
);memmove(control
->color
[1],control
->color
[0],sizeof( int [16])*y
);}elsey
--;}while(y
>=manager
->y
);manager
->erasedTotal
+=count
; manager
->score
+=scores
[count
];if(count
>0){manager
->erasedCount
[count
-1]++;}initTetris(manager
);setPoolColor(manager
,control
);if(count
>0)return true
;elsereturn false
;}
總結
以上是生活随笔為你收集整理的俄罗斯方块-C语言-完整代码的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。