# Include <windows. h>
# Include <stdio. h>
# Include <stdlib. h>
# Include <time. h>
# Include <conio. h>
Class Console
{
Public:
Console ()
{
Hstdoutput = invalid_handle_value;
Hstderror = invalid_handle_value;
}
Bool open (void)
{
Hstdoutput = getstdhandle (std_output_handle );
Hstderror = getstdhandle (std_error_handle );
Return invalid_handle_value! = Hstdoutput & invalid_handle_value! = Hstderror;
}
Inline bool settitle (char * Title) // sets the title
{
Return true = setconsoletitle (title );
}
Bool removecursor (void) // move cursor
{
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) // set the form size
{
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) // you can specify the buffer size.
{
COORD coord = {x, y };
If (! SetConsoleScreenBufferSize (hStdOutput, coord) return false;
If (! SetConsoleScreenBufferSize (hStdError, coord) return false;
Return true;
}
Bool GotoXY (short x, short y) // move the cursor
{
COORD coord = {x, y };
If (! SetConsoleCursorPosition (hStdOutput, coord) return false;
If (! SetConsoleCursorPosition (hStdError, coord) return false;
Return true;
}
Bool SetColor (WORD color) // you can specify the foreground color or background color.
{
If (! SetConsoleTextAttribute (hStdOutput, color) return false;
If (! SetConsoleTextAttribute (hStdError, color) return false;
Return true;
}
Bool OutputString (const char * pstr, size_t len = 0) // output string
{
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 = 0) // output string
{
COORD coord = {x, y };
DWORD n = 0;
Return TRUE = WriteConsoleOutputCharacter (hStdOutput, pstr, len? Len: strlen (pstr), coord, & n );
}
Private:
HANDLE hStdOutput;
HANDLE hStdError;
};
Const char bg [] =
"Zookeeper"
"┃ ■ ┃ ← ↓ → ↑"
"┃ ■ ┃ In"
"┃ ■ ┃ Voice = Yes"
"┃ ■ ┃ Sleep"
"┃ ■ ┃ Quit"
"┃ ■ ┃"
"┃ ■ ┃"
"┃ ■ ┃ NEXT"
"┃ ■ ┃ ━━ ━━━━ ━"
"┃ ■ ┃"
"┃ ■ ┃"
"┃ ■ ┃ ━━ ━━━━ ━"
"┃ ■ ┃ LEVEL"
"┃ ■ ┃ ━━ ━━━━ ━"
"┃ ■ ┃ 0 ┃"
"┃ ■ ┃ ━━ ━━━━ ━"
"┃ ■ SCORE"
"┃ ■ ┃ ━━ ━━━━ ━"
"┃ ■ ┃ 00000"
"When there are too many threads, there are too many threads, too many threads ";
Const char bk [7] [4] [4] [4] =
{
{
{,}, {,}, {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 }},
{,}, {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 }}
}
};
Const WORD COLOR_A = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY; // color in motion
Const WORD COLOR_ B = FOREGROUND_GREEN; // fixed color
Const WORD COLOR_C = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; // color of the blank space
Bool voice = true;
Int score = 0, level = 0;
Char data [19] [11] = {0 };
Int next =-1;
Int x = 4, y =-2, c =-1, z = 0; // x coordinate, coordinate, current square, Direction
Console csl; // defines Console objects
Void VoiceBeep (void)
{
If (voice)
Beep (1760, 10 );
}
Void DrawScoreLevel (void) // draw the score
{
Char tmp [6];
Sprintf (tmp, "% 05d", score );
Csl. OutputStringNoMove (31, 19, tmp, 5 );
Sprintf (tmp, "% 1d", level );
Csl. OutputStringNoMove (35, 15, tmp, 1 );
}
Void DrawVoice (void)
{
Csl. OutputStringNoMove (35, 3, voice? "Yes": "No ");
}
Void DrawNext (void) // draw the image in the "next box"
{
For (int I = 0; I <2; ++ I)
{
For (int j = 0; j <4; ++ j)
{
Csl. OutputStringNoMove (28 + j * 2, 10 + I, bk [next] [0] [I] [j] = 0? "": "■", 2 );
}
}
}
Void DrawOver (void) // end of the game
{
Csl. OutputStringNoMove (28, 10, "GAME ");
Csl. OutputStringNoMove (28, 11, "OVER ");
}
Void Draw (WORD color)
{
For (int I = 0; I <4; ++ I)
{
If (y + I <0 | y + I> = 19) continue;
For (int j = 0; j <4; ++ j)
{
If (bk [c] [z] [I] [j] = 1)
{
Csl. SetColor (color );
Csl. GotoXY (2 + x * 2 + j * 2, 1 + y + I );
Csl. OutputString ("■", 2 );
}
}
}
}
Bool IsFit (int x, int y, int c, int z) // whether the given x, y, c, and z are feasible
{
For (int I = 0; I <4; ++ I)
{
For (int 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) // cancel the line
{
Const char FULLLINE [] = {1, 1, 1, 1, 1, 1, 1, 1, 1 };
Int linecount = 0;
For (INT I = 0; I <19; ++ I)
{
If (0 = memcmp (data [I], fullline, 11 ))
{
++ Linecount;
For (INT m = 0; m <11; ++ m)
{
For (INT n = I; n> 1; -- N)
{
Data [N] [m] = data [n-1] [m];
CSL. setcolor (data [N] [m] = 1? Color_ B: color_c );
CSL. gotoxy (2 + M * 2, 1 + n );
CSL. outputstring ("■", 2 );
}
Data [0] [m] = 0;
CSL. outputstringnomove (2 + M * 2, 1, "■", 2 );
}
}
}
Char data [19] [11] = {0 };
If (linecount = 0) return;
Int _ score = 0;
Switch (linecount)
{
Case 1: _ score = 100; break;
Case 2: _ score = 300; break;
Case 3: _ score = 700; break;
Case 4: _ score = 1500; break;
}
Score + = _ score;
If (score> 99999) score = 99999;
Level = score/10000;
DrawScoreLevel ();
}
Void MoveTrans (void) // flip counter-clockwise
{
If (IsFit (x, y, c, (z + 1) % 4 ))
{
VoiceBeep ();
Draw (COLOR_C );
Z = (z + 1) % 4;
Draw (COLOR_A );
}
}
Void MoveLeft (void) // shift left
{
If (IsFit (x-1, y, c, z ))
{
VoiceBeep ();
Draw (COLOR_C );
-- X;
Draw (COLOR_A );
}
}
Void MoveRight (void) // shift to the right
{
If (IsFit (x + 1, y, c, z ))
{
VoiceBeep ();
Draw (COLOR_C );
++ X;
Draw (COLOR_A );
}
}
Void MoveDown (void) // move down
{
If (IsFit (x, y + 1, c, z ))
{
VoiceBeep ();
Draw (COLOR_C );
++ Y;
Draw (COLOR_A );
}
Else if (y! =-2) // bottoming
{
Draw (COLOR_ B );
For (int I = 0; I <4; ++ I)
{
If (y + I <0) continue;
For (int j = 0; j <4; ++ j)
{
If (bk [c] [z] [I] [j] = 1)
{
Data [y + I] [x + j] = 1;
}
}
}
RemoveRow ();
X = 4, y =-2, c = next, z = 0;
Next = rand () % 7;
DrawNext ();
}
Else // The game is over
{
DrawOver ();
}
}
Void MessageDeal (void)
{
Int cycle = 10-level;
For (;;)
{
For (int I = 0; I <cycle; ++ I)
{
If (_ kbhit ())
{
Switch (_ getch ())
{
Case 'q ':
Case 'q': // exit
Return;
Break;
Case's ': // pause
Case's ':
For (;;)
{
Switch (_ getch ())
{
Case 'q ':
Case 'q': // exit
Return;
Case 'V': // sound
Case 'V ':
Voice =! Voice;
DrawVoice ();
Break;
Case's ':
Case's ':
Goto LABLE_CONTINUE;
Break;
}
}
LABLE_CONTINUE:
Break;
Case 'V': // sound
Case 'V ':
Voice =! Voice;
DrawVoice ();
Break;
Case 0xe0: // commandid → fail
Switch (_ getch ())
{
Case 0x4B: // example
MoveLeft ();
Break;
Case 0x50: // else
MoveDown ();
Break;
Case 0x4d: // →
MoveRight ();
Break; // token Deformation
Case 0x48:
MoveTrans ();
Default:
Break;
}
Break;
Default:
Break;
}
}
Sleep (55 );
}
MoveDown ();
}
}
Int main ()
{
Csl. Open ();
// Set the title
Csl. SetTitle ("Tetris alpha ");
// Cursor
Csl. RemoveCursor ();
// Set the form size
Csl. SetWindowRect (38-1, 21-1 );
// Set the buffer size
Csl. SetBufSize (38, 21 );
// Output background characters
Csl. OutputStringNoMove (0, 0, bg );
// Set Random Seed
Srand (time (0 ));
Next = rand () % 7;
DrawNext ();
{
For (char c = (char) _ getch (); c! = 'B' & c! = 'B'; c = (char) _ getch () // start in
{
If (c = 'V' | c = 'V') // ringtone Vocie
{
If (voice)
{
Voice = false;
Csl. OutputStringNoMove (35, 3, "No ");
}
Else
{
Voice = true;
Csl. OutputStringNoMove (35, 3, "Yes ");
}
}
}
}
X = 4, y =-2, c = next, z = 0;
Next = rand () % 7;
DrawNext ();
MessageDeal ();
Return 0;
}