日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

c語(yǔ)言俄羅斯方塊游戲代碼QZQ

 EYYLTV 2024-06-22 發(fā)布于廣東

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

#include <time.h>

#include <conio.h>

#include <windows.h>

#ifdef _MSC_VER  // M$的編譯器要給予特殊照顧

#if _MSC_VER <= 1200  // VC6及以下版本

#error 你是不是還在用VC6?!

#else  // VC6以上版本

#if _MSC_VER >= 1600  // 據(jù)說(shuō)VC10及以上版本有stdint.h了

#include <stdint.h>

#else  // VC10以下版本,自己定義int8_t和uint16_t

typedef signed char int8_t;

typedef unsigned short uint16_t;

#endif

#ifndef __cplusplus  // 據(jù)說(shuō)VC都沒有stdbool.h,不用C++編譯,自己定義bool

typedef int bool;

#define true 1

#define false 0

#endif

#endif

#else  // 其他的編譯器都好說(shuō)

#include <stdint.h>

#ifndef __cplusplus  // 不用C++編譯,需要stdbool.h里的bool

#include <stdbool.h>

#endif

#endif

// =============================================================================

// 7種方塊的4旋轉(zhuǎn)狀態(tài)(4位為一行)

static const uint16_t gs_uTetrisTable[7][4] = { { 0x00F0U, 0x2222U, 0x00F0U,

        0x2222U },  // I型

        { 0x0072U, 0x0262U, 0x0270U, 0x0232U },  // T型

        { 0x0223U, 0x0074U, 0x0622U, 0x0170U },  // L型

        { 0x0226U, 0x0470U, 0x0322U, 0x0071U },  // J型

        { 0x0063U, 0x0264U, 0x0063U, 0x0264U },  // Z型

        { 0x006CU, 0x0462U, 0x006CU, 0x0462U },  // S型

        { 0x0660U, 0x0660U, 0x0660U, 0x0660U }   // O型

};

// =============================================================================

// 初始狀態(tài)的游戲池

// 每個(gè)元素表示游戲池的一行,下標(biāo)大的是游戲池底部

// 兩端各置2個(gè)1,底部2全置為1,便于進(jìn)行碰撞檢測(cè)

// 這樣一來(lái)游戲池的寬度為12列

// 如果想要傳統(tǒng)的10列,只需多填兩個(gè)1即可(0xE007),當(dāng)然顯示相關(guān)部分也要隨之改動(dòng)

// 當(dāng)某個(gè)元素為0xFFFFU時(shí),說(shuō)明該行已被填滿

// 頂部4行用于給方塊,不顯示出來(lái)

// 再除去底部2行,顯示出來(lái)的游戲池高度為22行

static const uint16_t gs_uInitialTetrisPool[28] = { 0xC003U, 0xC003U, 0xC003U,

        0xC003U, 0xC003U, 0xC003U, 0xC003U, 0xC003U, 0xC003U, 0xC003U, 0xC003U,

        0xC003U, 0xC003U, 0xC003U, 0xC003U, 0xC003U, 0xC003U, 0xC003U, 0xC003U,

        0xC003U, 0xC003U, 0xC003U, 0xC003U, 0xC003U, 0xC003U, 0xC003U, 0xFFFFU,

        0xFFFFU };

#define COL_BEGIN 2

#define COL_END 14

#define ROW_BEGIN 4

#define ROW_END 26

// =============================================================================

typedef struct TetrisManager  // 這個(gè)結(jié)構(gòu)體存儲(chǔ)游戲相關(guān)數(shù)據(jù)

{

    uint16_t pool[28];  // 游戲池

    int8_t x;  // 當(dāng)前方塊x坐標(biāo),此處坐標(biāo)為方塊左上角坐標(biāo)

    int8_t y;  // 當(dāng)前方塊y坐標(biāo)

    int8_t type[3];  // 當(dāng)前、下一個(gè)和下下一個(gè)方塊類型

    int8_t orientation[3];  // 當(dāng)前、下一個(gè)和下下一個(gè)方塊旋轉(zhuǎn)狀態(tài)

    unsigned score;  // 得分

    unsigned erasedCount[4];  // 消行數(shù)

    unsigned erasedTotal;  // 消行總數(shù)

    unsigned tetrisCount[7];  // 各方塊數(shù)

    unsigned tetrisTotal;  // 方塊總數(shù)

    bool dead;  // 掛

} TetrisManager;

// =============================================================================

typedef struct TetrisControl  // 這個(gè)結(jié)構(gòu)體存儲(chǔ)控制相關(guān)數(shù)據(jù)

{

    bool pause;  // 暫停

    bool clockwise;  // 旋轉(zhuǎn)方向:順時(shí)針為true

    int8_t direction;  // 移動(dòng)方向:0向左移動(dòng) 1向右移動(dòng)

    // 游戲池內(nèi)每格的顏色

    // 由于此版本是彩色的,僅用游戲池?cái)?shù)據(jù)無(wú)法存儲(chǔ)顏色信息

    // 當(dāng)然,如果只實(shí)現(xiàn)單色版的,就沒必要用這個(gè)數(shù)組了

    int8_t color[28][16];

} TetrisControl;

HANDLE g_hConsoleOutput;  // 控制臺(tái)輸出句柄

// =============================================================================

// 函數(shù)聲明

// 如果使用全局變量方式實(shí)現(xiàn),就沒必要傳參了

void initGame(TetrisManager *manager, TetrisControl *control);  // 初始化游戲

void restartGame(TetrisManager *manager, TetrisControl *control);  // 重新開始游戲

void giveTetris(TetrisManager *manager);  // 給一個(gè)方塊

bool checkCollision(const TetrisManager *manager);  // 碰撞檢測(cè)

void insertTetris(TetrisManager *manager);  // 插入方塊

void removeTetris(TetrisManager *manager);  // 移除方塊

void horzMoveTetris(TetrisManager *manager, TetrisControl *control);  // 水平移動(dòng)方塊

void moveDownTetris(TetrisManager *manager, TetrisControl *control);  // 向下移動(dòng)方塊

void rotateTetris(TetrisManager *manager, TetrisControl *control);  // 旋轉(zhuǎn)方塊

void dropDownTetris(TetrisManager *manager, TetrisControl *control);  // 方塊直接落地

bool checkErasing(TetrisManager *manager, TetrisControl *control);  // 消行檢測(cè)

void keydownControl(TetrisManager *manager, TetrisControl *control, int key); // 鍵按下

void setPoolColor(const TetrisManager *manager, TetrisControl *control); // 設(shè)置顏色

void gotoxyWithFullwidth(short x, short y);  // 以全角定位

void printPoolBorder();  // 顯示游戲池邊界

void printTetrisPool(const TetrisManager *manager, const TetrisControl *control); // 顯示游戲池

void printCurrentTetris(const TetrisManager *manager,

        const TetrisControl *control);  // 顯示當(dāng)前方塊

void printNextTetris(const TetrisManager *manager);  // 顯示下一個(gè)和下下一個(gè)方塊

void printScore(const TetrisManager *manager);  // 顯示得分信息

void runGame(TetrisManager *manager, TetrisControl *control);  // 運(yùn)行游戲

void printPrompting();  // 顯示提示信息

bool ifPlayAgain();  // 再來(lái)一次

// =============================================================================

// 出處:http://www.oschina.net/code/snippet_255612_16922

// 主函數(shù)

int main() {

    TetrisManager tetrisManager;

    TetrisControl tetrisControl;

    initGame(&tetrisManager, &tetrisControl);  // 初始化游戲

    do {

        printPrompting();  // 顯示提示信息

        printPoolBorder();  // 顯示游戲池邊界

        runGame(&tetrisManager, &tetrisControl);  // 運(yùn)行游戲

        if (ifPlayAgain())  // 再來(lái)一次

        {

            SetConsoleTextAttribute(g_hConsoleOutput, 0x7);

            system("cls");  // 清屏

            restartGame(&tetrisManager, &tetrisControl);  // 重新開始游戲

        } else {

            break;

        }

    } while (1);

    gotoxyWithFullwidth(0, 0);

    CloseHandle(g_hConsoleOutput);

    return 0;

}

// =============================================================================

// 初始化游戲

void initGame(TetrisManager *manager, TetrisControl *control) {

    CONSOLE_CURSOR_INFO cursorInfo = { 1, FALSE };  // 光標(biāo)信息

    g_hConsoleOutput = GetStdHandle(STD_OUTPUT_HANDLE);  // 獲取控制臺(tái)輸出句柄

    SetConsoleCursorInfo(g_hConsoleOutput, &cursorInfo);  // 設(shè)置光標(biāo)隱藏

    SetConsoleTitleA("俄羅斯方塊");

    restartGame(manager, control);

}

// =============================================================================

// 重新開始游戲

void restartGame(TetrisManager *manager, TetrisControl *control) {

    memset(manager, 0, sizeof(TetrisManager));  // 全部置0

    // 初始化游戲池

    memcpy(manager->pool, gs_uInitialTetrisPool, sizeof(uint16_t[28]));

    srand((unsigned) time(NULL ));  // 設(shè)置隨機(jī)種子

    manager->type[1] = rand() % 7;  // 下一個(gè)

    manager->orientation[1] = rand() & 3;

    manager->type[2] = rand() % 7;  // 下下一個(gè)

    manager->orientation[2] = rand() & 3;

    memset(control, 0, sizeof(TetrisControl));  // 全部置0

    giveTetris(manager);  // 給下一個(gè)方塊

    setPoolColor(manager, control);  // 設(shè)置顏色

}

// =============================================================================

// 給一個(gè)方塊

void giveTetris(TetrisManager *manager) {

    uint16_t tetris;

    manager->type[0] = manager->type[1];  // 下一個(gè)方塊置為當(dāng)前

    manager->orientation[0] = manager->orientation[1];

    manager->type[1] = manager->type[2];  // 下下一個(gè)置方塊為下一個(gè)

    manager->orientation[1] = manager->orientation[2];

    manager->type[2] = rand() % 7;  // 隨機(jī)生成下下一個(gè)方塊

    manager->orientation[2] = rand() & 3;

    tetris = gs_uTetrisTable[manager->type[0]][manager->orientation[0]]; // 當(dāng)前方塊

    // 設(shè)置當(dāng)前方塊y坐標(biāo),保證剛給出時(shí)只顯示方塊最下面一行

    // 這種實(shí)現(xiàn)使得玩家可以以很快的速度將方塊落在不顯示出來(lái)的頂部4行內(nèi)

    if (tetris & 0xF000) {

        manager->y = 0;

    } else {

        manager->y = (tetris & 0xFF00) ? 1 : 2;

    }

    manager->x = 6;  // 設(shè)置當(dāng)前方塊x坐標(biāo)

    if (checkCollision(manager))  // 檢測(cè)到碰撞

            {

        manager->dead = true;  // 標(biāo)記游戲結(jié)束

    } else  // 未檢測(cè)到碰撞

    {

        insertTetris(manager);  // 將當(dāng)前方塊加入游戲池

    }

    ++manager->tetrisTotal;  // 方塊總數(shù)

    ++manager->tetrisCount[manager->type[0]];  // 相應(yīng)方塊數(shù)

    printNextTetris(manager);  // 顯示下一個(gè)方塊

    printScore(manager);  // 顯示得分信息

}

// =============================================================================

// 碰撞檢測(cè)

bool checkCollision(const TetrisManager *manager) {

    // 當(dāng)前方塊

    uint16_t tetris = gs_uTetrisTable[manager->type[0]][manager->orientation[0]];

    uint16_t dest = 0;

    // 獲取當(dāng)前方塊在游戲池中的區(qū)域:

    // 游戲池坐標(biāo)x y處小方格信息,按低到高存放在16位無(wú)符號(hào)數(shù)中

    dest |= (((manager->pool[manager->y + 0] >> manager->x) << 0x0) & 0x000F);

    dest |= (((manager->pool[manager->y + 1] >> manager->x) << 0x4) & 0x00F0);

    dest |= (((manager->pool[manager->y + 2] >> manager->x) << 0x8) & 0x0F00);

    dest |= (((manager->pool[manager->y + 3] >> manager->x) << 0xC) & 0xF000);

    // 若當(dāng)前方塊與目標(biāo)區(qū)域存在重疊(碰撞),則位與的結(jié)果不為0

    return ((dest & tetris) != 0);

}

// =============================================================================

// 插入方塊

void insertTetris(TetrisManager *manager) {

    // 當(dāng)前方塊

    uint16_t tetris = gs_uTetrisTable[manager->type[0]][manager->orientation[0]];

    // 當(dāng)前方塊每4位取出,位或到游戲池相應(yīng)位置,即完成插入方塊

    manager->pool[manager->y + 0] |= (((tetris >> 0x0) & 0x000F) << manager->x);

    manager->pool[manager->y + 1] |= (((tetris >> 0x4) & 0x000F) << manager->x);

    manager->pool[manager->y + 2] |= (((tetris >> 0x8) & 0x000F) << manager->x);

    manager->pool[manager->y + 3] |= (((tetris >> 0xC) & 0x000F) << manager->x);

}

// =============================================================================

// 移除方塊

void removeTetris(TetrisManager *manager) {

    // 當(dāng)前方塊

    uint16_t tetris = gs_uTetrisTable[manager->type[0]][manager->orientation[0]];

    // 當(dāng)前方塊每4位取出,按位取反后位與到游戲池相應(yīng)位置,即完成移除方塊

    manager->pool[manager->y + 0] &=

            ~(((tetris >> 0x0) & 0x000F) << manager->x);

    manager->pool[manager->y + 1] &=

            ~(((tetris >> 0x4) & 0x000F) << manager->x);

    manager->pool[manager->y + 2] &=

            ~(((tetris >> 0x8) & 0x000F) << manager->x);

    manager->pool[manager->y + 3] &=

            ~(((tetris >> 0xC) & 0x000F) << manager->x);

}

// =============================================================================

// 設(shè)置顏色

void setPoolColor(const TetrisManager *manager, TetrisControl *control) {

    // 由于顯示游戲池時(shí),先要在游戲池里判斷某一方格有方塊才顯示相應(yīng)方格的顏色

    // 這里只作設(shè)置即可,沒必要清除

    // 當(dāng)移動(dòng)方塊或給一個(gè)方塊時(shí)調(diào)用

    int8_t i, x, y;

    // 當(dāng)前方塊

    uint16_t tetris = gs_uTetrisTable[manager->type[0]][manager->orientation[0]];

    for (i = 0; i < 16; ++i) {

        y = (i >> 2) + manager->y;  // 待設(shè)置的列

        if (y > ROW_END)  // 超過(guò)底部限制

        {

            break;

        }

        x = (i & 3) + manager->x;  // 待設(shè)置的行

        if ((tetris >> i) & 1)  // 檢測(cè)的到小方格屬于當(dāng)前方塊區(qū)域

                {

            control->color[y][x] = (manager->type[0] | 8);  // 設(shè)置顏色

        }

    }

}

// =============================================================================

// 旋轉(zhuǎn)方塊

void rotateTetris(TetrisManager *manager, TetrisControl *control) {

    int8_t ori = manager->orientation[0];  // 記錄原旋轉(zhuǎn)狀態(tài)

    removeTetris(manager);  // 移走當(dāng)前方塊

    // 順/逆時(shí)針旋轉(zhuǎn)

    manager->orientation[0] =

            (control->clockwise) ? ((ori + 1) & 3) : ((ori + 3) & 3);

    if (checkCollision(manager))  // 檢測(cè)到碰撞

            {

        manager->orientation[0] = ori;  // 恢復(fù)為原旋轉(zhuǎn)狀態(tài)

        insertTetris(manager);  // 放入當(dāng)前方塊。由于狀態(tài)沒改變,不需要設(shè)置顏色

    } else {

        insertTetris(manager);  // 放入當(dāng)前方塊

        setPoolColor(manager, control);  // 設(shè)置顏色

        printCurrentTetris(manager, control);  // 顯示當(dāng)前方塊

    }

}

// =============================================================================

// 水平移動(dòng)方塊

void horzMoveTetris(TetrisManager *manager, TetrisControl *control) {

    int x = manager->x;  // 記錄原列位置

    removeTetris(manager);  // 移走當(dāng)前方塊

    control->direction == 0 ? (--manager->x) : (++manager->x);  // 左/右移動(dòng)

    if (checkCollision(manager))  // 檢測(cè)到碰撞

            {

        manager->x = x;  // 恢復(fù)為原列位置

        insertTetris(manager);  // 放入當(dāng)前方塊。由于位置沒改變,不需要設(shè)置顏色

    } else {

        insertTetris(manager);  // 放入當(dāng)前方塊

        setPoolColor(manager, control);  // 設(shè)置顏色

        printCurrentTetris(manager, control);  // 顯示當(dāng)前方塊

    }

}

// =============================================================================

// 向下移動(dòng)方塊

void moveDownTetris(TetrisManager *manager, TetrisControl *control) {

    int8_t y = manager->y;  // 記錄原行位置

    removeTetris(manager);  // 移走當(dāng)前方塊

    ++manager->y;  // 向下移動(dòng)

    if (checkCollision(manager))  // 檢測(cè)到碰撞

            {

        manager->y = y;  // 恢復(fù)為原行位置

        insertTetris(manager);  // 放入當(dāng)前方塊。由于位置沒改變,不需要設(shè)置顏色

        if (checkErasing(manager, control))  // 檢測(cè)到消行

                {

            printTetrisPool(manager, control);  // 顯示游戲池

        }

    } else {

        insertTetris(manager);  // 放入當(dāng)前方塊

        setPoolColor(manager, control);  // 設(shè)置顏色

        printCurrentTetris(manager, control);  // 顯示當(dāng)前方塊

    }

}

// =============================================================================

// 方塊直接落地

void dropDownTetris(TetrisManager *manager, TetrisControl *control) {

    removeTetris(manager);  // 移走當(dāng)前方塊

    for (; manager->y < ROW_END; ++manager->y)  // 從上往下

            {

        if (checkCollision(manager))  // 檢測(cè)到碰撞

                {

            break;

        }

    }

    --manager->y;  // 上移一格當(dāng)然沒有碰撞

    insertTetris(manager);  // 放入當(dāng)前方塊

    setPoolColor(manager, control);  // 設(shè)置顏色

    checkErasing(manager, control);  // 檢測(cè)消行

    printTetrisPool(manager, control);  // 顯示游戲池

}

// =============================================================================

// 消行檢測(cè)

bool checkErasing(TetrisManager *manager, TetrisControl *control) {

    static const unsigned scores[5] = { 0, 10, 30, 90, 150 };  // 消行得分

    int8_t count = 0;

    int8_t k = 0, y = manager->y + 3;  // 從下往上檢測(cè)

    do {

        if (y < ROW_END && manager->pool[y] == 0xFFFFU)  // 有效區(qū)域內(nèi)且一行已填滿

                {

            ++count;

            // 消除一行方塊

            memmove(manager->pool + 1, manager->pool, sizeof(uint16_t) * y);

            // 顏色數(shù)組的元素隨之移動(dòng)

            memmove(control->color[1], control->color[0],

                    sizeof(int8_t[16]) * y);

        } else {

            --y;

            ++k;

        }

    } while (y >= manager->y && k < 4);

    manager->erasedTotal += count;  // 消行總數(shù)

    manager->score += scores[count];  // 得分

    if (count > 0) {

        ++manager->erasedCount[count - 1];  // 消行

    }

    giveTetris(manager);  // 給下一個(gè)方塊

    setPoolColor(manager, control);  // 設(shè)置顏色

    return (count > 0);

}

// =============================================================================

// 鍵按下

void keydownControl(TetrisManager *manager, TetrisControl *control, int key) {

    if (key == 13)  // 暫停/解除暫停

            {

        control->pause = !control->pause;

    }

    if (control->pause)  // 暫停狀態(tài),不作處理

    {

        return;

    }

    switch (key) {

    case 'w':

    case 'W':

    case '8':

    case 72:  // 上

        control->clockwise = true;  // 順時(shí)針旋轉(zhuǎn)

        rotateTetris(manager, control);  // 旋轉(zhuǎn)方塊

        break;

    case 'a':

    case 'A':

    case '4':

    case 75:  // 左

        control->direction = 0;  // 向左移動(dòng)

        horzMoveTetris(manager, control);  // 水平移動(dòng)方塊

        break;

    case 'd':

    case 'D':

    case '6':

    case 77:  // 右

        control->direction = 1;  // 向右移動(dòng)

        horzMoveTetris(manager, control);  // 水平移動(dòng)方塊

        break;

    case 's':

    case 'S':

    case '2':

    case 80:  // 下

        moveDownTetris(manager, control);  // 向下移動(dòng)方塊

        break;

    case ' ':  // 直接落地

        dropDownTetris(manager, control);

        break;

    case '0':  // 反轉(zhuǎn)

        control->clockwise = false;  // 逆時(shí)針旋轉(zhuǎn)

        rotateTetris(manager, control);  // 旋轉(zhuǎn)方塊

        break;

    default:

        break;

    }

}

// =============================================================================

// 以全角定位

void gotoxyWithFullwidth(short x, short y) {

    static COORD cd;

    cd.X = (short) (x << 1);

    cd.Y = y;

    SetConsoleCursorPosition(g_hConsoleOutput, cd);

}

// =============================================================================

// 顯示游戲池邊界

void printPoolBorder() {

    int8_t y;

    SetConsoleTextAttribute(g_hConsoleOutput, 0xF0);

    for (y = ROW_BEGIN; y < ROW_END; ++y)  // 不顯示頂部4行和底部2行

            {

        gotoxyWithFullwidth(10, y - 3);

        printf("%2s", "");

        gotoxyWithFullwidth(23, y - 3);

        printf("%2s", "");

    }

    gotoxyWithFullwidth(10, y - 3);  // 底部邊界

    printf("%28s", "");

}

// 定位到游戲池中的方格

#define gotoxyInPool(x, y) gotoxyWithFullwidth(x + 9, y - 3)

// =============================================================================

// 顯示游戲池

void printTetrisPool(const TetrisManager *manager, const TetrisControl *control) {

    int8_t x, y;

    for (y = ROW_BEGIN; y < ROW_END; ++y)  // 不顯示頂部4行和底部2行

            {

        gotoxyInPool(2, y);

        // 定點(diǎn)到游戲池中的方格

        for (x = COL_BEGIN; x < COL_END; ++x)  // 不顯示左右邊界

                {

            if ((manager->pool[y] >> x) & 1)  // 游戲池該方格有方塊

                    {

                // 用相應(yīng)顏色,顯示一個(gè)實(shí)心方塊

                SetConsoleTextAttribute(g_hConsoleOutput, control->color[y][x]);

                printf("■");

            } else  // 沒有方塊,顯示空白

            {

                SetConsoleTextAttribute(g_hConsoleOutput, 0);

                printf("%2s", "");

            }

        }

    }

}

// =============================================================================

// 顯示當(dāng)前方塊

void printCurrentTetris(const TetrisManager *manager,

        const TetrisControl *control) {

    int8_t x, y;

    // 顯示當(dāng)前方塊是在移動(dòng)后調(diào)用的,為擦去移動(dòng)前的方塊,需要擴(kuò)展顯示區(qū)域

    // 由于不可能向上移動(dòng),故不需要向下擴(kuò)展

    y = (manager->y > ROW_BEGIN) ? (manager->y - 1) : ROW_BEGIN;  // 向上擴(kuò)展一格

    for (; y < ROW_END && y < manager->y + 4; ++y) {

        x = (manager->x > COL_BEGIN) ? (manager->x - 1) : COL_BEGIN;  // 向左擴(kuò)展一格

        for (; x < COL_END && x < manager->x + 5; ++x)  // 向右擴(kuò)展一格

                {

            gotoxyInPool(x, y);

            // 定點(diǎn)到游戲池中的方格

            if ((manager->pool[y] >> x) & 1)  // 游戲池該方格有方塊

                    {

                // 用相應(yīng)顏色,顯示一個(gè)實(shí)心方塊

                SetConsoleTextAttribute(g_hConsoleOutput, control->color[y][x]);

                printf("■");

            } else  // 沒有方塊,顯示空白

            {

                SetConsoleTextAttribute(g_hConsoleOutput, 0);

                printf("%2s", "");

            }

        }

    }

}

// =============================================================================

// 顯示下一個(gè)和下下一個(gè)方塊

void printNextTetris(const TetrisManager *manager) {

    int8_t i;

    uint16_t tetris;

    // 邊框

    SetConsoleTextAttribute(g_hConsoleOutput, 0xF);

    gotoxyWithFullwidth(26, 1);

    printf("┏━━━━┳━━━━┓");

    gotoxyWithFullwidth(26, 2);

    printf("┃%8s┃%8s┃", "", "");

    gotoxyWithFullwidth(26, 3);

    printf("┃%8s┃%8s┃", "", "");

    gotoxyWithFullwidth(26, 4);

    printf("┃%8s┃%8s┃", "", "");

    gotoxyWithFullwidth(26, 5);

    printf("┃%8s┃%8s┃", "", "");

    gotoxyWithFullwidth(26, 6);

    printf("┗━━━━┻━━━━┛");

    // 下一個(gè),用相應(yīng)顏色顯示

    tetris = gs_uTetrisTable[manager->type[1]][manager->orientation[1]];

    SetConsoleTextAttribute(g_hConsoleOutput, manager->type[1] | 8);

    for (i = 0; i < 16; ++i) {

        gotoxyWithFullwidth((i & 3) + 27, (i >> 2) + 2);

        ((tetris >> i) & 1) ? printf("■") : printf("%2s", "");

    }

    // 下下一個(gè),不顯示彩色

    tetris = gs_uTetrisTable[manager->type[2]][manager->orientation[2]];

    SetConsoleTextAttribute(g_hConsoleOutput, 8);

    for (i = 0; i < 16; ++i) {

        gotoxyWithFullwidth((i & 3) + 32, (i >> 2) + 2);

        ((tetris >> i) & 1) ? printf("■") : printf("%2s", "");

    }

}

// =============================================================================

// 顯示得分信息

void printScore(const TetrisManager *manager) {

    static const char *tetrisName = "ITLJZSO";

    int8_t i;

    SetConsoleTextAttribute(g_hConsoleOutput, 0xE);

    gotoxyWithFullwidth(2, 2);

    printf("■得分:%u", manager->score);

    gotoxyWithFullwidth(1, 6);

    printf("■消行總數(shù):%u", manager->erasedTotal);

    for (i = 0; i < 4; ++i) {

        gotoxyWithFullwidth(2, 8 + i);

        printf("□消%d:%u", i + 1, manager->erasedCount[i]);

    }

    gotoxyWithFullwidth(1, 15);

    printf("■方塊總數(shù):%u", manager->tetrisTotal);

    for (i = 0; i < 7; ++i) {

        gotoxyWithFullwidth(2, 17 + i);

        printf("□%c形:%u", tetrisName[i], manager->tetrisCount[i]);

    }

}

// =============================================================================

// 顯示提示信息

void printPrompting() {

    SetConsoleTextAttribute(g_hConsoleOutput, 0xB);

    gotoxyWithFullwidth(26, 10);

    printf("■控制:");

    gotoxyWithFullwidth(27, 12);

    printf("□向左移動(dòng):← A 4");

    gotoxyWithFullwidth(27, 13);

    printf("□向右移動(dòng):→ D 6");

    gotoxyWithFullwidth(27, 14);

    printf("□向下移動(dòng):↓ S 2");

    gotoxyWithFullwidth(27, 15);

    printf("□順時(shí)針轉(zhuǎn):↑ W 8");

    gotoxyWithFullwidth(27, 16);

    printf("□逆時(shí)針轉(zhuǎn):0");

    gotoxyWithFullwidth(27, 17);

    printf("□直接落地:空格");

    gotoxyWithFullwidth(27, 18);

    printf("□暫停游戲:回車");

    gotoxyWithFullwidth(25, 23);

    printf("■By: wohaaitinciu 12.12.29");

}

// =============================================================================

// 運(yùn)行游戲

void runGame(TetrisManager *manager, TetrisControl *control) {

    clock_t clockLast, clockNow;

    clockLast = clock();  // 計(jì)時(shí)

    printTetrisPool(manager, control);  // 顯示游戲池

    while (!manager->dead)  // 沒掛

    {

        while (_kbhit())  // 有鍵按下

        {

            keydownControl(manager, control, _getch());  // 處理按鍵

        }

        if (!control->pause)  // 未暫停

        {

            clockNow = clock();  // 計(jì)時(shí)

            // 兩次記時(shí)的間隔超過(guò)0.45秒

            if (clockNow - clockLast > 0.45F * CLOCKS_PER_SEC ) {

                clockLast = clockNow;

                keydownControl(manager, control, 80);  // 方塊往下移

            }

        }

    }

}

// =============================================================================

// 再來(lái)一次

bool ifPlayAgain() {

    int ch;

    SetConsoleTextAttribute(g_hConsoleOutput, 0xF0);

    gotoxyWithFullwidth(15, 10);

    printf("游戲結(jié)束");

    gotoxyWithFullwidth(13, 11);

    printf("按Y重玩,按N退出");

    do {

        ch = _getch();

        if (ch == 'Y' || ch == 'y') {

            return true;

        } else if (ch == 'N' || ch == 'n') {

            return false;

        }

    } while (1);

}

    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約