zoukankan      html  css  js  c++  java
  • C++俄罗斯方块

    #include <iostream>
    #include <windows.h>
    #include <vector>
    #include <mmsystem.h>

    #pragma comment(lib, "winmm.lib")
    using namespace std;

    #define GameW 10
    #define GameH 20
    const int CtrlLeft = GameW*2+4 + 3;

    /*

    一、const int
    在定义变量的时候必须初始化,否则报错。

    二、const int *
    声明该指针变量指向的是常量,即该指针变量的内容可以改变,但是该内容指向的内容不可改变!

    因为delete只是告诉系统,现在p所指向的这块内存已还给自由存储区,不再被使用,可以被其他程序改写。而此时p依旧指向这块不可使用的内存,故需要对p进行清零。

    三、int *const
    声明该指针变量为常变量,即指针变量里面的内容不可改变,但是该内容指向的内容可以改变!

    四、const int * cosnt
    声明该指针变量里面的内容不可改变,同时该内容指向的内容亦不可改变。

    五、const int &
    在引用前面加上const,代表该引用为常引用,即被引用的对象不可改变。若是在形参中使用,则不可达到在函数里面修改变量值的目的。

    */

    struct Point {
    Point(){}
    Point(int x, int y) {_x = x, _y = y;}
    //有参数的构造函数
    int _x, _y;
    };

    HANDLE g_hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
    HANDLE g_hInput = GetStdHandle(STD_INPUT_HANDLE);

    //GetStdHandle 返回的句柄可供需要在控制台中进行读取或写入的应用程序使用。

    Point g_ptCursor(0,0);
    BOOL isChecking = FALSE;
    BOOL g_bGameOver = FALSE;

    int g_nGameBack[GameH][GameW], Case;
    int nowKeyInfo = -1;
    int g_nDiff = 1;
    int g_nLife = 2;
    int g_nScore = 0;

    //模块1设置指定控制台屏幕缓冲区中的光标位置。

    void SetCursor(COORD cd) {
    SetConsoleCursorPosition(g_hOutput, cd);
    }


    void SetCursor(int x, int y){
    COORD cd = {x, y};
    SetCursor(cd);
    }


    void SetBlockCursor(int x, int y){
    COORD cd = {2*x + 2, y + 1};
    SetCursor(cd);
    }

    void SetBack(int x, int y, BOOL bk) {
    SetBlockCursor(x, y);
    if (bk)
    printf("%s", "■");
    else
    printf(" ");
    }

    bool Out(int x, int y) {
    return x < 0 || y < 0 || x >= GameW || y >= GameH;
    }

    struct xBlock {
    public:
    int len;
    int nowRotateID;
    BOOL mask[4][4][4];
    static vector <xBlock> List;

    xBlock() { len = 0; }
    xBlock(int l, char *str) {
    int i, j, k;
    len = l;
    memset(mask, FALSE, sizeof(mask));
    for(i = 0; i < l; i++) {
    for(j = 0; j < l; j++) {
    mask[0][i][j] = str[i*l + j] - '0';
    }
    }
    for(k = 1; k < 4; k++) {
    for(i = 0; i < len; i++) {
    for(j = 0; j < len; j++) {
    mask[k][i][j] = mask[k-1][j][len-1-i];
    }
    }
    }
    nowRotateID = rand() % 4;
    }

    void rotate() {
    nowRotateID ++;
    if (nowRotateID >= 4)
    nowRotateID = 0;
    }

    BOOL getUnit(int x, int y, int roID) {
    if (roID == -1) {
    roID = nowRotateID;
    }
    return mask[roID][y][x];
    }
    };

    vector <xBlock> xBlock::List;

    class Block {
    public:
    int x, y;
    int ID;
    xBlock bk;

    void reset(xBlock *pbk) {
    bk = *pbk;

    x = 4, y = 0;
    ID = ++ Case;

    if(collide(0,0)) {
    lifeDown();
    }
    draw();

    *pbk = xBlock::List[rand() % xBlock::List.size()];
    }

    void lifeDown() {
    int i, j;
    for(i = 0; i < GameH; i++) {
    for(j = 0; j < GameW; j++) {
    SetBack(j, i, TRUE);
    Sleep(10);
    }
    }
    if(g_nLife) {
    g_nLife --;
    for(i = g_nLife; i < 6; i++) {
    SetCursor(CtrlLeft + i, 15);
    printf("%c", ' ');
    }
    for(i = GameH-1; i >= 0; i--) {
    for(j = GameW-1; j >= 0; j--) {
    SetBack(j, i, FALSE);
    Sleep(10);
    g_nGameBack[i][j] = 0;
    }
    }
    }else {
    g_bGameOver = TRUE;
    }
    }

    void erase() {
    int i, j;
    for(i = 0; i < bk.len; i++) {
    for(j = 0; j < bk.len; j++) {
    if (bk.getUnit(j, i, -1)) {
    if(!Out(j+x, i+y) && g_nGameBack[i+y][j+x]) {
    SetBack(j+x, i+y, FALSE);
    g_nGameBack[i+y][j+x] = 0;
    }
    }
    }
    }
    }
    void draw() {
    int i, j;
    for(i = 0; i < bk.len; i++) {
    for(j = 0; j < bk.len; j++) {
    if (bk.getUnit(j, i, -1)) {
    if(!Out(j+x, i+y) && !g_nGameBack[i+y][j+x]) {
    SetBack(j+x, i+y, TRUE);
    g_nGameBack[i+y][j+x] = ID;
    }
    }
    }
    }
    }
    void draw(int x, int y) {
    int i, j;
    for(i = 0; i < 4; i++) {
    for(j = 0; j < 4; j++) {
    SetCursor(x + 2*j, y + i);
    if (bk.getUnit(j, i, -1)) {
    printf("%s", "■");
    }else
    printf(" ");
    }
    }
    }
    bool collide(int dx, int dy, int roID = -1) {
    int i, j;
    for(i = 0; i < bk.len; i++) {
    for(j = 0; j < bk.len; j++) {
    if (bk.getUnit(j, i, roID)) {
    Point ptPos(j + x + dx, i + y + dy);
    if(Out(ptPos._x, ptPos._y)
    || g_nGameBack[ptPos._y][ptPos._x] && ID != g_nGameBack[ptPos._y][ptPos._x]) {
    return TRUE;
    }
    }
    }
    }
    return FALSE;
    }

    void rotate(int nTimes = 1) {
    int nextro = (bk.nowRotateID + nTimes) % 4;
    if(collide(0, 0, nextro)) {
    return ;
    }
    Beep(12000, 50);
    erase();
    bk.nowRotateID = nextro;
    draw();
    }

    BOOL changepos(int dx, int dy) {
    if(collide(dx, dy)) {
    return FALSE;
    }
    erase();
    x += dx;
    y += dy;
    draw();
    return TRUE;
    }
    };

    void GameInit() {
    CONSOLE_CURSOR_INFO cursor_info;
    cursor_info.bVisible = FALSE;
    cursor_info.dwSize = 100;
    SetConsoleCursorInfo(g_hOutput,&cursor_info);
    xBlock::List.push_back(xBlock(3, "010111000"));
    //倒立T
    xBlock::List.push_back(xBlock(3, "110110000"));
    //方块
    xBlock::List.push_back(xBlock(3, "111001000"));
    //正立T
    xBlock::List.push_back(xBlock(3, "111100000"));
    //侧立I
    xBlock::List.push_back(xBlock(3, "110011000"));
    //z
    xBlock::List.push_back(xBlock(3, "011110000"));
    //倒立T
    xBlock::List.push_back(xBlock(4, "1000100010001000"));
    //正立I
    }

    void DrawFrame(int x, int y, int nWidth, int nHeight) {
    int i;
    for(i = 0; i < nWidth; i++) {
    SetCursor(x + 2*i + 2, y);
    printf("%s", "一");
    SetCursor(x + 2*i + 2, y + nHeight+1);
    printf("%s", "┄");
    }
    for(i = 0; i < nHeight; i++) {
    SetCursor(x, y + i + 1);
    printf("%s", "┆");
    SetCursor(x + nWidth*2+2, y + i + 1);
    printf("%s", "┆");
    }
    SetCursor(x, y);
    printf("%s", "┌");
    SetCursor(x, y + nHeight+1);
    printf("%s", "└");
    SetCursor(x + nWidth*2+2, y);
    printf("%s", "┐");
    SetCursor(x + nWidth*2+2, y + nHeight+1);
    printf("%s", "┘");
    }

    void MissionInit() {
    memset(g_nGameBack, FALSE, sizeof(g_nGameBack));
    Case = 1;
    int i;
    DrawFrame(0, 0, GameW, GameH);
    DrawFrame(GameW*2+4, 0, 4, GameH);
    SetCursor(CtrlLeft, 2);
    printf("Next");

    SetCursor(CtrlLeft, 8);
    printf("Speed");
    for(i = 0; i < g_nDiff; i++) {
    SetCursor(CtrlLeft + i, 9);
    printf("%c", 1);
    }

    SetCursor(CtrlLeft, 11);
    printf("Score");
    SetCursor(CtrlLeft, 12);
    printf("%d", g_nScore);

    SetCursor(CtrlLeft, 14);
    printf("Life");
    for(i = 0; i < g_nLife; i++) {
    SetCursor(CtrlLeft + i, 15);
    printf("%c", 3);
    }

    SetCursor(CtrlLeft-1, 19);
    SetCursor(CtrlLeft-1, 20);
    }

    void Check() {
    isChecking = TRUE;
    int i, j, k;
    vector <int> line;
    for(i = 0; i < GameH; i++) {
    for(j = 0; j < GameW; j++) {
    if(!g_nGameBack[i][j])
    break;
    }
    if(j == GameW) {
    line.push_back(i);
    }
    }
    if(line.size()) {
    int nCount = 7;
    while(nCount --) {
    for(i = 0; i < line.size(); i++) {
    for(j = 0; j < GameW; j++) {
    SetBack(j, line[i], nCount&1);
    }
    }
    Sleep(70);
    }
    for(i = 0; i < line.size(); i++) {
    for(j = 0; j < GameW; j++) {
    g_nGameBack[line[i]][j] = 0;
    }
    }

    for(i = 0; i < GameW; i++) {
    int next = GameH-1;
    for(j = GameH-1; j >= 0; j--) {
    for(k = next; k >= 0; k--) {
    if(g_nGameBack[k][i])
    break;
    }
    next = k - 1;
    BOOL is = (k >= 0);
    SetBack(i, j, is);
    g_nGameBack[j][i] = is;
    }
    }

    g_nScore += 2*line.size()-1;
    SetCursor(CtrlLeft, 12);
    printf("%d", g_nScore);

    if( g_nScore >= g_nDiff * g_nDiff * 10) {
    if(g_nDiff <= 6)
    g_nDiff ++;
    }
    if( g_nScore >= 50 * (g_nLife+1)) {
    if(g_nLife <= 6)
    g_nLife ++;
    }
    }

    isChecking = FALSE;
    }
    int main() {
    Block* obj = new Block();
    Block* buf = new Block();


    BOOL bCreateNew = FALSE;
    int nTimer = GetTickCount();
    int LastKeyDownTime = GetTickCount();


    GameInit();
    MissionInit();

    buf->bk = xBlock::List[rand() % xBlock::List.size()];
    while(1) {
    if(!bCreateNew) {
    bCreateNew = TRUE;
    obj->reset(&buf->bk);
    if(g_bGameOver)
    break;
    buf->draw(CtrlLeft - 1, 4);
    }
    if (GetTickCount() - nTimer >= 1000 / g_nDiff) {
    nTimer = GetTickCount();
    if (!obj->collide(0, 1))
    obj->changepos(0, 1);
    else {
    Check();
    bCreateNew = FALSE;
    }
    }
    if (GetTickCount() - LastKeyDownTime >= 100) {
    if(FALSE == isChecking) {
    LastKeyDownTime = GetTickCount();
    if (GetAsyncKeyState(VK_UP)) {
    obj->rotate();
    }
    if (GetAsyncKeyState(VK_LEFT)) {
    obj->changepos(-1, 0);
    }
    if (GetAsyncKeyState(VK_RIGHT)) {
    obj->changepos(1, 0);
    }
    if (GetAsyncKeyState(VK_DOWN)) {
    if( FALSE == obj->changepos(0, 2) )
    obj->changepos(0, 1);
    }
    }
    }
    }
    SetCursor(8, 10);
    printf("Game Over");

    SetCursor(0, GameH+3);
    printf("按ESC键退出游戏");

    while(1) {
    if (GetAsyncKeyState(VK_ESCAPE))
    break;
    }
    return 0;
    }

    欢迎来我们oj刷题 oj地址:http://www.npumdacm.top/
  • 相关阅读:
    JVM学习五:JVM之类加载器之编译常量和主动使用
    JVM学习一:JVM之类加载器概况
    JVM学习三:JVM之类加载器之连接分析
    JVM学习二:JVM之类加载器之加载分析
    JVM学习四:JVM之类加载器之初始化分析
    高斯滤波详解 附python和matlab高斯滤波代码
    图像最大池化
    图像平均池化 pytorch库中的平均池化
    图像色彩量化处理
    图像RGB到HSV色彩空间转换及其逆变换
  • 原文地址:https://www.cnblogs.com/tlysMoodspace/p/14697383.html
Copyright © 2011-2022 走看看