# I nclude <stdio. h>
# I nclude <dos. h>
# I nclude <conio. h>
# I nclude <graphics. h>
# I nclude <stdlib. h>
# Ifdef _ cplusplus
# DEFINE _ cppargs...
# Else
# DEFINE _ cppargs
# Endif
# Define minboxsize 15/* minimum square size */
# Define bgcolor 7/* Background coloring */
# Define GX 200
# Define Gy 10
# Define sjnum 10000/* each time a player hits a 10 thousand-level score plus a level */
/* Key code */
# Define vk_left 0x4b00
# Define vk_right 0x4d00
# Define vk_down 0x5000
# Define vk_up 0x4800
# Define vk_home 0x4700
# Define vk_end 0x4f00
# Define vk_space 0x3920
# Define vk_esc 0x011b
# Define vk_enter 0x1c0d
/* Define the direction of the Tetris (I define it as 4 )*/
# Define f_dong 0
# Define f_nan 1
# Define f_xi 2
# Define f_bei 3
# Define nextcol 20/* Y coordinate of the next square to be exported */
# Define nextrow 12/* horizontal slave mark of the next square to be exported */
# Define maxrow 14/* game screen size */
# Define maxcol 20
# Define sccol 100/* Relative Position on the game screen large display */
# Define scrow 60
Int gril [22] [16];/* game screen coordinates */
Int Col = 1, row = 7;/* horizontal and vertical coordinates of the current square */
Int boxfx = 0, boxgs = 0;/* the shape and direction of the current temple block */
Int nextboxfx = 0, nextboxgs = 0, maxcol = 22;/* the shape and direction of the next square */
Int minboxcolor = 6, nextminboxcolor = 6;
Int num = 0;/* game score */
Int dj = 0, gamedj [10] = {,};/* game grade */
/* Below I used a 3-dimensional array to record the initial shape and direction of the square */
Int boxstr [7] [4] [16] = {{
{, 0, 0, 0, 0, 0, 0 },
},
{, 0, 0, 0, 0, 0, 0 },
}},
{
{, 0, 0, 0, 0, 0, 0, 0 },
},
{, 0, 0, 0, 0, 0, 0, 0 },
}},
{
{, 0, 0, 0, 0, 0 },
{, 0, 0, 0, 0, 0, 0, 0 },
{, 0 },
}},
{
},
},
},
}},
{
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{0, 0, 0, 0, 0, 0, 0, 0 },
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
}},
{
{0.0, 0, 0, 0, 0 },
{0.0, 0, 0, 0, 0 },
{0.0, 0, 0, 0, 0 },
{0.0, 0, 0, 0, 0 }},
{
},
},
{0.0, 0, 0, 0 },
}}
};
/* Randomly obtain the shape and direction of the current and next squares */
Void boxrad (){
Minboxcolor = nextminboxcolor;
Boxgs = nextboxgs;
Boxfx = nextboxfx;
Nextminboxcolor = random (14) + 1;
If (nextminboxcolor = 4 | nextminboxcolor = 7 | nextminboxcolor = 8)
Nextminboxcolor = 9;
Nextboxfx = f_dong;
Nextboxgs = random (7 );
}
/* Initialize the graphic model */
Void Init (INT gdrive, int gmode ){
Int errorcode;
Initgraph (& gdrive, & gmode, "E: // TC ");
Errorcode = graphresult ();
If (errorcode! = Grok ){
Printf ("error of: % s", grapherrormsg (errorcode ));
Exit (1 );
}
}
/* Clear screen in graphic mode */
Void Cls ()
{
Setfillstyle (solid_fill, 0 );
Setcolor (0 );
Bar (0,0, 640,480 );
}
/* Advanced clear screen in graphic mode */
Void clscr (int A, int B, int C, int D, int color ){
Setfillstyle (solid_fill, color );
Setcolor (color );
Bar (A, B, C, D );
}
/* Draw the smallest square */
Void minbox (int asc, int BSc, int color, int bdcolor ){
Int A = 0, B = 0;
A = sccol + ASC;
B = scrow + BSC;
Clscr (a + 1, B + 1, A-1 + minboxsize, B-1 + minboxsize, color );
If (color! = Bgcolor ){
Setcolor (bdcolor );
Line (a + 1, B + 1, A-1 + minboxsize, B + 1 );
Line (a + 1, B + 1, A + 1, B-1 + minboxsize );
Line (A-1 + minboxsize, B + 1, A-1 + minboxsize, B-1 + minboxsize );
Line (a + 1, B-1 + minboxsize, A-1 + minboxsize, B-1 + minboxsize );
}
}
/* Text in the game */
Void txt (int A, int B, char * txt, int font, int color ){
Setcolor (color );
Settextstyle (0, 0, font );
Outtextxy (a, B, txt );
}
/* Windows plotting */
Void win (int A, int B, int C, int D, int bgcolor, int bordercolor ){
Clscr (a, B, c, d, bgcolor );
Setcolor (bordercolor );
Line (A, B, C, B );
Line (A, B, A, D );
Line (A, D, C, D );
Line (C, B, C, D );
}
/* Draw the current square */
Void funbox (int A, int B, int color, int bdcolor ){
Int I, J;
Int boxz [4] [4];
For (I = 0; I <16; I ++)
Boxz [I/4] [I % 4] = boxstr [boxgs] [boxfx] [I];
For (I = 0; I <4; I ++)
For (j = 0; j <4; j ++)
If (boxz [I] [J] = 1)
Minbox (J + row + a) * minboxsize, (I + Col + B) * minboxsize, color, bdcolor );
}
/* Draw the next square */
Void nextfunbox (int A, int B, int color, int bdcolor ){
Int I, J;
Int boxz [4] [4];
For (I = 0; I <16; I ++)
Boxz [I/4] [I % 4] = boxstr [nextboxgs] [nextboxfx] [I];
For (I = 0; I <4; I ++)
For (j = 0; j <4; j ++)
If (boxz [I] [J] = 1)
Minbox (J + a) * minboxsize, (I + B) * minboxsize, color, bdcolor );
}
/* Definition of time interruption */
# Define timer 0x1c
Int timercounter = 0;
Void interrupt (* oldhandler) (_ cppargs );
Void interrupt newhandler (_ cppargs ){
Timercounter ++;
Oldhandler ();
}
Void settimer (void interrupt (* intproc) (_ cppargs )){
Oldhandler = getvect (timer );
Disable ();
Setvect (timer, intproc );
Enable ();
}
/* Due to game rules, delete a row with the smallest square */
Void delcol (int ){
Int I, J;
For (I = A; I> 1; I --)
For (j = 1; j <15; J ++ ){
Minbox (J * minboxsize, I * minboxsize, bgcolor, bgcolor );
Gril [I] [J] = gril [I-1] [J];
If (gril [I] [J] = 1)
Minbox (J * minboxsize, I * minboxsize, minboxcolor, 0 );
}
}
/* Delete all rows with the smallest square */
Void Delete (){
Int I, j, zero, delgx = 0;
Char * NM = "00000 ";
For (I = 1; I <21; I ++ ){
Zero = 0;
For (j = 1; j <15; J ++)
If (gril [I] [J] = 0)
Zero = 1;
If (zero = 0 ){
Delcol (I );
Delgx ++;
}
}
Num = num + delgx * 10;
Dj = num/10000;
Sprintf (nm, "% d", num );
Clscr (456,173,500,200, 4 );
TXT (456,173, "Number );
TXT (456,193, nm );
}
/* End of time interrupt */
Void killtimer (){
Disable ();
Setvect (timer, oldhandler );
Enable ();
}
/* Test whether the current square can be dropped */
Int downok (){
Int I, j, k = 1, a [4] [4];
For (I = 0; I <16; I ++)
A [I/4] [I % 4] = boxstr [boxgs] [boxfx] [I];
For (I = 0; I <4; I ++)
For (j = 0; j <4; j ++)
If (A [I] [J] & gril [col + I + 1] [row + J])
K = 0;
Return (k );
}
/* Test whether the current square can be left */
Int leftok (){
Int I, j, k = 1, a [4] [4];
For (I = 0; I <16; I ++)
A [I/4] [I % 4] = boxstr [boxgs] [boxfx] [I];
For (I = 0; I <4; I ++)
For (j = 0; j <4; j ++)
If (A [I] [J] & gril [col + I] [row + J-1])
K = 0;
Return (k );
}
/* Test whether the current square can be right */
Int rightok (){
Int I, j, k = 1, a [4] [4];
For (I = 0; I <16; I ++)
A [I/4] [I % 4] = boxstr [boxgs] [boxfx] [I];
For (I = 0; I <4; I ++)
For (j = 0; j <4; j ++)
If (A [I] [J] & gril [col + I] [row + J + 1])
K = 0;
Return (k );
}
/* Test whether the current square can be deformed */
Int upok (){
Int I, j, k = 1, a [4] [4];
For (I = 0; I <4; I ++)
For (I = 0; I <16; I ++)
A [I/4] [I % 4] = boxstr [boxgs] [boxfx + 1] [I];
For (I = 3; I> = 0; I --)
For (j = 3; j> = 0; j --)
If (A [I] [J] & gril [col + I] [row + J])
K = 0;
Return (k );
}
/* Mark the screen coordinates after the current square falls */
Void setgril (){
Int I, j, a [4] [4];
Funbox (0, 0, minboxcolor, 0 );
For (I = 0; I <16; I ++)
A [I/4] [I % 4] = boxstr [boxgs] [boxfx] [I];
For (I = 0; I <4; I ++)
For (j = 0; j <4; j ++)
If (A [I] [J])
Gril [col + I] [row + J] = 1;
Col = 1; ROW = 7;
}
/* Game end */
Void gameover (){
Int I, J;
For (I = 20; I> 0; I --)
For (j = 1; j <15; J ++)
Minbox (J * minboxsize, I * minboxsize, 2, 0 );
TXT (103,203, "Game over );
}
/* Key setting */
Void call_key (INT keyx ){
Switch (keyx ){
Case vk_down: {/* direction key, abscissa plus one. */
If (downok ()){
Col ++;
Funbox (0, 0, minboxcolor, 0 );}
Else {
Funbox (0, 0, minboxcolor, 0 );
Setgril ();
Nextfunbox (nextcol, nextrow, 4, 4 );
Boxrad ();
Nextfunbox (nextcol, nextrow, nextminboxcolor, 0 );
Delete ();
}
Break;
}
Case vk_up: {/* direction key, Rotate 90 degrees in the direction */
If (upok ())
Boxfx ++;
If (boxfx> 3)
Boxfx = 0;
Funbox (0, 0, minboxcolor, 0 );
Break;
}
Case vk_left: {/* left direction key, minus one vertical coordinate */
If (leftok ())
Row --;
Funbox (0, 0, minboxcolor, 0 );
Break;
}
Case vk_right: {/* right direction key, Y axis plus 1 */
If (rightok ())
Row ++;
Funbox (0, 0, minboxcolor, 0 );
Break;
}
Case vk_space:/* Space key, which can be directly placed to the end */
While (downok ())
Col ++;
Funbox (0, 0, minboxcolor, 0 );
Setgril ();
Nextfunbox (nextcol, nextrow, 4, 4 );
Boxrad ();
Nextfunbox (nextcol, nextrow, nextminboxcolor, 0 );
Delete ();
Break;
Default:
{
TXT (423,53, "worng key! ", 1, 4 );
TXT (428,80, "plese enter anly key Ag! ", 1, 4 );
Getch ();
Clscr (, 50, 622,97, bgcolor );
}
}
}
/* Start of time interruption */
Void timezd (void ){
Int key;
Settimer (newhandler );
Boxrad ();
Nextfunbox (nextcol, nextrow, nextminboxcolor, 0 );
For (;;){
If (bioskey (1 )){
Key = bioskey (0 );
Funbox (0, 0, bgcolor, bgcolor );
If (Key = vk_esc)
Break;
Call_key (key );
}
If (timercounter> gamedj [DJ]) {
Timercounter = 0;
If (downok ()){
Funbox (0, 0, bgcolor, bgcolor );
Col ++;
Funbox (0, 0, minboxcolor, 0 );
}
Else {
If (COL = 1 ){
Gameover ();
Getch ();
Break;
}
Setgril ();
Delete ();
Funbox (0, 0, minboxcolor, 0 );
Col = 1; ROW = 7;
Funbox (0, 0, bgcolor, bgcolor );
Nextfunbox (nextcol, nextrow, 4, 4 );
Boxrad ();
Nextfunbox (nextcol, nextrow, nextminboxcolor, 0 );
}
}
}
}
/* Start the main program */
Void main (void ){
Int I, J;
Char * NM = "00000 ";
Init (VGA, vgahi );
CLS ();
/* Screen coordinate initialization */
For (I = 0; I <= maxcol + 1; I ++)
For (j = 0; j <= maxrow + 1; j ++)
Gril [I] [J] = 0;
For (I = 0; I <= maxcol + 1; I ++ ){
Gril [I] [0] = 1;
Gril [I] [15] = 1;
}
For (j = 1; j <= maxrow; j ++ ){
Gril [0] [J] = 1;
Gril [21] [J] = 1;
}
Clscr (640,480, 15 );
Win (639,479 );
Win (sccol + MINBOXSIZE-2, scrow + MINBOXSIZE-2, sccol + 15 * minboxsize + 2, scrow + 21 * minboxsize + 2, bgcolor, 0 );
Nextboxgs = random (8 );
Nextboxfx = random (4 );
Sprintf (nm, "% d", num );
TXT (456,173, "Number );
TXT (456,193, nm );
TXT (456,243, "next box );
Timezd ();
Killtimer ();
Closegraph ();
}