windows和linux下基於C語言的俄羅斯方塊

2020-08-12 20:24:46

檔案下載地址

https://github.com/GitHubYuanHao/Tetris_C

windows版執行結果

單色版
在这里插入图片描述
在这里插入图片描述
彩色版
在这里插入图片描述
在这里插入图片描述

linux版執行結果

在这里插入图片描述
在这里插入图片描述

單色版程式碼

#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;
}

Linux版程式碼

#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;
}