https://github.com/GitHubYuanHao/Tetris_C
單色版
彩色版
#include<stdio.h>
#include<conio.h>
#include<time.h>
#include<windows.h>
#include<Mmsystem.h>
#pragma comment(lib,"winmm.lib")
#define FrameX 16 //遊戲視窗左上角的X軸座標
#define FrameY 4 //遊戲視窗左上角的Y軸座標
#define height 20 //遊戲視窗的高度
#define width 10//遊戲視窗的寬度
#define StartX 1+width/2//俄羅斯方塊中心出現位置橫座標
#define StartY 2//俄羅斯方塊中心出現位置縱座標
extern time1, time2;
int Line = 0;//消除的行數
int Level = 1;//等級
int Score = 0;//積分
int a[height + 2][width + 2] = { 0 };//俄羅斯方塊數據陣列
int Music = 1;
typedef struct
{
int kind_current;//當前方塊種類
int state_current;//當前方塊狀態
int kind_next;//下一方塊種類
int state_next;//下一方塊狀態
int left;//1爲可左移,0爲不可左移
int right;//1爲可右移,0爲不可右移
int down;//1爲可下移,0爲不可下移
int trans;//1爲可旋轉,0爲不可旋轉
int X;//中心方塊橫座標
int Y;//中心方塊縱座標
int temp[7][4][5][5];//俄羅斯方塊生成陣列
}MyTetris;
//■*********■*********■**************■■*******■■***■■
//■■■***■■■***■■■***■■■■*****■■***■■*****■■
MyTetris tetris =
{
0, 0, 0, 0, 1, 1, 1, 1, StartX, StartY,
{ {
{ { 0, 0, 0, 0, 0 }, { 0, 1, 0, 0, 0 }, { 0, 1, 1, 1, 0 }, { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 } },
{ { 0, 0, 0, 0, 0 }, { 0, 0, 1, 1, 0 }, { 0, 0, 1, 0, 0 }, { 0, 0, 1, 0, 0 }, { 0, 0, 0, 0, 0 } },
{ { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 }, { 0, 1, 1, 1, 0 }, { 0, 0, 0, 1, 0 }, { 0, 0, 0, 0, 0 } },
{ { 0, 0, 0, 0, 0 }, { 0, 0, 1, 0, 0 }, { 0, 0, 1, 0, 0 }, { 0, 1, 1, 0, 0 }, { 0, 0, 0, 0, 0 } }
}, {
{ { 0, 0, 0, 0, 0 }, { 0, 0, 1, 0, 0 }, { 0, 1, 1, 1, 0 }, { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 } },
{ { 0, 0, 0, 0, 0 }, { 0, 0, 1, 0, 0 }, { 0, 0, 1, 1, 0 }, { 0, 0, 1, 0, 0 }, { 0, 0, 0, 0, 0 } },
{ { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 }, { 0, 1, 1, 1, 0 }, { 0, 0, 1, 0, 0 }, { 0, 0, 0, 0, 0 } },
{ { 0, 0, 0, 0, 0 }, { 0, 0, 1, 0, 0 }, { 0, 1, 1, 0, 0 }, { 0, 0, 1, 0, 0 }, { 0, 0, 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, 0 } },
{ { 0, 0, 0, 0, 0 }, { 0, 0, 1, 0, 0 }, { 0, 0, 1, 0, 0 }, { 0, 0, 1, 1, 0 }, { 0, 0, 0, 0, 0 } },
{ { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 }, { 0, 1, 1, 1, 0 }, { 0, 1, 0, 0, 0 }, { 0, 0, 0, 0, 0 } },
{ { 0, 0, 0, 0, 0 }, { 0, 1, 1, 0, 0 }, { 0, 0, 1, 0, 0 }, { 0, 0, 1, 0, 0 }, { 0, 0, 0, 0, 0 } }
}, {
{ { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 }, { 0, 1, 1, 1, 1 }, { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 } },
{ { 0, 0, 0, 0, 0 }, { 0, 0, 1, 0, 0 }, { 0, 0, 1, 0, 0 }, { 0, 0, 1, 0, 0 }, { 0, 0, 1, 0, 0 } },
{ { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 }, { 0, 1, 1, 1, 1 }, { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 } },
{ { 0, 0, 0, 0, 0 }, { 0, 0, 1, 0, 0 }, { 0, 0, 1, 0, 0 }, { 0, 0, 1, 0, 0 }, { 0, 0, 1, 0, 0 } }
}, {
{ { 0, 0, 0, 0, 0 }, { 0, 1, 1, 0, 0 }, { 0, 0, 1, 1, 0 }, { 0, 0, 0, 0, 0 }, { 0, 0, 0, 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 } },
{ { 0, 0, 0, 0, 0 }, { 0, 1, 1, 0, 0 }, { 0, 0, 1, 1, 0 }, { 0, 0, 0, 0, 0 }, { 0, 0, 0, 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 } },
}, {
{ { 0, 0, 0, 0, 0 }, { 0, 0, 1, 1, 0 }, { 0, 1, 1, 0, 0 }, { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 } },
{ { 0, 0, 0, 0, 0 }, { 0, 0, 1, 0, 0 }, { 0, 0, 1, 1, 0 }, { 0, 0, 0, 1, 0 }, { 0, 0, 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, 0 } },
{ { 0, 0, 0, 0, 0 }, { 0, 0, 1, 0, 0 }, { 0, 0, 1, 1, 0 }, { 0, 0, 0, 1, 0 }, { 0, 0, 0, 0, 0 } },
}, {
{ { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 }, { 0, 0, 1, 1, 0 }, { 0, 0, 1, 1, 0 }, { 0, 0, 0, 0, 0 } },
{ { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 }, { 0, 0, 1, 1, 0 }, { 0, 0, 1, 1, 0 }, { 0, 0, 0, 0, 0 } },
{ { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 }, { 0, 0, 1, 1, 0 }, { 0, 0, 1, 1, 0 }, { 0, 0, 0, 0, 0 } },
{ { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 }, { 0, 0, 1, 1, 0 }, { 0, 0, 1, 1, 0 }, { 0, 0, 0, 0, 0 } }
} }
};
MyTetris *pt = &tetris;
long time1, time2;
void Welcom();
void GamePlay();
/****************************************
* 確定螢幕遊標位置
****************************************/
void GotoXY(int x, int y)
{
COORD pos;
pos.X = x;//橫座標
pos.Y = y;//縱座標
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
}
/****************************************
* 隱藏螢幕遊標
****************************************/
void HideCursor()
{
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO CursorInfo;
GetConsoleCursorInfo(handle, &CursorInfo);//獲取控制檯遊標資訊
CursorInfo.bVisible = 0; //隱藏控制檯遊標
SetConsoleCursorInfo(handle, &CursorInfo);//設定控制檯遊標狀態
}
/****************************************
* 音樂開啓並播放函數
****************************************/
void PlayMusic()
{
mciSendString(TEXT("open D:\\Music\\甩蔥歌.mp3 alias Song1"), NULL, 0, NULL);
mciSendString(TEXT("play Song1 repeat"), NULL, 0, NULL);
}
/****************************************
* 音樂重新播放函數
****************************************/
void RestartMusic()
{
mciSendString(TEXT("resume Song1"), NULL, 0, NULL);
}
/****************************************
* 音樂暫停播放函數
****************************************/
void PauseMusic()
{
mciSendString(TEXT("pause Song1"), NULL, 0, NULL);
}
/****************************************
* 列印俄羅斯方塊邊框
****************************************/
void DrwaGameframe()
{
int i = 0;
GotoXY(FrameX + width - 5, FrameY - 2);
printf("俄 羅 斯 方 塊");
for (i = 1; i <= width; i++)
{
GotoXY(FrameX + 2 * i, FrameY);//列印上橫框
printf("■");
GotoXY(FrameX + 2 * i, FrameY + height + 1);//列印下橫框
printf("■");
a[height + 1][i] = 1;
}
for (i = 0; i <= height + 1; i++)
{
GotoXY(FrameX, FrameY + i);//列印左豎框
printf("■");
GotoXY(FrameX + 2 * width + 2, FrameY + i);//列印右豎框
printf("■");
a[i][0] = 1;
a[i][width + 1] = 1;
}
GotoXY(FrameX + 2 * width + 8, FrameY - 1);
printf("Level:%d", Level);
GotoXY(FrameX + 2 * width + 8, FrameY + 1);
printf("積分:%d", Score);
GotoXY(FrameX + 2 * width + 8, FrameY + 3);
printf("消去的行數:%d", Line);
}
/****************************************
* 遊戲開始介面
****************************************/
void FacePlate()
{
printf("\n\n\n");
printf(" 俄 羅 斯 方 塊 \n");
printf("\n\n");
printf(" ■ ■ \n");
printf(" ■■ ■■ ■■ ■ ■\n");
printf(" ■ ■■ ■■ ■ ■■■\n");
printf(" ■ \n");
printf("\n\n");
printf(" 1.開始遊戲 2.按鍵說明 \n");
printf("\n\n");
printf(" 3.遊戲規則 4.退出遊戲 \n");
printf("\n\n");
printf(" 請選擇[1 2 3 4]:");
}
/****************************************
* 遊戲結束介面
****************************************/
void GameOver()
{
int n;
system("cls");
printf("\n\n\n\n\n\n\n\n");
printf(" ■■■ ■ ■ ■ ■■■■ ■■ ■ ■ ■■■■ ■■■ \n");
printf(" ■ ■■ ■ ■■ ■ ■ ■ ■ ■ ■ ■ ■ ■ \n");
printf(" ■ ■■ ■ ■ ■ ■ ■ ■■■ ■ ■ ■ ■ ■■■ ■■■ \n");
printf(" ■ ■ ■■■■ ■ ■ ■ ■ ■ ■ ■■ ■ ■ ■ \n");
printf(" ■■■ ■ ■ ■ ■ ■ ■■■■ ■■ ■ ■■■■ ■ ■\n");
printf("\n\n\n\n\n");
printf(" 1:再玩一局 2:退出遊戲 ");
printf("\n\n");
printf(" 選擇[1/2]:");
scanf("%d", &n);
switch (n)
{
case 1:GamePlay(); break;
case 2:exit(0); break;
}
}
/****************************************
* 遊戲按鍵介紹介面
****************************************/
void Explation()
{
system("cls");
printf("\n\n\n");
printf(" 按鍵說明 \n\n\n");
printf(" ************************************************\n");
printf(" * tip1: 玩家可以通過 ← →方向鍵來移動方塊 *\n");
printf(" * *\n");
printf(" * tip2: 通過 ↑使方塊旋轉 *\n");
printf(" * *\n");
printf(" * tip3: 通過 ↓加速方塊下落 *\n");
printf(" * *\n");
printf(" * tip4: 按空格鍵暫停遊戲,再按空格鍵繼續 *\n");
printf(" * *\n");
printf(" * tip5: 按ESC退出遊戲,按tab鍵暫停/播放音樂 *\n");
printf(" ************************************************\n");
getch();//按任意鍵返回主介面
system("cls");
Welcom();
}
/****************************************
* 遊戲規則介紹介面
****************************************/
void Regulation()
{
system("cls");
GotoXY(0, 3);
printf(" 按鍵說明 \n\n\n");
printf(" **********************************************************\n");
printf(" * tip1: 不同形狀的小方塊從螢幕上方落下,玩家通過調整 *\n");
printf(" * 方塊的位置和方向,使他們在螢幕底部拼出完整的 *\n");
printf(" * 一條或幾條 *\n");
printf(" * *\n");
printf(" * tip2: 每消除一行,積分增加100 *\n");
printf(" * *\n");
printf(" * tip3: 每累計1000分,會提升一個等級 *\n");
printf(" * *\n");
printf(" * tip4: 提升等級會使方塊下落速度加快,遊戲難度加大 *\n");
printf(" **********************************************************\n");
getch();//按任意鍵返回主介面
system("cls");
Welcom();
}
/****************************************
* 遊戲歡迎介面
****************************************/
void Welcom()
{
int n = 0;
HideCursor();
FacePlate();
PlayMusic();
scanf("%d", &n);//輸入選項
switch (n)
{
case 1:GamePlay(); break;//遊戲開始
case 2:Explation(); break;//按鍵說明函數
case 3:Regulation(); break;//遊戲規則
case 4:exit(0); break;//關閉遊戲
}
}
/****************************************
* 遊戲參數初始化
****************************************/
void Initialization()
{
int i = 0, j = 0;
pt->kind_current = rand() % 7;
pt->kind_next = rand() % 7;
pt->state_current = rand() % 4;
pt->state_next = rand() % 4;
pt->left = 1;
pt->right = 1;
pt->down = 1;
pt->trans = 1;
pt->X = StartX;
pt->Y = StartY;
Line = 0;
Level = 1;
Score = 0;
for (i = 1; i <= height + 1; i++)
for (j = 1; j <= width + 1; j++)a[i][j] = 0;
for (i = 1; i <= width; i++)a[height + 1][i] = 1;
for (i = 0; i <= height + 1; i++)
{
a[i][0] = 1;
a[i][width + 1] = 1;
}
}
/****************************************
* 生成俄羅斯方塊
****************************************/
void MakeTetris()
{
srand(time(NULL));
pt->kind_current = pt->kind_next;
pt->state_current = pt->state_next;
pt->kind_next = rand() % 7;
pt->state_next = rand() % 4;
}
/****************************************
* 列印出俄羅斯方塊
****************************************/
void PrintTetris()
{
int i = 0, j = 0;
for (i = 0; i < 5; i++)
for (j = 0; j < 5; j++)
a[pt->Y - 2 + i][pt->X - 2 + j] += pt->temp[pt->kind_current][pt->state_current][i][j];
for (i = 1; i <= height; i++)
{
GotoXY(FrameX + 2, FrameY + i);
for (j = 1; j <= width; j++)
if (a[i][j])printf("■");
else printf(" ");
}
}
/****************************************
* 清除舊的俄羅斯方塊
****************************************/
void CleanOld()
{
int i = 0, j = 0;
for (i = 0; i < 5; i++)
for (j = 0; j < 5; j++)
if (pt->temp[pt->kind_current][pt->state_current][i][j])
{
a[pt->Y - 2 + i][pt->X - 2 + j] = 0;
GotoXY(FrameX + 2 * pt->X - 4 + 2 * j, FrameY + pt->Y - 2 + i);
printf(" ");
}
}
/****************************************
* 列印新的俄羅斯方塊
****************************************/
void DrawNew()
{
int i = 0, j = 0;
for (i = 0; i < 5; i++)
for (j = 0; j < 5; j++)
if (pt->temp[pt->kind_current][pt->state_current][i][j])
{
a[pt->Y + i - 2][pt->X + j - 2] = pt->temp[pt->kind_current][pt->state_current][i][j];
GotoXY(FrameX + 2 * pt->X - 4 + 2 * j, FrameY + pt->Y - 2 + i);
printf("■");
}
}
/****************************************
* 旋轉俄羅斯方塊
****************************************/
void Transform()
{
if (pt->state_current != 3)pt->state_current++;
else pt->state_current = 0;
}
/****************************************
* 判斷俄羅斯方塊是否可移動和變形
****************************************/
void Judge_MoveAndTansform()
{
int t;
switch (pt->kind_current)
{
case 0:
case 1:
case 2:t = 4 * pt->kind_current + pt->state_current + 1; break;
case 3:
case 4:
case 5:t = 2 * pt->kind_current + pt->state_current % 2 + 7; break;
case 6:t = 19; break;
}
switch (t)
{
case 1:
if (a[pt->Y - 1][pt->X - 2] == 0 && a[pt->Y][pt->X - 2] == 0)pt->left = 1; else pt->left = 0;
if (a[pt->Y - 1][pt->X] == 0 && a[pt->Y][pt->X + 2] == 0)pt->right = 1; else pt->right = 0;
if (a[pt->Y + 1][pt->X - 1] == 0 && a[pt->Y + 1][pt->X] == 0 && a[pt->Y + 1][pt->X + 1] == 0)pt->down = 1; else pt->down = 0;
if (a[pt->Y - 1][pt->X] == 0 && a[pt->Y - 1][pt->X + 1] == 0 && a[pt->Y + 1][pt->X] == 0)pt->trans = 1; else pt->trans = 0;
break;
case 2:
if (a[pt->Y - 1][pt->X - 1] == 0 && a[pt->Y][pt->X - 1] == 0 && a[pt->Y + 1][pt->X - 1] == 0)pt->left = 1; else pt->left = 0;
if (a[pt->Y - 1][pt->X + 2] == 0 && a[pt->Y][pt->X + 1] == 0 && a[pt->Y + 1][pt->X + 1] == 0)pt->right = 1; else pt->right = 0;
if (a[pt->Y + 2][pt->X] == 0 && a[pt->Y][pt->X + 1] == 0)pt->down = 1; else pt->down = 0;
if (a[pt->Y][pt->X - 1] == 0 && a[pt->Y][pt->X + 1] == 0 && a[pt->Y + 1][pt->X + 1] == 0)pt->trans = 1; else pt->trans = 0;
break;
case 3:
if (a[pt->Y][pt->X - 2] == 0 && a[pt->Y + 1][pt->X] == 0)pt->left = 1; else pt->left = 0;
if (a[pt->Y][pt->X + 2] == 0 && a[pt->Y + 1][pt->X + 2] == 0)pt->right = 1; else pt->right = 0;
if (a[pt->Y + 1][pt->X - 1] == 0 && a[pt->Y + 1][pt->X] == 0 && a[pt->Y + 2][pt->X + 1] == 0)pt->down = 1; else pt->down = 0;
if (a[pt->Y - 1][pt->X] == 0 && a[pt->Y + 1][pt->X - 1] == 0 && a[pt->Y + 1][pt->X] == 0)pt->trans = 1; else pt->trans = 0;
break;
case 4:
if (a[pt->Y - 1][pt->X - 1] == 0 && a[pt->Y][pt->X - 1] == 0 && a[pt->Y + 1][pt->X - 2] == 0)pt->left = 1; else pt->left = 0;
if (a[pt->Y - 1][pt->X + 1] == 0 && a[pt->Y][pt->X + 1] == 0 && a[pt->Y + 1][pt->X + 1] == 0)pt->right = 1; else pt->right = 0;
if (a[pt->Y + 2][pt->X - 1] == 0 && a[pt->Y + 2][pt->X] == 0)pt->down = 1; else pt->down = 0;
if (a[pt->Y - 1][pt->X - 1] == 0 && a[pt->Y][pt->X - 1] == 0 && a[pt->Y][pt->X + 1] == 0)pt->trans = 1; else pt->trans = 0;
break;
case 5:
if (a[pt->Y - 1][pt->X - 1] == 0 && a[pt->Y][pt->X - 2] == 0)pt->left = 1; else pt->left = 0;
if (a[pt->Y - 1][pt->X + 1] == 0 && a[pt->Y][pt->X + 2] == 0)pt->right = 1; else pt->right = 0;
if (a[pt->Y + 1][pt->X - 1] == 0 && a[pt->Y + 1][pt->X] == 0 && a[pt->Y + 1][pt->X + 1] == 0)pt->down = 1; else pt->down = 0;
if (a[pt->Y + 1][pt->X] == 0)pt->trans = 1; else pt->trans = 0;
break;
case 6:
if (a[pt->Y - 1][pt->X - 1] == 0 && a[pt->Y][pt->X - 1] == 0 && a[pt->Y + 1][pt->X - 1] == 0)pt->left = 1; else pt->left = 0;
if (a[pt->Y - 1][pt->X + 1] == 0 && a[pt->Y][pt->X + 2] == 0 && a[pt->Y + 1][pt->X + 1] == 0)pt->right = 1; else pt->right = 0;
if (a[pt->Y + 2][pt->X] == 0 && a[pt->Y + 1][pt->X + 1] == 0)pt->down = 1; else pt->down = 0;
if (a[pt->Y][pt->X - 1] == 0)pt->trans = 1; else pt->trans = 0;
break;
case 7:
if (a[pt->Y][pt->X - 2] == 0 && a[pt->Y + 1][pt->X - 1] == 0)pt->left = 1; else pt->left = 0;
if (a[pt->Y][pt->X + 2] == 0 && a[pt->Y + 1][pt->X + 1] == 0)pt->right = 1; else pt->right = 0;
if (a[pt->Y + 1][pt->X - 1] == 0 && a[pt->Y + 2][pt->X] == 0 && a[pt->Y + 1][pt->X + 1] == 0)pt->down = 1; else pt->down = 0;
if (a[pt->Y - 1][pt->X] == 0)pt->trans = 1; else pt->trans = 0;
break;
case 8:
if (a[pt->Y - 1][pt->X - 1] == 0 && a[pt->Y][pt->X - 2] == 0 && a[pt->Y + 1][pt->X - 1] == 0)pt->left = 1; else pt->left = 0;
if (a[pt->Y - 1][pt->X + 1] == 0 && a[pt->Y][pt->X + 1] == 0 && a[pt->Y + 1][pt->X + 1] == 0)pt->right = 1; else pt->right = 0;
if (a[pt->Y + 1][pt->X - 1] == 0 && a[pt->Y + 2][pt->X] == 0)pt->down = 1; else pt->down = 0;
if (a[pt->Y][pt->X + 1] == 0)pt->trans = 1; else pt->trans = 0;
break;
case 9:
if (a[pt->Y][pt->X - 2] == 0 && a[pt->Y - 1][pt->X] == 0)pt->left = 1; else pt->left = 0;
if (a[pt->Y - 1][pt->X + 2] == 0 && a[pt->Y][pt->X + 2] == 0)pt->right = 1; else pt->right = 0;
if (a[pt->Y + 1][pt->X - 1] == 0 && a[pt->Y + 1][pt->X] == 0 && a[pt->Y + 1][pt->X + 1] == 0)pt->down = 1; else pt->down = 0;
if (a[pt->Y - 1][pt->X] == 0 && a[pt->Y + 1][pt->X] == 0 && a[pt->Y + 1][pt->X + 1] == 0)pt->trans = 1; else pt->trans = 0;
break;
case 10:
if (a[pt->Y - 1][pt->X - 1] == 0 && a[pt->Y][pt->X - 1] == 0 && a[pt->Y + 1][pt->X - 1] == 0)pt->left = 1; else pt->left = 0;
if (a[pt->Y - 1][pt->X + 1] == 0 && a[pt->Y][pt->X + 1] == 0 && a[pt->Y + 1][pt->X + 2] == 0)pt->right = 1; else pt->right = 0;
if (a[pt->Y + 2][pt->X] == 0 && a[pt->Y + 2][pt->X + 1] == 0)pt->down = 1; else pt->down = 0;
if (a[pt->Y][pt->X - 1] == 0 && a[pt->Y + 1][pt->X - 1] == 0 && a[pt->Y][pt->X + 1] == 0)pt->trans = 1; else pt->trans = 0;
break;
case 11:
if (a[pt->Y][pt->X - 2] == 0 && a[pt->Y + 1][pt->X - 2] == 0)pt->left = 1; else pt->left = 0;
if (a[pt->Y][pt->X + 2] == 0 && a[pt->Y + 1][pt->X] == 0)pt->right = 1; else pt->right = 0;
if (a[pt->Y + 2][pt->X - 1] == 0 && a[pt->Y + 1][pt->X] == 0 && a[pt->Y + 1][pt->X + 1] == 0)pt->down = 1; else pt->down = 0;
if (a[pt->Y - 1][pt->X - 1] == 0 && a[pt->Y - 1][pt->X] == 0 && a[pt->Y + 1][pt->X] == 0)pt->trans = 1; else pt->trans = 0;
break;
case 12:
if (a[pt->Y - 1][pt->X - 2] == 0 && a[pt->Y][pt->X - 1] == 0 && a[pt->Y + 1][pt->X - 1] == 0)pt->left = 1; else pt->left = 0;
if (a[pt->Y - 1][pt->X + 1] == 0 && a[pt->Y][pt->X + 1] == 0 && a[pt->Y + 1][pt->X + 1] == 0)pt->right = 1; else pt->right = 0;
if (a[pt->Y][pt->X - 1] == 0 && a[pt->Y + 2][pt->X] == 0)pt->down = 1; else pt->down = 0;
if (a[pt->Y - 1][pt->X + 1] == 0 && a[pt->Y][pt->X - 1] == 0 && a[pt->Y][pt->X + 1] == 0)pt->trans = 1; else pt->trans = 0;
break;
case 13:
if (a[pt->Y][pt->X - 2] == 0)pt->left = 1; else pt->left = 0;
if (a[pt->Y][pt->X + 3] == 0)pt->right = 1; else pt->right = 0;
if (a[pt->Y + 1][pt->X - 1] == 0 && a[pt->Y + 1][pt->X] == 0 && a[pt->Y + 1][pt->X + 1] == 0 && a[pt->Y + 1][pt->X + 2] == 0)pt->down = 1; else pt->down = 0;
if (a[pt->Y - 1][pt->X] == 0 && a[pt->Y + 1][pt->X] == 0 && a[pt->Y + 2][pt->X] == 0)pt->trans = 1; else pt->trans = 0;
break;
case 14:
if (a[pt->Y - 1][pt->X - 1] == 0 && a[pt->Y][pt->X - 1] == 0 && a[pt->Y + 1][pt->X - 1] == 0 && a[pt->Y + 2][pt->X - 1] == 0)pt->left = 1; else pt->left = 0;
if (a[pt->Y - 1][pt->X + 1] == 0 && a[pt->Y][pt->X + 1] == 0 && a[pt->Y + 1][pt->X + 1] == 0 && a[pt->Y + 2][pt->X + 1] == 0)pt->right = 1; else pt->right = 0;
if (a[pt->Y + 3][pt->X] == 0)pt->down = 1; else pt->down = 0;
if (a[pt->Y][pt->X - 1] == 0 && a[pt->Y][pt->X + 1] == 0 && a[pt->Y][pt->X + 2] == 0)pt->trans = 1; else pt->trans = 0;
break;
case 15:
if (a[pt->Y - 1][pt->X - 2] == 0 && a[pt->Y][pt->X - 1] == 0)pt->left = 1; else pt->left = 0;
if (a[pt->Y - 1][pt->X + 1] == 0 && a[pt->Y][pt->X + 2] == 0)pt->right = 1; else pt->right = 0;
if (a[pt->Y][pt->X - 1] == 0 && a[pt->Y + 1][pt->X] == 0 && a[pt->Y + 1][pt->X + 1] == 0)pt->down = 1; else pt->down = 0;
if (a[pt->Y - 1][pt->X + 1] == 0 && a[pt->Y + 1][pt->X] == 0)pt->trans = 1; else pt->trans = 0;
break;
case 16:
if (a[pt->Y - 1][pt->X] == 0 && a[pt->Y][pt->X - 1] == 0 && a[pt->Y + 1][pt->X - 1] == 0)pt->left = 1; else pt->left = 0;
if (a[pt->Y - 1][pt->X + 2] == 0 && a[pt->Y][pt->X + 2] == 0 && a[pt->Y + 1][pt->X + 1] == 0)pt->right = 1; else pt->right = 0;
if (a[pt->Y + 2][pt->X] == 0 && a[pt->Y + 1][pt->X + 1] == 0)pt->down = 1; else pt->down = 0;
if (a[pt->Y - 1][pt->X - 1] == 0 && a[pt->Y - 1][pt->X] == 0)pt->trans = 1; else pt->trans = 0;
break;
case 17:
if (a[pt->Y - 1][pt->X - 1] == 0 && a[pt->Y][pt->X - 2] == 0)pt->left = 1; else pt->left = 0;
if (a[pt->Y - 1][pt->X + 2] == 0 && a[pt->Y][pt->X + 1] == 0)pt->right = 1; else pt->right = 0;
if (a[pt->Y + 1][pt->X - 1] == 0 && a[pt->Y + 1][pt->X] == 0 && a[pt->Y][pt->X + 1] == 0)pt->down = 1; else pt->down = 0;
if (a[pt->Y][pt->X + 1] == 0 && a[pt->Y + 1][pt->X + 1] == 0)pt->trans = 1; else pt->trans = 0;
break;
case 18:
if (a[pt->Y - 1][pt->X - 1] == 0 && a[pt->Y][pt->X - 1] == 0 && a[pt->Y + 1][pt->X] == 0)pt->left = 1; else pt->left = 0;
if (a[pt->Y - 1][pt->X + 1] == 0 && a[pt->Y][pt->X + 2] == 0 && a[pt->Y + 1][pt->X + 2] == 0)pt->right = 1; else pt->right = 0;
if (a[pt->Y + 1][pt->X] == 0 && a[pt->Y + 2][pt->X + 1] == 0)pt->down = 1; else pt->down = 0;
if (a[pt->Y - 1][pt->X + 1] == 0 && a[pt->Y][pt->X - 1] == 0)pt->trans = 1; else pt->trans = 0;
break;
case 19:
if (a[pt->Y][pt->X - 1] == 0 && a[pt->Y + 1][pt->X - 1] == 0)pt->left = 1; else pt->left = 0;
if (a[pt->Y][pt->X + 2] == 0 && a[pt->Y + 1][pt->X + 2] == 0)pt->right = 1; else pt->right = 0;
if (a[pt->Y + 2][pt->X] == 0 && a[pt->Y + 2][pt->X + 1] == 0)pt->down = 1; else pt->down = 0;
pt->trans = 0;
break;
default:break;
}
}
/****************************************
* 關鍵參數顯示函數(用於偵錯)
****************************************/
void JustForDebugging()
{
int i = 0, j = 0;
for (i = 0; i < height + 2; i++)
{
GotoXY(FrameX + 2 * width + 24, FrameY + i);
for (j = 0; j < width + 2; j++)printf("%d", a[i][j]);
}
GotoXY(FrameX + 3 * width + 30, FrameY + 2);
printf("X=%2d", pt->X);
GotoXY(FrameX + 3 * width + 30, FrameY + 3);
printf("Y=%2d", pt->Y);
GotoXY(FrameX + 3 * width + 30, FrameY + 4);
printf("Left=%d", pt->left);
GotoXY(FrameX + 3 * width + 30, FrameY + 5);
printf("Right=%d", pt->right);
GotoXY(FrameX + 3 * width + 30, FrameY + 6);
printf("Down=%d", pt->down);
GotoXY(FrameX + 3 * width + 30, FrameY + 7);
printf("Trans=%d", pt->trans);
}
/****************************************
* 列印下一個俄羅斯方塊
****************************************/
void PrintNextTetris()
{
int i = 0, j = 0;
GotoXY(FrameX + 2 * width + 8, FrameY + 5);
printf("下一個方塊:%2d", pt->kind_next);
for (i = 0; i < 5; i++)
for (j = 0; j < 5; j++)
{
GotoXY(FrameX + 2 * width + 2 * j + 8, FrameY + 6 + i);
if (pt->temp[pt->kind_next][pt->state_next][i][j])printf("■");
else printf(" ");
}
}
/****************************************
* 清除滿行
****************************************/
void CleanLine()
{
int i = height, j = 1, k = 0, sum = 0;
for (i = height; i > 0; i--)
{
sum = 0;
for (j = 1; j <= width; j++)sum += a[i][j];
if (sum == width)
{
Line++;
for (k = i; k > 1; k--)
for (j = 1; j <= width; j++)a[k][j] = a[k - 1][j];
i++;
}
}
Level = 1 + Line / 10;
Score = Line * 100;
GotoXY(FrameX + 2 * width + 8, FrameY - 1);
printf("Level:%d", Level);
GotoXY(FrameX + 2 * width + 8, FrameY + 1);
printf("積分:%d", Score);
GotoXY(FrameX + 2 * width + 8, FrameY + 3);
printf("消去的行數:%d", Line);
}
/****************************************
* 自動下落函數
****************************************/
void AutoDown()
{
int i = 0, j = 0;
time2 = clock();
if (time2 - time1 > 1000 - 100 * Level)
{
Judge_MoveAndTansform();
if (pt->down)
{
CleanOld();
pt->Y++;
DrawNew();
//JustForDebugging();
}
if (!pt->down)
{
CleanLine();
pt->X = StartX;
pt->Y = StartY;
MakeTetris();
Judge_MoveAndTansform();
if (!pt->down)
{
PrintTetris();
Sleep(2000);//停頓兩秒
GameOver();
}
PrintTetris();
PrintNextTetris();
}
//JustForDebugging();
time1 = clock();
}
}
/****************************************
* 鍵盤輸入判定
****************************************/
void KeyControl()
{
int i = 0, j = 0, ch = 0;
if (_kbhit())
{
ch = getch();
Judge_MoveAndTansform();
switch (ch)
{
case 72:if (pt->trans){ CleanOld(); Transform(); DrawNew(); }break;//變形
case 75:if (pt->left){ CleanOld(); pt->X--; DrawNew(); }break;//向上
case 77:if (pt->right){ CleanOld(); pt->X++; DrawNew(); }break;//->向右
case 80:if (pt->down){ CleanOld(); pt->Y++; DrawNew(); }break;//向下
case 32:getch(); break;//空格鍵 暫停遊戲
case 9: Music = -Music;
if (Music > 0)RestartMusic();
else RestartMusic(); break;//tap鍵 暫停歌曲
case 27:system("cls"); exit(0); break;//ESC鍵 退出
default:break;
}
}
}
/****************************************
* 遊戲開始函數
****************************************/
void GamePlay()
{
system("cls");
Initialization();
DrwaGameframe();
MakeTetris();
DrawNew();
PrintNextTetris();
time1 = clock();
while (1)
{
KeyControl();
//JustForDebugging();
AutoDown();
}
}
int main()
{
Welcom();
return 0;
}
#include<stdio.h>
#include<conio.h>
#include<time.h>
#include<windows.h>
#include<Mmsystem.h>
#pragma comment(lib,"winmm.lib")
#define FrameX 16 //遊戲視窗左上角的X軸座標
#define FrameY 4 //遊戲視窗左上角的Y軸座標
#define height 20 //遊戲視窗的高度
#define width 16//遊戲視窗的寬度
#define StartX 1+width/2//俄羅斯方塊中心出現位置橫座標
#define StartY 2//俄羅斯方塊中心出現位置縱座標
extern time1, time2;
int Line = 0;//消除的行數
int Level = 1;//等級
int Score = 0;//積分
/*
黑色=0 藍色=1 綠色=2 淺綠色=3
紅色=4 紫色=5 黃色=6 白色=7
灰色=8 淡藍色=9 淡綠色=10 單淺綠色=11
淡紅色=12 淡紫色=13 淡黃色=14 亮白色=15
*/
#define c1 2 //綠 L形
#define c2 8 //灰 T形
#define c3 15//白 長條形
#define c4 4 //紅 Z形
#define c5 1 //藍 方塊形
int a[height + 2][width + 2] = { 0 };//俄羅斯方塊數據陣列
int Music = 1;
typedef struct
{
int kind_current;//當前方塊種類
int state_current;//當前方塊狀態
int kind_next;//下一方塊種類
int state_next;//下一方塊狀態
int left;//1爲可左移,0爲不可左移
int right;//1爲可右移,0爲不可右移
int down;//1爲可下移,0爲不可下移
int trans;//1爲可旋轉,0爲不可旋轉
int X;//中心方塊橫座標
int Y;//中心方塊縱座標
int temp[7][4][5][5];//俄羅斯方塊生成陣列
}MyTetris;
//■*********■*********■**************■■*******■■***■■
//■■■***■■■***■■■***■■■■*****■■***■■*****■■
MyTetris tetris =
{
0, 0, 0, 0, 1, 1, 1, 1, StartX, StartY,
{ {
{ { 0, 0, 0, 0, 0 }, { 0, c1, 0, 0, 0 }, { 0, c1, c1, c1, 0 }, { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 } },
{ { 0, 0, 0, 0, 0 }, { 0, 0, c1, c1, 0 }, { 0, 0, c1, 0, 0 }, { 0, 0, c1, 0, 0 }, { 0, 0, 0, 0, 0 } },
{ { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 }, { 0, c1, c1, c1, 0 }, { 0, 0, 0, c1, 0 }, { 0, 0, 0, 0, 0 } },
{ { 0, 0, 0, 0, 0 }, { 0, 0, c1, 0, 0 }, { 0, 0, c1, 0, 0 }, { 0, c1, c1, 0, 0 }, { 0, 0, 0, 0, 0 } }
}, {
{ { 0, 0, 0, 0, 0 }, { 0, 0, c2, 0, 0 }, { 0, c2, c2, c2, 0 }, { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 } },
{ { 0, 0, 0, 0, 0 }, { 0, 0, c2, 0, 0 }, { 0, 0, c2, c2, 0 }, { 0, 0, c2, 0, 0 }, { 0, 0, 0, 0, 0 } },
{ { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 }, { 0, c2, c2, c2, 0 }, { 0, 0, c2, 0, 0 }, { 0, 0, 0, 0, 0 } },
{ { 0, 0, 0, 0, 0 }, { 0, 0, c2, 0, 0 }, { 0, c2, c2, 0, 0 }, { 0, 0, c2, 0, 0 }, { 0, 0, 0, 0, 0 } }
}, {
{ { 0, 0, 0, 0, 0 }, { 0, 0, 0, c1, 0 }, { 0, c1, c1, c1, 0 }, { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 } },
{ { 0, 0, 0, 0, 0 }, { 0, 0, c1, 0, 0 }, { 0, 0, c1, 0, 0 }, { 0, 0, c1, c1, 0 }, { 0, 0, 0, 0, 0 } },
{ { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 }, { 0, c1, c1, c1, 0 }, { 0, c1, 0, 0, 0 }, { 0, 0, 0, 0, 0 } },
{ { 0, 0, 0, 0, 0 }, { 0, c1, c1, 0, 0 }, { 0, 0, c1, 0, 0 }, { 0, 0, c1, 0, 0 }, { 0, 0, 0, 0, 0 } }
}, {
{ { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 }, { 0, c3, c3, c3, c3 }, { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 } },
{ { 0, 0, 0, 0, 0 }, { 0, 0, c3, 0, 0 }, { 0, 0, c3, 0, 0 }, { 0, 0, c3, 0, 0 }, { 0, 0, c3, 0, 0 } },
{ { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 }, { 0, c3, c3, c3, c3 }, { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 } },
{ { 0, 0, 0, 0, 0 }, { 0, 0, c3, 0, 0 }, { 0, 0, c3, 0, 0 }, { 0, 0, c3, 0, 0 }, { 0, 0, c3, 0, 0 } }
}, {
{ { 0, 0, 0, 0, 0 }, { 0, c4, c4, 0, 0 }, { 0, 0, c4, c4, 0 }, { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 } },
{ { 0, 0, 0, 0, 0 }, { 0, 0, 0, c4, 0 }, { 0, 0, c4, c4, 0 }, { 0, 0, c4, 0, 0 }, { 0, 0, 0, 0, 0 } },
{ { 0, 0, 0, 0, 0 }, { 0, c4, c4, 0, 0 }, { 0, 0, c4, c4, 0 }, { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 } },
{ { 0, 0, 0, 0, 0 }, { 0, 0, 0, c4, 0 }, { 0, 0, c4, c4, 0 }, { 0, 0, c4, 0, 0 }, { 0, 0, 0, 0, 0 } },
}, {
{ { 0, 0, 0, 0, 0 }, { 0, 0, c4, c4, 0 }, { 0, c4, c4, 0, 0 }, { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 } },
{ { 0, 0, 0, 0, 0 }, { 0, 0, c4, 0, 0 }, { 0, 0, c4, c4, 0 }, { 0, 0, 0, c4, 0 }, { 0, 0, 0, 0, 0 } },
{ { 0, 0, 0, 0, 0 }, { 0, 0, c4, c4, 0 }, { 0, c4, c4, 0, 0 }, { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 } },
{ { 0, 0, 0, 0, 0 }, { 0, 0, c4, 0, 0 }, { 0, 0, c4, c4, 0 }, { 0, 0, 0, c4, 0 }, { 0, 0, 0, 0, 0 } },
}, {
{ { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 }, { 0, 0, c5, c5, 0 }, { 0, 0, c5, c5, 0 }, { 0, 0, 0, 0, 0 } },
{ { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 }, { 0, 0, c5, c5, 0 }, { 0, 0, c5, c5, 0 }, { 0, 0, 0, 0, 0 } },
{ { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 }, { 0, 0, c5, c5, 0 }, { 0, 0, c5, c5, 0 }, { 0, 0, 0, 0, 0 } },
{ { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 }, { 0, 0, c5, c5, 0 }, { 0, 0, c5, c5, 0 }, { 0, 0, 0, 0, 0 } }
} }
};
MyTetris *pt = &tetris;
long time1, time2;
void GamePlay();
void Welcom();
/************************************************************************************************************************
* 控制檯函數設定部分
************************************************************************************************************************/
/****************************************
* 確定螢幕遊標位置
****************************************/
void GotoXY(int x, int y)
{
COORD pos;
pos.X = x;//橫座標
pos.Y = y;//縱座標
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
}
/****************************************
* 隱藏螢幕遊標
****************************************/
void HideCursor()
{
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO CursorInfo;
GetConsoleCursorInfo(handle, &CursorInfo);//獲取控制檯遊標資訊
CursorInfo.bVisible = 0; //隱藏控制檯遊標
SetConsoleCursorInfo(handle, &CursorInfo);//設定控制檯遊標狀態
}
/****************************************
* 控制檯顏色選擇函數
****************************************/
void Color(int c)
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), c);//更改文字顏色
}
/****************************************
* 音樂開啓並播放函數
****************************************/
void PlayMusic()
{
mciSendString(TEXT("open D:\\Music\\甩蔥歌.mp3 alias Song1"), NULL, 0, NULL);
mciSendString(TEXT("play Song1 repeat"), NULL, 0, NULL);
}
/****************************************
* 音樂重新播放函數
****************************************/
void RestartMusic()
{
mciSendString(TEXT("resume Song1"), NULL, 0, NULL);
}
/****************************************
* 音樂暫停播放函數
****************************************/
void PauseMusic()
{
mciSendString(TEXT("pause Song1"), NULL, 0, NULL);
}
/************************************************************************************************************************
* 邊框繪製函數設定部分
************************************************************************************************************************/
/****************************************
* 列印俄羅斯方塊邊框
****************************************/
void DrwaGameframe()
{
int i = 0;
Color(15);
GotoXY(FrameX + width - 5, FrameY - 2);
printf(" 俄 羅 斯 方 塊");
Color(5);
for (i = 1; i <= width+11; i++)
{
GotoXY(FrameX + 2 * i, FrameY);//列印上橫框
printf("■");
GotoXY(FrameX + 2 * i, FrameY + height + 1);//列印下橫框
printf("■");
a[height + 1][i] = 1;
}
for (i = 0; i <= height + 1; i++)
{
GotoXY(FrameX, FrameY + i);//列印左豎框
printf("■");
GotoXY(FrameX + 2 * width + 2, FrameY + i);//列印中豎框
printf("■");
GotoXY(FrameX + 2 * width + 24, FrameY + i);//列印右豎框
printf("■");
a[i][0] = 1;
a[i][width + 1] = 1;
}
GotoXY(FrameX + 2 * width + 8, FrameY + 1);
printf("Level:%d", Level);
GotoXY(FrameX + 2 * width + 8, FrameY + 3);
printf("積分:%d", Score);
GotoXY(FrameX + 2 * width + 8, FrameY + 5);
printf("消去的行數:%d", Line);
}
/****************************************
* 遊戲開始介面
****************************************/
void FacePlate()
{
Color(1);
printf("\n\n\n");
printf(" 俄 羅 斯 方 塊 \n");
Color(c2);
GotoXY(18, 5);
printf("■");
GotoXY(18, 6);
printf("■■");
GotoXY(18, 7);
printf("■");
Color(c4);
GotoXY(26, 6);
printf("■■");
GotoXY(28, 7);
printf("■■");
Color(c5);
GotoXY(36, 6);
printf("■■");
GotoXY(36, 7);
printf("■■");
Color(c3);
GotoXY(45, 5);
printf("■");
GotoXY(45, 6);
printf("■");
GotoXY(45, 7);
printf("■");
GotoXY(45, 8);
printf("■");
Color(c1);
GotoXY(56, 6);
printf("■");
GotoXY(52, 7);
printf("■■■");
Color(1);
GotoXY(0, 12);
printf(" 1.開始遊戲 2.按鍵說明 \n");
printf("\n\n");
printf(" 3.遊戲規則 4.退出遊戲 \n");
printf("\n\n");
printf(" 請選擇[1 2 3 4]:");
Color(15);
}
/****************************************
* 遊戲結束介面
****************************************/
void GameOver()
{
int n;
system("cls");
Color(1);
printf("\n\n\n\n\n\n\n\n");
printf(" ■■■ ■ ■ ■ ■■■■ ■■ ■ ■ ■■■■ ■■■ \n");
printf(" ■ ■■ ■ ■■ ■ ■ ■ ■ ■ ■ ■ ■ ■ \n");
printf(" ■ ■■ ■ ■ ■ ■ ■ ■■■ ■ ■ ■ ■ ■■■ ■■■ \n");
printf(" ■ ■ ■■■■ ■ ■ ■ ■ ■ ■ ■■ ■ ■ ■ \n");
printf(" ■■■ ■ ■ ■ ■ ■ ■■■■ ■■ ■ ■■■■ ■ ■\n");
printf("\n\n\n\n\n");
printf(" 1:再玩一局 2:退出遊戲 ");
printf("\n\n");
printf(" 選擇[1/2]:");
Color(15);
scanf("%d", &n);
switch (n)
{
case 1:GamePlay(); break;
case 2:exit(0); break;
}
}
/****************************************
* 遊戲按鍵介紹介面
****************************************/
void Explation()
{
system("cls");
Color(1);
printf("\n\n\n");
printf(" 按鍵說明 \n\n\n");
printf(" ************************************************\n");
printf(" * tip1: 玩家可以通過 ← →方向鍵來移動方塊 *\n");
printf(" * *\n");
printf(" * tip2: 通過 ↑使方塊旋轉 *\n");
printf(" * *\n");
printf(" * tip3: 通過 ↓加速方塊下落 *\n");
printf(" * *\n");
printf(" * tip4: 按空格鍵暫停遊戲,再按空格鍵繼續 *\n");
printf(" * *\n");
printf(" * tip5: 按ESC退出遊戲,按tab鍵暫停/播放音樂 *\n");
printf(" ************************************************\n");
Color(15);
getch();//按任意鍵返回主介面
system("cls");
Welcom();
}
/****************************************
* 遊戲規則介紹介面
****************************************/
void Regulation()
{
system("cls");
Color(1);
GotoXY(0, 3);
printf(" 按鍵說明 \n\n\n");
printf(" **********************************************************\n");
printf(" * tip1: 不同形狀的小方塊從螢幕上方落下,玩家通過調整 *\n");
printf(" * 方塊的位置和方向,使他們在螢幕底部拼出完整的 *\n");
printf(" * 一條或幾條 *\n");
printf(" * *\n");
printf(" * tip2: 每消除一行,積分增加100 *\n");
printf(" * *\n");
printf(" * tip3: 每累計1000分,會提升一個等級 *\n");
printf(" * *\n");
printf(" * tip4: 提升等級會使方塊下落速度加快,遊戲難度加大 *\n");
printf(" **********************************************************\n");
Color(15);
getch();//按任意鍵返回主介面
system("cls");
Welcom();
}
/****************************************
* 遊戲歡迎介面
****************************************/
void Welcom()
{
int n = 0;
HideCursor();
FacePlate();
PlayMusic();
scanf("%d", &n);//輸入選項
switch (n)
{
case 1:GamePlay(); break;//遊戲開始
case 2:Explation(); break;//按鍵說明函數
case 3:Regulation(); break;//遊戲規則
case 4:exit(0); break;//關閉遊戲
}
}
/****************************************
* 遊戲參數初始化
****************************************/
void Initialization()
{
int i = 0, j = 0;
pt->kind_current = rand() % 7;
pt->kind_next = rand() % 7;
pt->state_current = rand() % 4;
pt->state_next = rand() % 4;
pt->left = 1;
pt->right = 1;
pt->down = 1;
pt->trans = 1;
pt->X = StartX;
pt->Y = StartY;
Line = 0;
Level = 1;
Score = 0;
for (i = 1; i <= height + 1; i++)
for (j = 1; j <= width + 1; j++)a[i][j] = 0;
for (i = 1; i <= width; i++)a[height + 1][i] = 1;
for (i = 0; i <= height + 1; i++)
{
a[i][0] = 1;
a[i][width + 1] = 1;
}
}
/****************************************
* 生成俄羅斯方塊
****************************************/
void MakeTetris()
{
srand(time(NULL));
pt->kind_current = pt->kind_next;
pt->state_current = pt->state_next;
pt->kind_next = rand() % 7;
pt->state_next = rand() % 4;
}
/****************************************
* 列印出俄羅斯方塊
****************************************/
void PrintTetris()
{
int i = 0, j = 0;
for (i = 0; i < 5; i++)
for (j = 0; j < 5; j++)
a[pt->Y - 2 + i][pt->X - 2 + j] += pt->temp[pt->kind_current][pt->state_current][i][j];
for (i = 1; i <= height; i++)
{
GotoXY(FrameX + 2, FrameY + i);
for (j = 1; j <= width; j++)
if (a[i][j])
{
Color(a[i][j]);
printf("■");
}
else printf(" ");
}
}
/****************************************
* 清除舊的俄羅斯方塊
****************************************/
void CleanOld()
{
int i = 0, j = 0;
for (i = 0; i < 5; i++)
for (j = 0; j < 5; j++)
if (pt->temp[pt->kind_current][pt->state_current][i][j])
{
a[pt->Y - 2 + i][pt->X - 2 + j] = 0;
GotoXY(FrameX + 2 * pt->X - 4 + 2 * j, FrameY + pt->Y - 2 + i);
printf(" ");
}
}
/****************************************
* 列印新的俄羅斯方塊
****************************************/
void DrawNew()
{
int i = 0, j = 0;
for (i = 0; i < 5; i++)
for (j = 0; j < 5; j++)
if (pt->temp[pt->kind_current][pt->state_current][i][j])
{
a[pt->Y + i - 2][pt->X + j - 2] = pt->temp[pt->kind_current][pt->state_current][i][j];
GotoXY(FrameX + 2 * pt->X - 4 + 2 * j, FrameY + pt->Y - 2 + i);
Color(pt->temp[pt->kind_current][pt->state_current][i][j]);
printf("■");
}
}
/************************************************************************************************************************
* 俄羅斯方塊遊戲邏輯部分
************************************************************************************************************************/
/****************************************
* 旋轉俄羅斯方塊
****************************************/
void Transform()
{
if (pt->state_current != 3)pt->state_current++;
else pt->state_current = 0;
}
/****************************************
* 判斷俄羅斯方塊是否可移動和變形
****************************************/
void Judge_MoveAndTansform()
{
int t;
switch (pt->kind_current)
{
case 0:
case 1:
case 2:t = 4 * pt->kind_current + pt->state_current + 1; break;
case 3:
case 4:
case 5:t = 2 * pt->kind_current + pt->state_current % 2 + 7; break;
case 6:t = 19; break;
}
switch (t)
{
case 1:
if (a[pt->Y - 1][pt->X - 2] == 0 && a[pt->Y][pt->X - 2] == 0)pt->left = 1; else pt->left = 0;
if (a[pt->Y - 1][pt->X] == 0 && a[pt->Y][pt->X + 2] == 0)pt->right = 1; else pt->right = 0;
if (a[pt->Y + 1][pt->X - 1] == 0 && a[pt->Y + 1][pt->X] == 0 && a[pt->Y + 1][pt->X + 1] == 0)pt->down = 1; else pt->down = 0;
if (a[pt->Y - 1][pt->X] == 0 && a[pt->Y - 1][pt->X + 1] == 0 && a[pt->Y + 1][pt->X] == 0)pt->trans = 1; else pt->trans = 0;
break;
case 2:
if (a[pt->Y - 1][pt->X - 1] == 0 && a[pt->Y][pt->X - 1] == 0 && a[pt->Y + 1][pt->X - 1] == 0)pt->left = 1; else pt->left = 0;
if (a[pt->Y - 1][pt->X + 2] == 0 && a[pt->Y][pt->X + 1] == 0 && a[pt->Y + 1][pt->X + 1] == 0)pt->right = 1; else pt->right = 0;
if (a[pt->Y + 2][pt->X] == 0 && a[pt->Y][pt->X + 1] == 0)pt->down = 1; else pt->down = 0;
if (a[pt->Y][pt->X - 1] == 0 && a[pt->Y][pt->X + 1] == 0 && a[pt->Y + 1][pt->X + 1] == 0)pt->trans = 1; else pt->trans = 0;
break;
case 3:
if (a[pt->Y][pt->X - 2] == 0 && a[pt->Y + 1][pt->X] == 0)pt->left = 1; else pt->left = 0;
if (a[pt->Y][pt->X + 2] == 0 && a[pt->Y + 1][pt->X + 2] == 0)pt->right = 1; else pt->right = 0;
if (a[pt->Y + 1][pt->X - 1] == 0 && a[pt->Y + 1][pt->X] == 0 && a[pt->Y + 2][pt->X + 1] == 0)pt->down = 1; else pt->down = 0;
if (a[pt->Y - 1][pt->X] == 0 && a[pt->Y + 1][pt->X - 1] == 0 && a[pt->Y + 1][pt->X] == 0)pt->trans = 1; else pt->trans = 0;
break;
case 4:
if (a[pt->Y - 1][pt->X - 1] == 0 && a[pt->Y][pt->X - 1] == 0 && a[pt->Y + 1][pt->X - 2] == 0)pt->left = 1; else pt->left = 0;
if (a[pt->Y - 1][pt->X + 1] == 0 && a[pt->Y][pt->X + 1] == 0 && a[pt->Y + 1][pt->X + 1] == 0)pt->right = 1; else pt->right = 0;
if (a[pt->Y + 2][pt->X - 1] == 0 && a[pt->Y + 2][pt->X] == 0)pt->down = 1; else pt->down = 0;
if (a[pt->Y - 1][pt->X - 1] == 0 && a[pt->Y][pt->X - 1] == 0 && a[pt->Y][pt->X + 1] == 0)pt->trans = 1; else pt->trans = 0;
break;
case 5:
if (a[pt->Y - 1][pt->X - 1] == 0 && a[pt->Y][pt->X - 2] == 0)pt->left = 1; else pt->left = 0;
if (a[pt->Y - 1][pt->X + 1] == 0 && a[pt->Y][pt->X + 2] == 0)pt->right = 1; else pt->right = 0;
if (a[pt->Y + 1][pt->X - 1] == 0 && a[pt->Y + 1][pt->X] == 0 && a[pt->Y + 1][pt->X + 1] == 0)pt->down = 1; else pt->down = 0;
if (a[pt->Y + 1][pt->X] == 0)pt->trans = 1; else pt->trans = 0;
break;
case 6:
if (a[pt->Y - 1][pt->X - 1] == 0 && a[pt->Y][pt->X - 1] == 0 && a[pt->Y + 1][pt->X - 1] == 0)pt->left = 1; else pt->left = 0;
if (a[pt->Y - 1][pt->X + 1] == 0 && a[pt->Y][pt->X + 2] == 0 && a[pt->Y + 1][pt->X + 1] == 0)pt->right = 1; else pt->right = 0;
if (a[pt->Y + 2][pt->X] == 0 && a[pt->Y + 1][pt->X + 1] == 0)pt->down = 1; else pt->down = 0;
if (a[pt->Y][pt->X - 1] == 0)pt->trans = 1; else pt->trans = 0;
break;
case 7:
if (a[pt->Y][pt->X - 2] == 0 && a[pt->Y + 1][pt->X - 1] == 0)pt->left = 1; else pt->left = 0;
if (a[pt->Y][pt->X + 2] == 0 && a[pt->Y + 1][pt->X + 1] == 0)pt->right = 1; else pt->right = 0;
if (a[pt->Y + 1][pt->X - 1] == 0 && a[pt->Y + 2][pt->X] == 0 && a[pt->Y + 1][pt->X + 1] == 0)pt->down = 1; else pt->down = 0;
if (a[pt->Y - 1][pt->X] == 0)pt->trans = 1; else pt->trans = 0;
break;
case 8:
if (a[pt->Y - 1][pt->X - 1] == 0 && a[pt->Y][pt->X - 2] == 0 && a[pt->Y + 1][pt->X - 1] == 0)pt->left = 1; else pt->left = 0;
if (a[pt->Y - 1][pt->X + 1] == 0 && a[pt->Y][pt->X + 1] == 0 && a[pt->Y + 1][pt->X + 1] == 0)pt->right = 1; else pt->right = 0;
if (a[pt->Y + 1][pt->X - 1] == 0 && a[pt->Y + 2][pt->X] == 0)pt->down = 1; else pt->down = 0;
if (a[pt->Y][pt->X + 1] == 0)pt->trans = 1; else pt->trans = 0;
break;
case 9:
if (a[pt->Y][pt->X - 2] == 0 && a[pt->Y - 1][pt->X] == 0)pt->left = 1; else pt->left = 0;
if (a[pt->Y - 1][pt->X + 2] == 0 && a[pt->Y][pt->X + 2] == 0)pt->right = 1; else pt->right = 0;
if (a[pt->Y + 1][pt->X - 1] == 0 && a[pt->Y + 1][pt->X] == 0 && a[pt->Y + 1][pt->X + 1] == 0)pt->down = 1; else pt->down = 0;
if (a[pt->Y - 1][pt->X] == 0 && a[pt->Y + 1][pt->X] == 0 && a[pt->Y + 1][pt->X + 1] == 0)pt->trans = 1; else pt->trans = 0;
break;
case 10:
if (a[pt->Y - 1][pt->X - 1] == 0 && a[pt->Y][pt->X - 1] == 0 && a[pt->Y + 1][pt->X - 1] == 0)pt->left = 1; else pt->left = 0;
if (a[pt->Y - 1][pt->X + 1] == 0 && a[pt->Y][pt->X + 1] == 0 && a[pt->Y + 1][pt->X + 2] == 0)pt->right = 1; else pt->right = 0;
if (a[pt->Y + 2][pt->X] == 0 && a[pt->Y + 2][pt->X + 1] == 0)pt->down = 1; else pt->down = 0;
if (a[pt->Y][pt->X - 1] == 0 && a[pt->Y + 1][pt->X - 1] == 0 && a[pt->Y][pt->X + 1] == 0)pt->trans = 1; else pt->trans = 0;
break;
case 11:
if (a[pt->Y][pt->X - 2] == 0 && a[pt->Y + 1][pt->X - 2] == 0)pt->left = 1; else pt->left = 0;
if (a[pt->Y][pt->X + 2] == 0 && a[pt->Y + 1][pt->X] == 0)pt->right = 1; else pt->right = 0;
if (a[pt->Y + 2][pt->X - 1] == 0 && a[pt->Y + 1][pt->X] == 0 && a[pt->Y + 1][pt->X + 1] == 0)pt->down = 1; else pt->down = 0;
if (a[pt->Y - 1][pt->X - 1] == 0 && a[pt->Y - 1][pt->X] == 0 && a[pt->Y + 1][pt->X] == 0)pt->trans = 1; else pt->trans = 0;
break;
case 12:
if (a[pt->Y - 1][pt->X - 2] == 0 && a[pt->Y][pt->X - 1] == 0 && a[pt->Y + 1][pt->X - 1] == 0)pt->left = 1; else pt->left = 0;
if (a[pt->Y - 1][pt->X + 1] == 0 && a[pt->Y][pt->X + 1] == 0 && a[pt->Y + 1][pt->X + 1] == 0)pt->right = 1; else pt->right = 0;
if (a[pt->Y][pt->X - 1] == 0 && a[pt->Y + 2][pt->X] == 0)pt->down = 1; else pt->down = 0;
if (a[pt->Y - 1][pt->X + 1] == 0 && a[pt->Y][pt->X - 1] == 0 && a[pt->Y][pt->X + 1] == 0)pt->trans = 1; else pt->trans = 0;
break;
case 13:
if (a[pt->Y][pt->X - 2] == 0)pt->left = 1; else pt->left = 0;
if (a[pt->Y][pt->X + 3] == 0)pt->right = 1; else pt->right = 0;
if (a[pt->Y + 1][pt->X - 1] == 0 && a[pt->Y + 1][pt->X] == 0 && a[pt->Y + 1][pt->X + 1] == 0 && a[pt->Y + 1][pt->X + 2] == 0)pt->down = 1; else pt->down = 0;
if (a[pt->Y - 1][pt->X] == 0 && a[pt->Y + 1][pt->X] == 0 && a[pt->Y + 2][pt->X] == 0)pt->trans = 1; else pt->trans = 0;
break;
case 14:
if (a[pt->Y - 1][pt->X - 1] == 0 && a[pt->Y][pt->X - 1] == 0 && a[pt->Y + 1][pt->X - 1] == 0 && a[pt->Y + 2][pt->X - 1] == 0)pt->left = 1; else pt->left = 0;
if (a[pt->Y - 1][pt->X + 1] == 0 && a[pt->Y][pt->X + 1] == 0 && a[pt->Y + 1][pt->X + 1] == 0 && a[pt->Y + 2][pt->X + 1] == 0)pt->right = 1; else pt->right = 0;
if (a[pt->Y + 3][pt->X] == 0)pt->down = 1; else pt->down = 0;
if (a[pt->Y][pt->X - 1] == 0 && a[pt->Y][pt->X + 1] == 0 && a[pt->Y][pt->X + 2] == 0)pt->trans = 1; else pt->trans = 0;
break;
case 15:
if (a[pt->Y - 1][pt->X - 2] == 0 && a[pt->Y][pt->X - 1] == 0)pt->left = 1; else pt->left = 0;
if (a[pt->Y - 1][pt->X + 1] == 0 && a[pt->Y][pt->X + 2] == 0)pt->right = 1; else pt->right = 0;
if (a[pt->Y][pt->X - 1] == 0 && a[pt->Y + 1][pt->X] == 0 && a[pt->Y + 1][pt->X + 1] == 0)pt->down = 1; else pt->down = 0;
if (a[pt->Y - 1][pt->X + 1] == 0 && a[pt->Y + 1][pt->X] == 0)pt->trans = 1; else pt->trans = 0;
break;
case 16:
if (a[pt->Y - 1][pt->X] == 0 && a[pt->Y][pt->X - 1] == 0 && a[pt->Y + 1][pt->X - 1] == 0)pt->left = 1; else pt->left = 0;
if (a[pt->Y - 1][pt->X + 2] == 0 && a[pt->Y][pt->X + 2] == 0 && a[pt->Y + 1][pt->X + 1] == 0)pt->right = 1; else pt->right = 0;
if (a[pt->Y + 2][pt->X] == 0 && a[pt->Y + 1][pt->X + 1] == 0)pt->down = 1; else pt->down = 0;
if (a[pt->Y - 1][pt->X - 1] == 0 && a[pt->Y - 1][pt->X] == 0)pt->trans = 1; else pt->trans = 0;
break;
case 17:
if (a[pt->Y - 1][pt->X - 1] == 0 && a[pt->Y][pt->X - 2] == 0)pt->left = 1; else pt->left = 0;
if (a[pt->Y - 1][pt->X + 2] == 0 && a[pt->Y][pt->X + 1] == 0)pt->right = 1; else pt->right = 0;
if (a[pt->Y + 1][pt->X - 1] == 0 && a[pt->Y + 1][pt->X] == 0 && a[pt->Y][pt->X + 1] == 0)pt->down = 1; else pt->down = 0;
if (a[pt->Y][pt->X + 1] == 0 && a[pt->Y + 1][pt->X + 1] == 0)pt->trans = 1; else pt->trans = 0;
break;
case 18:
if (a[pt->Y - 1][pt->X - 1] == 0 && a[pt->Y][pt->X - 1] == 0 && a[pt->Y + 1][pt->X] == 0)pt->left = 1; else pt->left = 0;
if (a[pt->Y - 1][pt->X + 1] == 0 && a[pt->Y][pt->X + 2] == 0 && a[pt->Y + 1][pt->X + 2] == 0)pt->right = 1; else pt->right = 0;
if (a[pt->Y + 1][pt->X] == 0 && a[pt->Y + 2][pt->X + 1] == 0)pt->down = 1; else pt->down = 0;
if (a[pt->Y - 1][pt->X + 1] == 0 && a[pt->Y][pt->X - 1] == 0)pt->trans = 1; else pt->trans = 0;
break;
case 19:
if (a[pt->Y][pt->X - 1] == 0 && a[pt->Y + 1][pt->X - 1] == 0)pt->left = 1; else pt->left = 0;
if (a[pt->Y][pt->X + 2] == 0 && a[pt->Y + 1][pt->X + 2] == 0)pt->right = 1; else pt->right = 0;
if (a[pt->Y + 2][pt->X] == 0 && a[pt->Y + 2][pt->X + 1] == 0)pt->down = 1; else pt->down = 0;
pt->trans = 0;
break;
default:break;
}
}
/****************************************
* 關鍵參數顯示函數(用於偵錯)
****************************************/
/*
void JustForDebugging()
{
Color(15);
int i = 0, j = 0;
for (i = 0; i < height + 2; i++)
{
GotoXY(FrameX + 2 * width + 24, FrameY + i);
for (j = 0; j < width + 2; j++)printf("%2d", a[i][j]);
}
GotoXY(FrameX + 4 * width + 30, FrameY + 2);
printf("X=%2d", pt->X);
GotoXY(FrameX + 4 * width + 30, FrameY + 3);
printf("Y=%2d", pt->Y);
GotoXY(FrameX + 4 * width + 30, FrameY + 4);
printf("Left=%d", pt->left);
GotoXY(FrameX + 4 * width + 30, FrameY + 5);
printf("Right=%d", pt->right);
GotoXY(FrameX + 4 * width + 30, FrameY + 6);
printf("Down=%d", pt->down);
GotoXY(FrameX + 4 * width + 30, FrameY + 7);
printf("Trans=%d", pt->trans);
}
*/
/****************************************
* 列印下一個俄羅斯方塊
****************************************/
void PrintNextTetris()
{
int i = 0, j = 0;
Color(15);
GotoXY(FrameX + 2 * width + 8, FrameY + 5);
printf("下一個方塊:%2d", pt->kind_next);
for (i = 0; i < 5; i++)
for (j = 0; j < 5; j++)
{
GotoXY(FrameX + 2 * width + 2 * j + 8, FrameY + 6 + i);
if (pt->temp[pt->kind_next][pt->state_next][i][j])
{
Color(pt->temp[pt->kind_next][pt->state_next][i][j]);
printf("■");
}
else printf(" ");
}
}
/****************************************
* 清除滿行
****************************************/
void CleanLine()
{
int i = height, j = 1, k = 0, sum = 0;
for (i = height; i > 0; i--)
{
sum = 0;
for (j = 1; j <= width; j++)if (a[i][j])sum++;
if (sum == width)
{
Line++;
for (k = i; k > 1; k--)
for (j = 1; j <= width; j++)a[k][j] = a[k - 1][j];
i++;
}
}
Level = 1 + Line / 10;
Score = Line * 100;
Color(1);
GotoXY(FrameX + 2 * width + 8, FrameY + 1);
printf("Level:%d", Level);
GotoXY(FrameX + 2 * width + 8, FrameY + 3);
printf("積分:%d", Score);
GotoXY(FrameX + 2 * width + 8, FrameY + 5);
printf("消去的行數:%d", Line);
}
/****************************************
* 自動下落函數
****************************************/
void AutoDown()
{
time2 = clock();
if (time2 - time1 > 1000 - 100 * Level)
{
Judge_MoveAndTansform();
if (pt->down)
{
CleanOld();
pt->Y++;
DrawNew();
//JustForDebugging();
}
if (!pt->down)
{
CleanLine();
pt->X = StartX;
pt->Y = StartY;
MakeTetris();
Judge_MoveAndTansform();
if (!pt->down)
{
PrintTetris();
Sleep(2000);//停頓兩秒
GameOver();
}
PrintTetris();
PrintNextTetris();
}
//JustForDebugging();
time1 = clock();
}
}
/****************************************
* 鍵盤輸入判定
****************************************/
void KeyControl()
{
int ch = 0;
if (_kbhit())
{
ch = getch();
Judge_MoveAndTansform();
switch (ch)
{
case 72:if (pt->trans){ CleanOld(); Transform(); DrawNew(); }break;//變形
case 75:if (pt->left){ CleanOld(); pt->X--; DrawNew(); }break;//向上
case 77:if (pt->right){ CleanOld(); pt->X++; DrawNew(); }break;//->向右
case 80:if (pt->down){ CleanOld(); pt->Y++; DrawNew(); }break;//向下
case 32:getch(); break;//空格鍵 暫停遊戲
case 9: Music = -Music;
if (Music>0)RestartMusic();
else PauseMusic(); break;//tab鍵 暫停歌曲
case 27:system("cls"); exit(0); break;//ESC鍵 退出
default:break;
}
}
}
/****************************************
* 遊戲開始函數
****************************************/
void GamePlay()
{
system("cls");
Initialization();
DrwaGameframe();
MakeTetris();
DrawNew();
PrintNextTetris();
time1 = clock();
while (1)
{
KeyControl();
//JustForDebugging();
AutoDown();
}
}
int main()
{
Welcom();
return 0;
}
#include<stdio.h>
#include <stdlib.h>
#include<termios.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/time.h>
#include <sys/types.h>
#define debug 0 //1開啓參數函數,0關閉參數顯示
#define FrameX 16 //遊戲視窗左上角的X軸座標
#define FrameY 4 //遊戲視窗左上角的Y軸座標
#define height 20 //遊戲視窗的高度
#define width 10//遊戲視窗的寬度
#define StartX 1+width/2//俄羅斯方塊中心出現位置橫座標
#define StartY 2//俄羅斯方塊中心出現位置縱座標
int Suspend = -1;
int Line = 0;//消除的行數
int Level = 1;//等級
int Score = 0;//積分
int a[height + 2][width + 2] = { 0 };//俄羅斯方塊數據陣列
typedef struct
{
int kind_current;//當前方塊種類
int state_current;//當前方塊狀態
int kind_next;//下一方塊種類
int state_next;//下一方塊狀態
int left;//1爲可左移,0爲不可左移
int right;//1爲可右移,0爲不可右移
int down;//1爲可下移,0爲不可下移
int trans;//1爲可旋轉,0爲不可旋轉
int X;//中心方塊橫座標
int Y;//中心方塊縱座標
int temp[7][4][5][5];//俄羅斯方塊生成陣列
}MyTetris;
//[]*********[]*********[]**************[][]*******[][]***[][]
//[][][]***[][][]***[][][]***[][][][]*****[][]***[][]*****[][]
MyTetris tetris =
{
0, 0, 0, 0, 1, 1, 1, 1, StartX, StartY,
{ {
{ { 0, 0, 0, 0, 0 }, { 0, 1, 0, 0, 0 }, { 0, 1, 1, 1, 0 }, { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 } },
{ { 0, 0, 0, 0, 0 }, { 0, 0, 1, 1, 0 }, { 0, 0, 1, 0, 0 }, { 0, 0, 1, 0, 0 }, { 0, 0, 0, 0, 0 } },
{ { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 }, { 0, 1, 1, 1, 0 }, { 0, 0, 0, 1, 0 }, { 0, 0, 0, 0, 0 } },
{ { 0, 0, 0, 0, 0 }, { 0, 0, 1, 0, 0 }, { 0, 0, 1, 0, 0 }, { 0, 1, 1, 0, 0 }, { 0, 0, 0, 0, 0 } }
}, {
{ { 0, 0, 0, 0, 0 }, { 0, 0, 1, 0, 0 }, { 0, 1, 1, 1, 0 }, { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 } },
{ { 0, 0, 0, 0, 0 }, { 0, 0, 1, 0, 0 }, { 0, 0, 1, 1, 0 }, { 0, 0, 1, 0, 0 }, { 0, 0, 0, 0, 0 } },
{ { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 }, { 0, 1, 1, 1, 0 }, { 0, 0, 1, 0, 0 }, { 0, 0, 0, 0, 0 } },
{ { 0, 0, 0, 0, 0 }, { 0, 0, 1, 0, 0 }, { 0, 1, 1, 0, 0 }, { 0, 0, 1, 0, 0 }, { 0, 0, 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, 0 } },
{ { 0, 0, 0, 0, 0 }, { 0, 0, 1, 0, 0 }, { 0, 0, 1, 0, 0 }, { 0, 0, 1, 1, 0 }, { 0, 0, 0, 0, 0 } },
{ { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 }, { 0, 1, 1, 1, 0 }, { 0, 1, 0, 0, 0 }, { 0, 0, 0, 0, 0 } },
{ { 0, 0, 0, 0, 0 }, { 0, 1, 1, 0, 0 }, { 0, 0, 1, 0, 0 }, { 0, 0, 1, 0, 0 }, { 0, 0, 0, 0, 0 } }
}, {
{ { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 }, { 0, 1, 1, 1, 1 }, { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 } },
{ { 0, 0, 0, 0, 0 }, { 0, 0, 1, 0, 0 }, { 0, 0, 1, 0, 0 }, { 0, 0, 1, 0, 0 }, { 0, 0, 1, 0, 0 } },
{ { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 }, { 0, 1, 1, 1, 1 }, { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 } },
{ { 0, 0, 0, 0, 0 }, { 0, 0, 1, 0, 0 }, { 0, 0, 1, 0, 0 }, { 0, 0, 1, 0, 0 }, { 0, 0, 1, 0, 0 } }
}, {
{ { 0, 0, 0, 0, 0 }, { 0, 1, 1, 0, 0 }, { 0, 0, 1, 1, 0 }, { 0, 0, 0, 0, 0 }, { 0, 0, 0, 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 } },
{ { 0, 0, 0, 0, 0 }, { 0, 1, 1, 0, 0 }, { 0, 0, 1, 1, 0 }, { 0, 0, 0, 0, 0 }, { 0, 0, 0, 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 } },
}, {
{ { 0, 0, 0, 0, 0 }, { 0, 0, 1, 1, 0 }, { 0, 1, 1, 0, 0 }, { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 } },
{ { 0, 0, 0, 0, 0 }, { 0, 1, 0, 0, 0 }, { 0, 1, 1, 0, 0 }, { 0, 0, 1, 0, 0 }, { 0, 0, 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, 0 } },
{ { 0, 0, 0, 0, 0 }, { 0, 1, 0, 0, 0 }, { 0, 1, 1, 0, 0 }, { 0, 0, 1, 0, 0 }, { 0, 0, 0, 0, 0 } },
}, {
{ { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 }, { 0, 0, 1, 1, 0 }, { 0, 0, 1, 1, 0 }, { 0, 0, 0, 0, 0 } },
{ { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 }, { 0, 0, 1, 1, 0 }, { 0, 0, 1, 1, 0 }, { 0, 0, 0, 0, 0 } },
{ { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 }, { 0, 0, 1, 1, 0 }, { 0, 0, 1, 1, 0 }, { 0, 0, 0, 0, 0 } },
{ { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 }, { 0, 0, 1, 1, 0 }, { 0, 0, 1, 1, 0 }, { 0, 0, 0, 0, 0 } }
} }
};
MyTetris *pt = &tetris;
pthread_mutex_t lock;
pthread_t tid_a, tid_b;
int AutoDown();
void Initialization();
void MakeTetris();
void PrintTetris();
void CleanOld();
void DrawNew();
void Transform();
void Judge_MoveAndTansform();
void JustForDebugging();
void PrintNextTetris();
void CleanLine();
int KeyControl(int ch);
void GotoXY(int x, int y);
void Initial_terminal();
void Recovery_terminal();
void StartTimer();
void DrwaGameframe();
void FacePlate();
int GameOver();
void Explation();
void Regulation();
void Welcom();
void GamePlay();
void GameRun();
/****************************************
* 確定螢幕遊標位置
****************************************/
void GotoXY(int x, int y)
{
printf("\033[%d;%dH",y,x);
}
/****************************************
* 終端初始化
****************************************/
void Initial_terminal()
{
printf("\033[?25l");//隱藏遊標
system("stty -icanon");//關緩衝
system("stty -echo");//關回顯
}
/****************************************
* 終端恢復
****************************************/
void Recovery_terminal()
{
system("stty icanon");//恢復緩衝
system("stty echo");//恢復回顯
printf("\033[?25h");//恢復遊標
}
/****************************************
* 列印俄羅斯方塊邊框
****************************************/
void DrwaGameframe()
{
int i = 0;
GotoXY(FrameX + width - 5, FrameY - 2);
printf("俄 羅 斯 方 塊");
GotoXY(FrameX, FrameY);
for (i = 0; i < width + 2; i++)printf("[]");//列印上橫框
GotoXY(FrameX, FrameY + height + 1);
for (i = 0; i < width + 2; i++)printf("[]");//列印下橫框
for (i = 1; i <= height; i++)
{
GotoXY(FrameX, FrameY + i);
printf("[]"); //列印左豎框
}
for (i = 1; i <= height; i++)
{
GotoXY(FrameX + 2 * width + 2, FrameY + i);
printf("[]"); //列印右豎框
}
GotoXY(FrameX + 2 * width + 8, FrameY - 1);
printf("Level:%d", Level);
GotoXY(FrameX + 2 * width + 8, FrameY + 1);
printf("積分:%d", Score);
GotoXY(FrameX + 2 * width + 8, FrameY + 3);
printf("消去的行數:%d", Line);
fflush(stdout);
}
/****************************************
* 遊戲開始介面
****************************************/
void FacePlate()
{
printf("\n\n\n");
printf(" 俄 羅 斯 方 塊 \n");
printf("\n\n");
printf(" [] [] \n");
printf(" [][] [][] [][] [] []\n");
printf(" [] [][] [][] [] [][][]\n");
printf(" [] \n");
printf("\n\n");
printf(" 1.開始遊戲 2.按鍵說明 \n");
printf("\n\n");
printf(" 3.遊戲規則 4.退出遊戲 \n");
printf("\n\n");
printf(" 請選擇[1 2 3 4]:");
}
/****************************************
* 遊戲結束介面
****************************************/
int GameOver()
{
int n;
system("clear");
Recovery_terminal();
printf("\n\n\n\n\n\n\n\n");
printf(" [][][] [] [] [] [][][][] [][] [] [] [][][][] [][][] \n");
printf(" [] [][] [] [][] [] [] [] [] [] [] [] [] [] \n");
printf(" [] [][] [] [] [] [] [] [][][] [] [] [] [] [][][] [][][] \n");
printf(" [] [] [][][][] [] [] [] [] [] [] [][] [] [] [] \n");
printf(" [][][] [] [] [] [] [] [][][][] [][] [] [][][][] [] []\n");
printf("\n\n\n\n\n");
printf(" 1:再玩一局 2:退出遊戲 ");
printf("\n\n");
printf(" 選擇[1/2]:");
scanf("%d", &n);
return n;
}
/****************************************
* 遊戲按鍵介紹介面
****************************************/
void Explation()
{
system("clear");
printf("\n\n\n");
printf(" 按鍵說明 \n\n\n");
printf(" ************************************************\n");
printf(" * tip1: 玩家可以通過 A D方向鍵來移動方塊 *\n");
printf(" * *\n");
printf(" * tip2: 通過 W 使方塊旋轉 *\n");
printf(" * *\n");
printf(" * tip3: 通過 S 加速方塊下落 *\n");
printf(" * *\n");
printf(" * tip4: 按空格鍵暫停遊戲,再按空格鍵繼續 *\n");
printf(" * *\n");
printf(" * tip5: 按ESC退出遊戲 *\n");
printf(" ************************************************\n");
getchar();//按任意鍵返回主介面
getchar();//按任意鍵返回主介面
system("clear");
Welcom();
}
/****************************************
* 遊戲規則介紹介面
****************************************/
void Regulation()
{
system("clear");
GotoXY(0, 3);
printf(" 按鍵說明 \n\n\n");
printf(" **********************************************************\n");
printf(" * tip1: 不同形狀的小方塊從螢幕上方落下,玩家通過調整 *\n");
printf(" * 方塊的位置和方向,使他們在螢幕底部拼出完整的 *\n");
printf(" * 一條或幾條 *\n");
printf(" * *\n");
printf(" * tip2: 每消除一行,積分增加100 *\n");
printf(" * *\n");
printf(" * tip3: 每累計1000分,會提升一個等級 *\n");
printf(" * *\n");
printf(" * tip4: 提升等級會使方塊下落速度加快,遊戲難度加大 *\n");
printf(" **********************************************************\n");
getchar();//按任意鍵返回主介面
getchar();//按任意鍵返回主介面
system("clear");
Welcom();
}
/****************************************
* 遊戲歡迎介面
****************************************/
void Welcom()
{
int n = 0;
system("clear");
FacePlate();
scanf("%d", &n);//輸入選項
switch (n)
{
case 1:GamePlay();break;//遊戲開始
case 2:Explation(); break;//按鍵說明函數
case 3:Regulation(); break;//遊戲規則
case 4:exit(0); break;//關閉遊戲
}
}
/****************************************
* 遊戲參數初始化
****************************************/
void Initialization()
{
int i = 0, j = 0;
Initial_terminal();
pt->kind_current = rand() % 7;
pt->kind_next = rand() % 7;
pt->state_current = rand() % 4;
pt->state_next = rand() % 4;
pt->left = 1;
pt->right = 1;
pt->down = 1;
pt->trans = 1;
pt->X = StartX;
pt->Y = StartY;
Line = 0;
Level = 1;
Score = 0;
for (i = 1; i <= height + 1; i++)
for (j = 1; j <= width + 1; j++)a[i][j] = 0;
for (i = 1; i <= width; i++)a[height + 1][i] = 1;
for (i = 0; i <= height + 1; i++)
{
a[i][0] = 1;
a[i][width + 1] = 1;
}
}
/****************************************
* 生成俄羅斯方塊
****************************************/
void MakeTetris()
{
srand(time(NULL));
pt->kind_current = pt->kind_next;
pt->state_current = pt->state_next;
pt->kind_next = rand() % 7;
pt->state_next = rand() % 4;
}
/****************************************
* 列印出俄羅斯方塊
****************************************/
void PrintTetris()
{
int i = 0, j = 0;
for (i = 0; i < 5; i++)
for (j = 0; j < 5; j++)
a[pt->Y - 2 + i][pt->X - 2 + j] += pt->temp[pt->kind_current][pt->state_current][i][j];
for (i = 1; i <= height; i++)
{
GotoXY(FrameX + 2, FrameY + i);
for (j = 1; j <= width; j++)
if (a[i][j])printf("[]");
else printf(" ");
}
fflush(stdout);
}
/****************************************
* 清除舊的俄羅斯方塊
****************************************/
void CleanOld()
{
int i = 0, j = 0;
for (i = 0; i < 5; i++)
for (j = 0; j < 5; j++)
if (pt->temp[pt->kind_current][pt->state_current][i][j])
{
a[pt->Y - 2 + i][pt->X - 2 + j] = 0;
GotoXY(FrameX + 2 * pt->X - 4 + 2 * j, FrameY + pt->Y - 2 + i);
printf(" ");
}
fflush(stdout);
}
/****************************************
* 列印新的俄羅斯方塊
****************************************/
void DrawNew()
{
int i = 0, j = 0;
for (i = 0; i < 5; i++)
for (j = 0; j < 5; j++)
if (pt->temp[pt->kind_current][pt->state_current][i][j])
{
a[pt->Y + i - 2][pt->X + j - 2] = pt->temp[pt->kind_current][pt->state_current][i][j];
GotoXY(FrameX + 2 * pt->X - 4 + 2 * j, FrameY + pt->Y - 2 + i);
printf("[]");
}
fflush(stdout);
}
/****************************************
* 旋轉俄羅斯方塊
****************************************/
void Transform()
{
if (pt->state_current != 3)pt->state_current++;
else pt->state_current = 0;
}
/****************************************
* 判斷俄羅斯方塊是否可移動和變形
****************************************/
void Judge_MoveAndTansform()
{
int t;
switch (pt->kind_current)
{
case 0:
case 1:
case 2:t = 4 * pt->kind_current + pt->state_current + 1; break;
case 3:
case 4:
case 5:t = 2 * pt->kind_current + pt->state_current % 2 + 7; break;
case 6:t = 19; break;
}
switch (t)
{
case 1:
if (a[pt->Y - 1][pt->X - 2] == 0 && a[pt->Y][pt->X - 2] == 0)pt->left = 1; else pt->left = 0;
if (a[pt->Y - 1][pt->X] == 0 && a[pt->Y][pt->X + 2] == 0)pt->right = 1; else pt->right = 0;
if (a[pt->Y + 1][pt->X - 1] == 0 && a[pt->Y + 1][pt->X] == 0 && a[pt->Y + 1][pt->X + 1] == 0)pt->down = 1; else pt->down = 0;
if (a[pt->Y - 1][pt->X] == 0 && a[pt->Y - 1][pt->X + 1] == 0 && a[pt->Y + 1][pt->X] == 0)pt->trans = 1; else pt->trans = 0;
break;
case 2:
if (a[pt->Y - 1][pt->X - 1] == 0 && a[pt->Y][pt->X - 1] == 0 && a[pt->Y + 1][pt->X - 1] == 0)pt->left = 1; else pt->left = 0;
if (a[pt->Y - 1][pt->X + 2] == 0 && a[pt->Y][pt->X + 1] == 0 && a[pt->Y + 1][pt->X + 1] == 0)pt->right = 1; else pt->right = 0;
if (a[pt->Y + 2][pt->X] == 0 && a[pt->Y][pt->X + 1] == 0)pt->down = 1; else pt->down = 0;
if (a[pt->Y][pt->X - 1] == 0 && a[pt->Y][pt->X + 1] == 0 && a[pt->Y + 1][pt->X + 1] == 0)pt->trans = 1; else pt->trans = 0;
break;
case 3:
if (a[pt->Y][pt->X - 2] == 0 && a[pt->Y + 1][pt->X] == 0)pt->left = 1; else pt->left = 0;
if (a[pt->Y][pt->X + 2] == 0 && a[pt->Y + 1][pt->X + 2] == 0)pt->right = 1; else pt->right = 0;
if (a[pt->Y + 1][pt->X - 1] == 0 && a[pt->Y + 1][pt->X] == 0 && a[pt->Y + 2][pt->X + 1] == 0)pt->down = 1; else pt->down = 0;
if (a[pt->Y - 1][pt->X] == 0 && a[pt->Y + 1][pt->X - 1] == 0 && a[pt->Y + 1][pt->X] == 0)pt->trans = 1; else pt->trans = 0;
break;
case 4:
if (a[pt->Y - 1][pt->X - 1] == 0 && a[pt->Y][pt->X - 1] == 0 && a[pt->Y + 1][pt->X - 2] == 0)pt->left = 1; else pt->left = 0;
if (a[pt->Y - 1][pt->X + 1] == 0 && a[pt->Y][pt->X + 1] == 0 && a[pt->Y + 1][pt->X + 1] == 0)pt->right = 1; else pt->right = 0;
if (a[pt->Y + 2][pt->X - 1] == 0 && a[pt->Y + 2][pt->X] == 0)pt->down = 1; else pt->down = 0;
if (a[pt->Y - 1][pt->X - 1] == 0 && a[pt->Y][pt->X - 1] == 0 && a[pt->Y][pt->X + 1] == 0)pt->trans = 1; else pt->trans = 0;
break;
case 5:
if (a[pt->Y - 1][pt->X - 1] == 0 && a[pt->Y][pt->X - 2] == 0)pt->left = 1; else pt->left = 0;
if (a[pt->Y - 1][pt->X + 1] == 0 && a[pt->Y][pt->X + 2] == 0)pt->right = 1; else pt->right = 0;
if (a[pt->Y + 1][pt->X - 1] == 0 && a[pt->Y + 1][pt->X] == 0 && a[pt->Y + 1][pt->X + 1] == 0)pt->down = 1; else pt->down = 0;
if (a[pt->Y + 1][pt->X] == 0)pt->trans = 1; else pt->trans = 0;
break;
case 6:
if (a[pt->Y - 1][pt->X - 1] == 0 && a[pt->Y][pt->X - 1] == 0 && a[pt->Y + 1][pt->X - 1] == 0)pt->left = 1; else pt->left = 0;
if (a[pt->Y - 1][pt->X + 1] == 0 && a[pt->Y][pt->X + 2] == 0 && a[pt->Y + 1][pt->X + 1] == 0)pt->right = 1; else pt->right = 0;
if (a[pt->Y + 2][pt->X] == 0 && a[pt->Y + 1][pt->X + 1] == 0)pt->down = 1; else pt->down = 0;
if (a[pt->Y][pt->X - 1] == 0)pt->trans = 1; else pt->trans = 0;
break;
case 7:
if (a[pt->Y][pt->X - 2] == 0 && a[pt->Y + 1][pt->X - 1] == 0)pt->left = 1; else pt->left = 0;
if (a[pt->Y][pt->X + 2] == 0 && a[pt->Y + 1][pt->X + 1] == 0)pt->right = 1; else pt->right = 0;
if (a[pt->Y + 1][pt->X - 1] == 0 && a[pt->Y + 2][pt->X] == 0 && a[pt->Y + 1][pt->X + 1] == 0)pt->down = 1; else pt->down = 0;
if (a[pt->Y - 1][pt->X] == 0)pt->trans = 1; else pt->trans = 0;
break;
case 8:
if (a[pt->Y - 1][pt->X - 1] == 0 && a[pt->Y][pt->X - 2] == 0 && a[pt->Y + 1][pt->X - 1] == 0)pt->left = 1; else pt->left = 0;
if (a[pt->Y - 1][pt->X + 1] == 0 && a[pt->Y][pt->X + 1] == 0 && a[pt->Y + 1][pt->X + 1] == 0)pt->right = 1; else pt->right = 0;
if (a[pt->Y + 1][pt->X - 1] == 0 && a[pt->Y + 2][pt->X] == 0)pt->down = 1; else pt->down = 0;
if (a[pt->Y][pt->X + 1] == 0)pt->trans = 1; else pt->trans = 0;
break;
case 9:
if (a[pt->Y][pt->X - 2] == 0 && a[pt->Y - 1][pt->X] == 0)pt->left = 1; else pt->left = 0;
if (a[pt->Y - 1][pt->X + 2] == 0 && a[pt->Y][pt->X + 2] == 0)pt->right = 1; else pt->right = 0;
if (a[pt->Y + 1][pt->X - 1] == 0 && a[pt->Y + 1][pt->X] == 0 && a[pt->Y + 1][pt->X + 1] == 0)pt->down = 1; else pt->down = 0;
if (a[pt->Y - 1][pt->X] == 0 && a[pt->Y + 1][pt->X] == 0 && a[pt->Y + 1][pt->X + 1] == 0)pt->trans = 1; else pt->trans = 0;
break;
case 10:
if (a[pt->Y - 1][pt->X - 1] == 0 && a[pt->Y][pt->X - 1] == 0 && a[pt->Y + 1][pt->X - 1] == 0)pt->left = 1; else pt->left = 0;
if (a[pt->Y - 1][pt->X + 1] == 0 && a[pt->Y][pt->X + 1] == 0 && a[pt->Y + 1][pt->X + 2] == 0)pt->right = 1; else pt->right = 0;
if (a[pt->Y + 2][pt->X] == 0 && a[pt->Y + 2][pt->X + 1] == 0)pt->down = 1; else pt->down = 0;
if (a[pt->Y][pt->X - 1] == 0 && a[pt->Y + 1][pt->X - 1] == 0 && a[pt->Y][pt->X + 1] == 0)pt->trans = 1; else pt->trans = 0;
break;
case 11:
if (a[pt->Y][pt->X - 2] == 0 && a[pt->Y + 1][pt->X - 2] == 0)pt->left = 1; else pt->left = 0;
if (a[pt->Y][pt->X + 2] == 0 && a[pt->Y + 1][pt->X] == 0)pt->right = 1; else pt->right = 0;
if (a[pt->Y + 2][pt->X - 1] == 0 && a[pt->Y + 1][pt->X] == 0 && a[pt->Y + 1][pt->X + 1] == 0)pt->down = 1; else pt->down = 0;
if (a[pt->Y - 1][pt->X - 1] == 0 && a[pt->Y - 1][pt->X] == 0 && a[pt->Y + 1][pt->X] == 0)pt->trans = 1; else pt->trans = 0;
break;
case 12:
if (a[pt->Y - 1][pt->X - 2] == 0 && a[pt->Y][pt->X - 1] == 0 && a[pt->Y + 1][pt->X - 1] == 0)pt->left = 1; else pt->left = 0;
if (a[pt->Y - 1][pt->X + 1] == 0 && a[pt->Y][pt->X + 1] == 0 && a[pt->Y + 1][pt->X + 1] == 0)pt->right = 1; else pt->right = 0;
if (a[pt->Y][pt->X - 1] == 0 && a[pt->Y + 2][pt->X] == 0)pt->down = 1; else pt->down = 0;
if (a[pt->Y - 1][pt->X + 1] == 0 && a[pt->Y][pt->X - 1] == 0 && a[pt->Y][pt->X + 1] == 0)pt->trans = 1; else pt->trans = 0;
break;
case 13:
if (a[pt->Y][pt->X - 2] == 0)pt->left = 1; else pt->left = 0;
if (a[pt->Y][pt->X + 3] == 0)pt->right = 1; else pt->right = 0;
if (a[pt->Y + 1][pt->X - 1] == 0 && a[pt->Y + 1][pt->X] == 0 && a[pt->Y + 1][pt->X + 1] == 0 && a[pt->Y + 1][pt->X + 2] == 0)pt->down = 1;
else pt->down = 0;
if (a[pt->Y - 1][pt->X] == 0 && a[pt->Y + 1][pt->X] == 0 && a[pt->Y + 2][pt->X] == 0)pt->trans = 1; else pt->trans = 0;
break;
case 14:
if (a[pt->Y - 1][pt->X - 1] == 0 && a[pt->Y][pt->X - 1] == 0 && a[pt->Y + 1][pt->X - 1] == 0 && a[pt->Y + 2][pt->X - 1] == 0)pt->left = 1;
else pt->left = 0;
if (a[pt->Y - 1][pt->X + 1] == 0 && a[pt->Y][pt->X + 1] == 0 && a[pt->Y + 1][pt->X + 1] == 0 && a[pt->Y + 2][pt->X + 1] == 0)pt->right = 1;
else pt->right = 0;
if (a[pt->Y + 3][pt->X] == 0)pt->down = 1; else pt->down = 0;
if (a[pt->Y][pt->X - 1] == 0 && a[pt->Y][pt->X + 1] == 0 && a[pt->Y][pt->X + 2] == 0)pt->trans = 1; else pt->trans = 0;
break;
case 15:
if (a[pt->Y - 1][pt->X - 2] == 0 && a[pt->Y][pt->X - 1] == 0)pt->left = 1; else pt->left = 0;
if (a[pt->Y - 1][pt->X + 1] == 0 && a[pt->Y][pt->X + 2] == 0)pt->right = 1; else pt->right = 0;
if (a[pt->Y][pt->X - 1] == 0 && a[pt->Y + 1][pt->X] == 0 && a[pt->Y + 1][pt->X + 1] == 0)pt->down = 1; else pt->down = 0;
if (a[pt->Y - 1][pt->X + 1] == 0 && a[pt->Y + 1][pt->X] == 0)pt->trans = 1; else pt->trans = 0;
break;
case 16:
if (a[pt->Y - 1][pt->X] == 0 && a[pt->Y][pt->X - 1] == 0 && a[pt->Y + 1][pt->X - 1] == 0)pt->left = 1; else pt->left = 0;
if (a[pt->Y - 1][pt->X + 2] == 0 && a[pt->Y][pt->X + 2] == 0 && a[pt->Y + 1][pt->X + 1] == 0)pt->right = 1; else pt->right = 0;
if (a[pt->Y + 2][pt->X] == 0 && a[pt->Y + 1][pt->X + 1] == 0)pt->down = 1; else pt->down = 0;
if (a[pt->Y - 1][pt->X - 1] == 0 && a[pt->Y - 1][pt->X] == 0)pt->trans = 1; else pt->trans = 0;
break;
case 17:
if (a[pt->Y - 1][pt->X - 1] == 0 && a[pt->Y][pt->X - 2] == 0)pt->left = 1; else pt->left = 0;
if (a[pt->Y - 1][pt->X + 2] == 0 && a[pt->Y][pt->X + 1] == 0)pt->right = 1; else pt->right = 0;
if (a[pt->Y + 1][pt->X - 1] == 0 && a[pt->Y + 1][pt->X] == 0 && a[pt->Y][pt->X + 1] == 0)pt->down = 1; else pt->down = 0;
if (a[pt->Y][pt->X + 1] == 0 && a[pt->Y + 1][pt->X + 1] == 0)pt->trans = 1; else pt->trans = 0;
break;
case 18:
if (a[pt->Y - 1][pt->X - 2] == 0 && a[pt->Y][pt->X - 2] == 0 && a[pt->Y + 1][pt->X - 1] == 0)pt->left = 1; else pt->left = 0;
if (a[pt->Y - 1][pt->X + 1] == 0 && a[pt->Y][pt->X + 1] == 0 && a[pt->Y + 1][pt->X + 1] == 0)pt->right = 1; else pt->right = 0;
if (a[pt->Y + 1][pt->X - 1] == 0 && a[pt->Y + 2][pt->X] == 0)pt->down = 1; else pt->down = 0;
if (a[pt->Y - 1][pt->X] == 0 && a[pt->Y - 1][pt->X + 1] == 0)pt->trans = 1; else pt->trans = 0;
break;
case 19:
if (a[pt->Y][pt->X - 1] == 0 && a[pt->Y + 1][pt->X - 1] == 0)pt->left = 1; else pt->left = 0;
if (a[pt->Y][pt->X + 2] == 0 && a[pt->Y + 1][pt->X + 2] == 0)pt->right = 1; else pt->right = 0;
if (a[pt->Y + 2][pt->X] == 0 && a[pt->Y + 2][pt->X + 1] == 0)pt->down = 1; else pt->down = 0;
pt->trans = 0;
break;
default:break;
}
}
/****************************************
* 關鍵參數顯示函數(用於偵錯)
****************************************/
#if debug
void JustForDebugging()
{
int i = 0, j = 0;
for (i = 0; i < height + 2; i++)
{
GotoXY(FrameX + 2 * width + 24, FrameY + i);
for (j = 0; j < width + 2; j++)printf("%d", a[i][j]);
}
GotoXY(FrameX + 3 * width + 30, FrameY + 2);
printf("X=%2d", pt->X);
GotoXY(FrameX + 3 * width + 30, FrameY + 3);
printf("Y=%2d", pt->Y);
GotoXY(FrameX + 3 * width + 30, FrameY + 4);
printf("Left=%d", pt->left);
GotoXY(FrameX + 3 * width + 30, FrameY + 5);
printf("Right=%d", pt->right);
GotoXY(FrameX + 3 * width + 30, FrameY + 6);
printf("Down=%d", pt->down);
GotoXY(FrameX + 3 * width + 30, FrameY + 7);
printf("Trans=%d", pt->trans);
fflush(stdout);//清空輸出緩衝區
}
#elif !debug
void JustForDebugging()
{
}
#endif
/****************************************
* 列印下一個俄羅斯方塊
****************************************/
void PrintNextTetris()
{
int i = 0, j = 0;
GotoXY(FrameX + 2 * width + 8, FrameY + 5);
printf("下一個方塊:%2d", pt->kind_next);
for (i = 0; i < 5; i++)
for (j = 0; j < 5; j++)
{
GotoXY(FrameX + 2 * width + 2 * j + 8, FrameY + 6 + i);
if (pt->temp[pt->kind_next][pt->state_next][i][j])printf("[]");
else printf(" ");
}
fflush(stdout);
}
/****************************************
* 清除滿行
****************************************/
void CleanLine()
{
int i = height, j = 1, k = 0, sum = 0;
for (i = height; i > 0; i--)
{
sum = 0;
for (j = 1; j <= width; j++)sum += a[i][j];
if (sum == width)
{
Line++;
for (k = i; k > 1; k--)
for (j = 1; j <= width; j++)a[k][j] = a[k - 1][j];
i++;
}
}
Level = 1 + Line / 10;
Score = Line * 100;
GotoXY(FrameX + 2 * width + 8, FrameY - 1);
printf("Level:%d", Level);
GotoXY(FrameX + 2 * width + 8, FrameY + 1);
printf("積分:%d", Score);
GotoXY(FrameX + 2 * width + 8, FrameY + 3);
printf("消去的行數:%d", Line);
fflush(stdout);
}
/****************************************
* 遊戲開始函數
****************************************/
void GamePlay()
{
system("clear");
Initialization();
DrwaGameframe();
MakeTetris();
DrawNew();
PrintNextTetris();
}
/****************************************
* 自動下落函數
****************************************/
int AutoDown()
{
Judge_MoveAndTansform();
JustForDebugging();
if(pt->down)
{
CleanOld();
pt->Y++;
DrawNew();
}
JustForDebugging();
if(!pt->down)
{
CleanLine();
pt->X=StartX;
pt->Y=StartY;
MakeTetris();
Judge_MoveAndTansform();
if(!pt->down)
{
PrintTetris();
sleep(1);
return 1;
}
PrintTetris();
PrintNextTetris();
}
JustForDebugging();
return 0;
}
/****************************************
* 鍵盤輸入判定
****************************************/
int KeyControl(int ch)
{
if(-1==Suspend||32==ch)
{
Judge_MoveAndTansform();
switch (ch)
{
case 'w':if(pt->trans){CleanOld();Transform();DrawNew();}break;//變形
case 'a':if(pt->left){CleanOld();pt->X--;DrawNew();}break;//向上
case 'd':if(pt->right){CleanOld();pt->X++;DrawNew();}break;//->向右
case 's':if (pt->down){ CleanOld();pt->Y++; DrawNew(); }break;//向下
case 32:Suspend=-Suspend;break;//空格鍵 暫停遊戲
case 27:system("clear");Recovery_terminal();return 1;//ESC鍵 退出
default:break;
}
}
return 0;
}
void *thread_functiona(void *arg)
{
int ret, tmp=0;
while(1)
{
while(1==Suspend);
/*lock*/
ret = pthread_mutex_lock(&lock);
if (0 != ret)
{
perror("pthread_mutex_lock");
pthread_exit(NULL);
}
tmp=AutoDown();
/*unlock*/
ret = pthread_mutex_unlock(&lock);
if (0 != ret)
{
perror("pthread_mutex_unlock");
pthread_exit(NULL);
}
if(tmp)break;
usleep(1000000);
}
pthread_exit(NULL);
}
void *thread_functionb(void *arg)
{
int i, ch=0, ret, tmp;
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
while(1)
{
ch=getchar();
/*lock*/
ret = pthread_mutex_lock(&lock);
if (0 != ret)
{
perror("pthread_mutex_lock");
pthread_exit(NULL);
}
tmp=KeyControl(ch);
/*unlock*/
ret = pthread_mutex_unlock(&lock);
if (0 != ret)
{
perror("pthread_mutex_unlock");
pthread_exit(NULL);
}
if(tmp)break;
}
pthread_cancel(tid_a);
}
void GameRun()
{
int ret;
/*初始化互斥鎖*/
ret = pthread_mutex_init(&lock, NULL);
if (0 != ret)
{
perror("pthread_mutex_init");
exit(EXIT_FAILURE);
}
ret = pthread_create(&tid_a, NULL, thread_functiona, NULL);
if (0 != ret)
{
perror("pthread_create");
exit(EXIT_FAILURE);
}
ret = pthread_create(&tid_b, NULL, thread_functionb, NULL);
if (0 != ret)
{
perror("pthread_create");
exit(EXIT_FAILURE);
}
ret = pthread_join(tid_a, NULL);
if (0 != ret)
{
perror("pthread_join");
exit(EXIT_FAILURE);
}
pthread_cancel(tid_b);
ret = pthread_join(tid_b, NULL);
if (0 != ret)
{
perror("pthread_join");
exit(EXIT_FAILURE);
}
ret = pthread_mutex_destroy(&lock);
if (0 != ret)
{
perror("pthread_mutex_lock");
exit(EXIT_FAILURE);
}
}
int main()
{
loop:
Welcom();
GameRun();
if(1==GameOver())goto loop;
system("clear");
Recovery_terminal();
return 0;
}