Linux下俄罗斯方块程序设计(c++)-转

14 篇文章 0 订阅

Linux下俄罗斯方块程序设计(c++)-转

  • 空间

http://fangnux.blog.51cto.com/7902770/1347375



话不多说先上图:

   很多在windows下做的,用的图形图像的库,监听键盘的线程也是封装好的,大家在看我的程序时就会发现,所有东西都是最原始的,相比较而言更原始更原汁原味一点。

   接下来我把正个程序一点一点拆开与大家分享。

1:cur.h文件(我们打印图像,自然要移动光标,大家是不是对移动光标很有兴趣?马上教你怎么实现!)


#ifndef CUR_H_

#define CUR_H_

#include<iostream>

using namespace std;

class Cur{

public:

        void saveCur();             //保存光标位置

        void moveCur(const int x,const int y);  //移动光标位置到(x,y)坐标

        void resumeCur();           //恢复光标位置

};

#endif

   实现cur.cpp文件


void Cur::moveCur(const int x,const int y)

{

    int i;

    for(i = 0; i < y; i++)

        printf("\33[2C");

    for(i = 0; i < x; i++)

        printf("\33[1B");

}

void Cur::saveCur()

{

    //save cur and move to destination

    printf("\33[s");  

}

void Cur::resumeCur()

{

    printf("\33[u");

}

   是不是移动光标比想象中的简单的多?这样封装起来一旦你的程序中想把光标移到哪就只需要搞一个Cur对象,然后就想在哪打印就在哪打印了。用起来很方便,而且还可以用在其它程序中。

2:cubePoint.h文件,屏幕上怎样打印一个小方块(各种颜色的)?然后我们就用小方块组成我们想要


#ifndef CUBEPOINT_H_

#define CUBEPOINT_H_

#include<iostream>

#include "cur.h"

using namespace std;

enum color{

    CLEAR = 0,

    BLACK = 30,

    RED,

    GREEN,

    YELLOW,

    BLUE,

    PURPLE,

    DEEP_GREEN,

    WHITE

};

/*

 * 每个点显然有个坐标值

 * 每个点有一个颜色

 */

class CubePoint{

protected:

    int color;

    int x;

    int y; //每个方格点有颜色属性,坐标属性

public:

    CubePoint()

    {

        color = CLEAR;

        x = 0;

        y = 0;

    }

    CubePoint(int a,int b,int c)

    {

        color = a;

        x = b;

        y = c;

    }

    void setLocate(const int x,const int y){this->x = x;this->y = y;}

    void setColor(const int color){this->color = color;}

                                                                                                                                                                                                            

    int getColor(){return color;}

    void getLocate(int&x,int &y){x = this->x;y = this->y;}

    //打印点的方法

    void printPoint();

};

#endif

实现cubePoint.cpp  我们同样是使用强大的printf函数打印各种各样的点,这里就需要移动光标了!



void CubePoint::printPoint()

{

    Cur cur;

    cur.saveCur();

    cur.moveCur(x,y);

    switch(color)

    {

         case BLACK     :printf("\033[40;30m  \033[0m");break;

         case RED       :printf("\033[41;31m  \033[0m");break;

         case GREEN     :printf("\033[42;32m  \033[0m");break;

         case YELLOW    :printf("\033[43;33m  \033[0m");break;

         case BLUE      :printf("\033[44;34m  \033[0m");break;

         case PURPLE    :printf("\033[45;35m  \033[0m");break;

         case DEEP_GREEN:printf("\033[46;36m  \033[0m");break;

         case WHITE     :printf("\033[47;37m  \033[0m");break;

         case CLEAR     :printf("\033[8m  ");

         default:

         break;

    }

    cur.resumeCur();

}

可能很多人没这样用过printf函数吧,赶紧去试试!最后一个CLEAR是擦出,也放到一起了,使用起来也方便~

3:图形工厂闪亮登场!graph.h我每种方块是用一个3X3的数组保存的(所以我的长条形状只有三格长度,不是为了做游戏而做游戏,咱的目的是实现功能,从而更好的了解c++对吧。)



#include <iostream>

using namespace std;

#include <stdio.h>

#include "cubePoint.h"

#include <stdlib.h>

#define DOWN 0

#define LEFT 1

#define RIGHT 2

class Gbase{

protected:

    int x;

    int y;  //a[0][0]的位置

    int a[3][3];

public:

    Gbase(){

        int i,j;

        x = 0;

        y = 0;

        for(j = 0; j < 3; j++)

        for(i = 0; i < 3; i++)

        a[i][j] = 0;

    }

    int move(int dir);

    virtual int roll();

    virtual void draw(){}

    void setLocate(int a,int b){x = a;y = b;}

    void getLocate(int* a,int* b){*a = x;*b = y;}

    void printG(int color);

    //获取数组首地址

    void* getArray(){return (void*)a;}

};

class Zgraph : public Gbase{

public:

    void draw(){

        a[0][0] = 1;

        a[0][1] = 1;

        a[0][2] = 0;

        a[1][0] = 0;

        a[1][1] = 1;

        a[1][2] = 1;

        a[2][0] = 0;

        a[2][1] = 0;

        a[2][2] = 0;

    }

};

class Tgraph : public Gbase{

public:

    void draw(){

        a[0][0] = 1;

        a[0][1] = 1;

        a[0][2] = 1;

        a[1][0] = 0;

        a[1][1] = 1;

        a[1][2] = 0;

        a[2][0] = 0;

        a[2][1] = 0;

        a[2][2] = 0;

    }

};

class Ograph : public Gbase{

public:

    void draw(){

        a[0][0] = 1;

        a[0][1] = 1;

        a[0][2] = 0;

        a[1][0] = 1;

        a[1][1] = 1;

        a[1][2] = 0;

        a[2][0] = 0;

        a[2][1] = 0;

        a[2][2] = 0;

    }

    virtual int roll(){};

};

class Igraph : public Gbase{

public:

    void draw(){

        a[0][0] = 0;

        a[0][1] = 1;

        a[0][2] = 0;

        a[1][0] = 0;

        a[1][1] = 1;

        a[1][2] = 0;

        a[2][0] = 0;

        a[2][1] = 1;

        a[2][2] = 0;

    }

};

class Lgraph : public Gbase{

public:

    void draw(){

        a[0][0] = 0;

        a[0][1] = 1;

        a[0][2] = 0;

        a[1][0] = 0;

        a[1][1] = 1;

        a[1][2] = 0;

        a[2][0] = 0;

        a[2][1] = 1;

        a[2][2] = 1;

    }

};

class Context

{

private:

    Gbase* gbase;

public:

    ~Context()

    {

        delete gbase;

    }

    Context(char cType)

    {

        switch(cType)

        {

            case 'Z':

                gbase = new Zgraph();

                break;

            case 'T':

                gbase = new Tgraph();

                break;

            case 'O':

                gbase = new Ograph();

                break;

            case 'I':

                gbase = new Igraph();

                break;

            case 'L':

                gbase = new Lgraph();

                break;

            default:

                printf("no %c type\n",cType);

                break;

        }

    }

    int move(int dir){return gbase->move(dir);}

    int roll(){return gbase->roll();}

    void draw(){gbase->draw();}

    void setLocate(int a,int b){gbase->setLocate(a,b);}

    void getLocate(int *a,int* b){gbase->getLocate(a,b);}

    void* getArray(){gbase->getArray();}

    void printG(int color){gbase->printG(color);}

};

这里用了一个图形的基类Gbase然后五个方块就五个子类(所以你自己想添加新的形状就去继承就可以了)外加一个Context类,这就是一个类似工厂的玩意儿,当然这里还使用到了策略模式。这样我们在处理逻辑的时候就可以将Context类作为接口,不需要关心什么基类子类了,用起来更方便。

   实现很简单graph.cpp



void Gbase::printG(int color)

{

    int i,j;

    CubePoint p;

    for(i = x; i < x+3; i++)

        for(j = y; j < y+3; j++)

        {

            if(a[i - x][j - y] == 1)

            {

                p.setLocate(i,j);

                p.setColor(color);

                p.printPoint();

            }

        }

}

int Gbase::move(int dir)

{

    switch(dir)

    {

        case DOWN:x++;break;

        case LEFT:y--;break;

        case RIGHT:y++;break;

        default:

                break;

    }

    return 0;

}

int Gbase::roll()

{

    int i,j;

    int b[3][3];

    for(i = 0; i < 3; i++)

        for(j = 0; j < 3; j++)

        {

            b[2-j][i] = a[i][j];

        }

    for(i = 0; i < 3; i++)

        for(j = 0; j < 3; j++)

        {

            a[i][j] = b[i][j];

        }

}

到此为止,准备工作基本完成了,现在就可以开始处理逻辑了,我们得把程序跑在面板上

4:game.h


#include "graph.h"

class Game

{

private:

    int m_penal[24][17];

    Context* m_graph;

    int x;

    int y;//当前方块的位置,方块移动或者旋转成功后才可以设置这个值

private:

    //恢复设置(方块会探索下一个位置是否合法,不合法需恢复面板)

    bool recoverPenal();

    //是否着陆(是否碰到下边)

    bool isAttachBottom();

    //是否碰到左边

    bool isAttachLeft();

    //是否碰到右边

    bool isAttachRight();

    //随机获取方块形状

    char getShape();

    //用方块数组给面板数组赋值

    bool setPenal();

    //方块动过后要把遗留面板信息擦除

    bool erasePenal();

public:

    Game();

    //随机创建方块的方法

    void createCube();

    //移动的方法,移动的过程中对m_penal的改变

    void move(int dir);

    //旋转的方法。。。

    void roll();

    //方块停止

    void stop();

    //擦除满行

    void erase();

    //擦除完上面的图形整块坠落

    void down(int level);

};

实现:要处理的逻辑还是比较多的,但是基本看代码就能看懂,我就直接贴上去了

game.cpp




214

215




#define PENAL_SIZE (17*24*sizeof(int))

#define CUBE_SIZE (3*3*sizeof(int))

Game::Game()

{

    m_graph = NULL;

    x = 1;

    y = 7;

    CubePoint p;

    int i;

    memset((void*)m_penal,0,PENAL_SIZE);

   for(i = 0; i < 24; i++)

   {

        p.setLocate(i,0);

        p.setColor(BLUE);

        p.printPoint();

        p.setLocate(i,16);

        p.setColor(BLUE);

        p.printPoint();

        m_penal[i][0] = 1;

        m_penal[i][16] = 1;

   }

   for(i = 0; i < 17; i++)

   {

        p.setLocate(23,i);

        p.setColor(BLUE);

        p.printPoint();

        p.setLocate(0,i);

        p.setColor(RED);

        p.printPoint();

        m_penal[23][i] = 1;

        m_penal[0][i] = 1;

   }

   /*测试面板值是否正常

   for(i = 0; i < 24; i++)

   {

        for(int j = 0; j < 17; j++)

            cout << m_penal[i][j] <<" ";

        cout << endl;

   }

   */

   fflush(stdout);

}

char Game::getShape()

{

    Rand r;

    char ch;

    switch(r.randNum(1,6))

    {

        case 1:ch = 'Z';break;

        case 2:ch = 'T';break;

        case 3:ch = 'O';break;

        case 4:ch = 'I';break;

        case 5:ch = 'L';break;

        default:

               cout<<"no this shape type"<<endl;

               ch = '\0';

               break;

    }

    return ch;

}

bool Game::erasePenal()

{

    int i,j;

    int b[3][3] = {0};  //获取方块数组

    m_graph->printG(CLEAR);

    memcpy(b,m_graph->getArray(),CUBE_SIZE);

    for(i = 0; i < 3; i++)

        for(j = 0; j < 3; j++)

        {

            m_penal[i + x][j + y] -= b[i][j];

        }

    return true;

}

bool Game::recoverPenal()

{

    int i,j;

    int b[3][3] = {0};  //获取方块数组

    memcpy(b,m_graph->getArray(),CUBE_SIZE);

    for(i = x; i < x + 3; i++)

        for(j = y; j < y + 3; j++)

        {

            m_penal[i][j] += b[i-x][j-y];

        }

    return true;

}

bool Game::setPenal()

{

    int i,j;

    int b[3][3] = {0};  //获取方块数组

    m_graph->getLocate(&x,&y);

    memcpy(b,m_graph->getArray(),CUBE_SIZE);

    /*测试取到方块数组是否正常

    for(i = 0;i < 3; i++)

    {

        for(j = 0; j < 3; j++)

            cout<<b[i][j]<< " ";

        cout<<endl;

    }

    */

    for(i = x; i < x + 3; i++)

        for(j = y; j < y + 3; j++)

        {

            m_penal[i][j] += b[i-x][j-y];

            if(m_penal[i][j] > 1)

            {

                cout<<"game over"<<endl;

                //加分数统计排行榜等

                system("stty icanon echo");

                exit(0);

            }

        }

    return true;

}

void Game::createCube()

{

    m_graph = new Context(getShape());

    m_graph->draw();

    m_graph->setLocate(1,7);

    setPenal();

    m_graph->printG(YELLOW);

    /*

   for(int i = 0; i < 24; i++)

   {

        for(int j = 0; j < 17; j++)

            cout << m_penal[i][j] <<" ";

        cout << endl;

   }

   */

}

void Game::move(int dir)

{

    erasePenal();

    switch(dir)

    {

        case DOWN:

            if(false == isAttachBottom())

            {

                m_graph->move(DOWN);

                setPenal();

                m_graph->printG(YELLOW);

            }

            else

            {

                recoverPenal();

                m_graph->printG(YELLOW);

                erase();

                stop();

            }

            break;

        case LEFT:

            if(false == isAttachLeft())

            {

                m_graph->move(LEFT);

                setPenal();

                m_graph->printG(YELLOW);

            }

            else

            {

                recoverPenal();

                m_graph->printG(YELLOW);

            }

                   

            break;

        case RIGHT:

            if(false == isAttachRight())

            {

                m_graph->move(RIGHT);

                setPenal();

                m_graph->printG(YELLOW);

            }

            else

            {

                recoverPenal();

                m_graph->printG(YELLOW);

            }

            break;

        default:

            break;

    }

}

void Game::roll()

{

    //取出方块的值,先放到一个数组中

    int i,j;

    int flag = 0;

    int b[3][3] = {0};  //获取方块数组

    int temp[3][3] = {0};

    m_graph->getLocate(&x,&y);

    memcpy(b,m_graph->getArray(),CUBE_SIZE);

    erasePenal();

    //旋转数组

    for(i = 0; i < 3; i++)

        for(j = 0; j < 3; j++)

        {

            temp[2-j][i] = b[i][j];

        }

    //判断旋转后是否会与面板重合

    for(i = 0; i < 3; i++)

    {

        for(j = 0; j < 3; j++)

        {

            if (temp[i][j] == 1 && m_penal[x + i][y + j] == 1) 

            {

                flag = 1;

                break;

            }

        }

        if(flag == 1)

            break;

    }

    //如果不重合则旋转方块,设置面板的值

    if(flag == 0)

    {

        m_graph->roll();

    }

    setPenal();

    m_graph->printG(YELLOW);

}

void Game::stop()

{

    delete m_graph;

    createCube();

}

bool Game::isAttachBottom()

{

    int i,j;

    int cube_x,cube_y;

    int b[3][3] = {0};  //获取方块数组

    int flag = false;

    m_graph->getLocate(&cube_x,&cube_y);

    memcpy(b,m_graph->getArray(),CUBE_SIZE);

    for(i = 0; i < 3; i++)

    {

        for(j = 0; j < 3; j++)

        {

           if (b[i][j] == 1 && m_penal[i + cube_x + 1][j + cube_y] == 1)

           {

                flag = true;

                break;

           }

        }

        if (flag == true)

            break;

    }

    return flag;

}

bool Game::isAttachLeft()

{

    int i,j;

    int cube_x,cube_y;

    int b[3][3] = {0};  //获取方块数组

    int flag = false;

    m_graph->getLocate(&cube_x,&cube_y);

    memcpy(b,m_graph->getArray(),CUBE_SIZE);

    for(i = 0; i < 3; i++)

    {

        for(j = 0; j < 3; j++)

        {

           if (b[i][j] == 1 && m_penal[i + cube_x][j + cube_y - 1] == 1)

           {

                flag = true;

                break;

           }

        }

        if (flag == true)

            break;

    }

    return flag;

}

bool Game::isAttachRight()

{

    int i,j;

    int cube_x,cube_y;

    int b[3][3] = {0};  //获取方块数组

    int flag = false;

    m_graph->getLocate(&cube_x,&cube_y);

    memcpy(b,m_graph->getArray(),CUBE_SIZE);

    for(i = 0; i < 3; i++)

    {

        for(j = 0; j < 3; j++)

        {

           if (b[i][j] == 1 && m_penal[i + cube_x][j + cube_y + 1] == 1)

           {

                flag = true;

                break;

           }

        }

        if (flag == true)

            break;

    }

    return flag;

}

void Game::erase()

{

   int i,j;

   int flag = 0;

   for(i = 22; i > 0; i--)

   {

        for(j = 1; j < 16; j++)

        {

            if(m_penal[i][j] == 0)

            {

                flag = 1;

            }

        }

        if(flag == 0)

        {

            //该行上面的图形整体坐落

            down(i);

            i++;

        }

        flag = 0;

   }

}

void Game::down(int level)

{

    int i,j;

    int flag = 1;

    for(i = level; i > 1; i--)

        for(j = 1; j < 16; j++)

        {

            m_penal[i][j] = m_penal[i - 1][j];

        }

    //刷新面板

    CubePoint p;

    for(i = 1; i < 23; i++)

        for(j = 1; j < 16; j++)

        {

            if(m_penal[i][j] == 1)

            {

                p.setLocate(i,j);

                p.setColor(YELLOW);

                p.printPoint();

            }

            if(m_penal[i][j] == 0)

            {

                p.setLocate(i,j);

                p.setColor(CLEAR);

                p.printPoint();

            }

        }

}

5:main函数:


void* listenKey(void *key)

{

    char* key_;

    key_ = (char*)key;

    while(1)

    {

        system("stty -icanon -echo");

        *key_ = getchar();

        system("stty icanon echo");

    }

}

int main()

{

    pthread_t t1;

    char key;

    system("clear");

    Game g;

    g.createCube();

    key = 's';

    pthread_create(&t1,NULL,listenKey,(void*)(&key));

    while(1)

    {

        fflush(stdout);

        usleep(500000);

        switch(key)

        {

            case 's':

                g.move(DOWN);break;

            case 'a':

                g.move(LEFT);key = 's';break;

            case 'd':

                g.move(RIGHT);key = 's';break;

            case 'w':

                g.roll();key = 's';break;

            default:

                g.move(DOWN);break;

        }

        g.move(DOWN);

    }

    return 0;

}

这里要注意看我是怎么设置无输入缓存的!很多人无法做出来就是卡在这了(stty -icanon -echo)。

-----------------------------------------------------------------------------------------以下为调试通过代码

cur.h


#ifndef CUR_H_

#define CUR_H_

#include<iostream>

using namespace std;

class Cur{

public:

        void saveCur();             //保存光标位置

        void moveCur(const int x,const int y);  //移动光标位置到(x,y)坐标

        void resumeCur();           //恢复光标位置

};

#endif


cur.cpp


#include "game.h"


void Cur::moveCur(const int x,const int y)

{

    int i;

    for(i = 0; i < y; i++)

        printf("\33[2C");

    for(i = 0; i < x; i++)

        printf("\33[1B");

}

void Cur::saveCur()

{

    //save cur and move to destination

    printf("\33[s");  

}

void Cur::resumeCur()

{

    printf("\33[u");

}



cubePoint.h


#ifndef CUBEPOINT_H_

#define CUBEPOINT_H_

#include<iostream>

#include "cur.h"

using namespace std;

enum color{

    CLEAR = 0,

    BLACK = 30,

    RED,

    GREEN,

    YELLOW,

    BLUE,

    PURPLE,

    DEEP_GREEN,

    WHITE

};

/*

 * 每个点显然有个坐标值

 * 每个点有一个颜色

 */

class CubePoint{

protected:

    int color;

    int x;

    int y; //每个方格点有颜色属性,坐标属性

public:

    CubePoint()

    {

        color = CLEAR;

        x = 0;

        y = 0;

    }

    CubePoint(int a,int b,int c)

    {

        color = a;

        x = b;

        y = c;

    }

    void setLocate(const int x,const int y){this->x = x;this->y = y;}

    void setColor(const int color){this->color = color;}

                                                                                                                                                                                                            

    int getColor(){return color;}

    void getLocate(int&x,int &y){x = this->x;y = this->y;}

    //打印点的方法

    void printPoint();

};

#endif


cubePoint.cpp


#include "cubePoint.h"


void CubePoint::printPoint()

{

    Cur cur;

    cur.saveCur();

    cur.moveCur(x,y);

    switch(color)

    {

         case BLACK     :printf("\033[40;30m  \033[0m");break;

         case RED       :printf("\033[41;31m  \033[0m");break;

         case GREEN     :printf("\033[42;32m  \033[0m");break;

         case YELLOW    :printf("\033[43;33m  \033[0m");break;

         case BLUE      :printf("\033[44;34m  \033[0m");break;

         case PURPLE    :printf("\033[45;35m  \033[0m");break;

         case DEEP_GREEN:printf("\033[46;36m  \033[0m");break;

         case WHITE     :printf("\033[47;37m  \033[0m");break;

         case CLEAR     :printf("\033[8m  ");

         default:

         break;

    }

    cur.resumeCur();

}



game.h


#include "graph.h"

class Game

{

private:

    int m_penal[24][17];

    Context* m_graph;

    int x;

    int y;//当前方块的位置,方块移动或者旋转成功后才可以设置这个值

private:

    //恢复设置(方块会探索下一个位置是否合法,不合法需恢复面板)

    bool recoverPenal();

    //是否着陆(是否碰到下边)

    bool isAttachBottom();

    //是否碰到左边

    bool isAttachLeft();

    //是否碰到右边

    bool isAttachRight();

    //随机获取方块形状

    char getShape();

    //用方块数组给面板数组赋值

    bool setPenal();

    //方块动过后要把遗留面板信息擦除

    bool erasePenal();

public:

    Game();

    //随机创建方块的方法

    void createCube();

    //移动的方法,移动的过程中对m_penal的改变

    void move(int dir);

    //旋转的方法。。。

    void roll();

    //方块停止

    void stop();

    //擦除满行

    void erase();

    //擦除完上面的图形整块坠落

    void down(int level);

};


game.cpp


#include "game.h"


#define PENAL_SIZE (17*24*sizeof(int))

#define CUBE_SIZE (3*3*sizeof(int))

Game::Game()

{

    m_graph = NULL;

    x = 1;

    y = 7;

    CubePoint p;

    int i;

    memset((void*)m_penal,0,PENAL_SIZE);

   for(i = 0; i < 24; i++)

   {

        p.setLocate(i,0);

        p.setColor(BLUE);

        p.printPoint();

        p.setLocate(i,16);

        p.setColor(BLUE);

        p.printPoint();

        m_penal[i][0] = 1;

        m_penal[i][16] = 1;

   }

   for(i = 0; i < 17; i++)

   {

        p.setLocate(23,i);

        p.setColor(BLUE);

        p.printPoint();

        p.setLocate(0,i);

        p.setColor(RED);

        p.printPoint();

        m_penal[23][i] = 1;

        m_penal[0][i] = 1;

   }

   /*测试面板值是否正常

   for(i = 0; i < 24; i++)

   {

        for(int j = 0; j < 17; j++)

            cout << m_penal[i][j] <<" ";

        cout << endl;

   }

   */

   fflush(stdout);

}

char Game::getShape()

{

  

    char ch;

    int num = 1 + rand() % 5;

    switch(num)

    {

        case 1:ch = 'Z';break;

        case 2:ch = 'T';break;

        case 3:ch = 'O';break;

        case 4:ch = 'I';break;

        case 5:ch = 'L';break;

        default:

               cout<<"no this shape type"<<endl;

               ch = '\0';

               break;

    }

    return ch;

}

bool Game::erasePenal()

{

    int i,j;

    int b[3][3] = {0};  //获取方块数组

    m_graph->printG(CLEAR);

    memcpy(b,m_graph->getArray(),CUBE_SIZE);

    for(i = 0; i < 3; i++)

        for(j = 0; j < 3; j++)

        {

            m_penal[i + x][j + y] -= b[i][j];

        }

    return true;

}

bool Game::recoverPenal()

{

    int i,j;

    int b[3][3] = {0};  //获取方块数组

    memcpy(b,m_graph->getArray(),CUBE_SIZE);

    for(i = x; i < x + 3; i++)

        for(j = y; j < y + 3; j++)

        {

            m_penal[i][j] += b[i-x][j-y];

        }

    return true;

}

bool Game::setPenal()

{

    int i,j;

    int b[3][3] = {0};  //获取方块数组

    m_graph->getLocate(&x,&y);

    memcpy(b,m_graph->getArray(),CUBE_SIZE);

    /*测试取到方块数组是否正常

    for(i = 0;i < 3; i++)

    {

        for(j = 0; j < 3; j++)

            cout<<b[i][j]<< " ";

        cout<<endl;

    }

    */

    for(i = x; i < x + 3; i++)

        for(j = y; j < y + 3; j++)

        {

            m_penal[i][j] += b[i-x][j-y];

            if(m_penal[i][j] > 1)

            {

                cout<<"game over"<<endl;

                //加分数统计排行榜等

                system("stty icanon echo");

                exit(0);

            }

        }

    return true;

}

void Game::createCube()

{

    m_graph = new Context(getShape());

    m_graph->draw();

    m_graph->setLocate(1,7);

    setPenal();

    m_graph->printG(YELLOW);

    /*

   for(int i = 0; i < 24; i++)

   {

        for(int j = 0; j < 17; j++)

            cout << m_penal[i][j] <<" ";

        cout << endl;

   }

   */

}

void Game::move(int dir)

{

    erasePenal();

    switch(dir)

    {

        case DOWN:

            if(false == isAttachBottom())

            {

                m_graph->move(DOWN);

                setPenal();

                m_graph->printG(YELLOW);

            }

            else

            {

                recoverPenal();

                m_graph->printG(YELLOW);

                erase();

                stop();

            }

            break;

        case LEFT:

            if(false == isAttachLeft())

            {

                m_graph->move(LEFT);

                setPenal();

                m_graph->printG(YELLOW);

            }

            else

            {

                recoverPenal();

                m_graph->printG(YELLOW);

            }

                   

            break;

        case RIGHT:

            if(false == isAttachRight())

            {

                m_graph->move(RIGHT);

                setPenal();

                m_graph->printG(YELLOW);

            }

            else

            {

                recoverPenal();

                m_graph->printG(YELLOW);

            }

            break;

        default:

            break;

    }

}

void Game::roll()

{

    //取出方块的值,先放到一个数组中

    int i,j;

    int flag = 0;

    int b[3][3] = {0};  //获取方块数组

    int temp[3][3] = {0};

    m_graph->getLocate(&x,&y);

    memcpy(b,m_graph->getArray(),CUBE_SIZE);

    erasePenal();

    //旋转数组

    for(i = 0; i < 3; i++)

        for(j = 0; j < 3; j++)

        {

            temp[2-j][i] = b[i][j];

        }

    //判断旋转后是否会与面板重合

    for(i = 0; i < 3; i++)

    {

        for(j = 0; j < 3; j++)

        {

            if (temp[i][j] == 1 && m_penal[x + i][y + j] == 1) 

            {

                flag = 1;

                break;

            }

        }

        if(flag == 1)

            break;

    }

    //如果不重合则旋转方块,设置面板的值

    if(flag == 0)

    {

        m_graph->roll();

    }

    setPenal();

    m_graph->printG(YELLOW);

}

void Game::stop()

{

    delete m_graph;

    createCube();

}

bool Game::isAttachBottom()

{

    int i,j;

    int cube_x,cube_y;

    int b[3][3] = {0};  //获取方块数组

    int flag = false;

    m_graph->getLocate(&cube_x,&cube_y);

    memcpy(b,m_graph->getArray(),CUBE_SIZE);

    for(i = 0; i < 3; i++)

    {

        for(j = 0; j < 3; j++)

        {

           if (b[i][j] == 1 && m_penal[i + cube_x + 1][j + cube_y] == 1)

           {

                flag = true;

                break;

           }

        }

        if (flag == true)

            break;

    }

    return flag;

}

bool Game::isAttachLeft()

{

    int i,j;

    int cube_x,cube_y;

    int b[3][3] = {0};  //获取方块数组

    int flag = false;

    m_graph->getLocate(&cube_x,&cube_y);

    memcpy(b,m_graph->getArray(),CUBE_SIZE);

    for(i = 0; i < 3; i++)

    {

        for(j = 0; j < 3; j++)

        {

           if (b[i][j] == 1 && m_penal[i + cube_x][j + cube_y - 1] == 1)

           {

                flag = true;

                break;

           }

        }

        if (flag == true)

            break;

    }

    return flag;

}

bool Game::isAttachRight()

{

    int i,j;

    int cube_x,cube_y;

    int b[3][3] = {0};  //获取方块数组

    int flag = false;

    m_graph->getLocate(&cube_x,&cube_y);

    memcpy(b,m_graph->getArray(),CUBE_SIZE);

    for(i = 0; i < 3; i++)

    {

        for(j = 0; j < 3; j++)

        {

           if (b[i][j] == 1 && m_penal[i + cube_x][j + cube_y + 1] == 1)

           {

                flag = true;

                break;

           }

        }

        if (flag == true)

            break;

    }

    return flag;

}

void Game::erase()

{

   int i,j;

   int flag = 0;

   for(i = 22; i > 0; i--)

   {

        for(j = 1; j < 16; j++)

        {

            if(m_penal[i][j] == 0)

            {

                flag = 1;

            }

        }

        if(flag == 0)

        {

            //该行上面的图形整体坐落

            down(i);

            i++;

        }

        flag = 0;

   }

}

void Game::down(int level)

{

    int i,j;

    int flag = 1;

    for(i = level; i > 1; i--)

        for(j = 1; j < 16; j++)

        {

            m_penal[i][j] = m_penal[i - 1][j];

        }

    //刷新面板

    CubePoint p;

    for(i = 1; i < 23; i++)

        for(j = 1; j < 16; j++)

        {

            if(m_penal[i][j] == 1)

            {

                p.setLocate(i,j);

                p.setColor(YELLOW);

                p.printPoint();

            }

            if(m_penal[i][j] == 0)

            {

                p.setLocate(i,j);

                p.setColor(CLEAR);

                p.printPoint();

            }

        }

}


graph.h



#include <iostream>

using namespace std;

#include <stdio.h>

#include "cubePoint.h"

#include <stdlib.h>

#define DOWN 0

#define LEFT 1

#define RIGHT 2


class Gbase{

protected:

    int x;

    int y;  //a[0][0]的位置

    int a[3][3];

public:

    Gbase(){

        int i,j;

        x = 0;

        y = 0;

        for(j = 0; j < 3; j++)

        for(i = 0; i < 3; i++)

        a[i][j] = 0;

    }

    int move(int dir);

    virtual int roll();

    virtual void draw(){}

    void setLocate(int a,int b){x = a;y = b;}

    void getLocate(int* a,int* b){*a = x;*b = y;}

    void printG(int color);

    //获取数组首地址

    void* getArray(){return (void*)a;}

};

class Zgraph : public Gbase{

public:

    void draw(){

        a[0][0] = 1;

        a[0][1] = 1;

        a[0][2] = 0;

        a[1][0] = 0;

        a[1][1] = 1;

        a[1][2] = 1;

        a[2][0] = 0;

        a[2][1] = 0;

        a[2][2] = 0;

    }

};

class Tgraph : public Gbase{

public:

    void draw(){

        a[0][0] = 1;

        a[0][1] = 1;

        a[0][2] = 1;

        a[1][0] = 0;

        a[1][1] = 1;

        a[1][2] = 0;

        a[2][0] = 0;

        a[2][1] = 0;

        a[2][2] = 0;

    }

};

class Ograph : public Gbase{

public:

    void draw(){

        a[0][0] = 1;

        a[0][1] = 1;

        a[0][2] = 0;

        a[1][0] = 1;

        a[1][1] = 1;

        a[1][2] = 0;

        a[2][0] = 0;

        a[2][1] = 0;

        a[2][2] = 0;

    }

    virtual int roll(){};

};

class Igraph : public Gbase{

public:

    void draw(){

        a[0][0] = 0;

        a[0][1] = 1;

        a[0][2] = 0;

        a[1][0] = 0;

        a[1][1] = 1;

        a[1][2] = 0;

        a[2][0] = 0;

        a[2][1] = 1;

        a[2][2] = 0;

    }

};

class Lgraph : public Gbase{

public:

    void draw(){

        a[0][0] = 0;

        a[0][1] = 1;

        a[0][2] = 0;

        a[1][0] = 0;

        a[1][1] = 1;

        a[1][2] = 0;

        a[2][0] = 0;

        a[2][1] = 1;

        a[2][2] = 1;

    }

};

class Context

{

private:

    Gbase* gbase;

public:

    ~Context()

    {

        delete gbase;

    }

    Context(char cType)

    {

        switch(cType)

        {

            case 'Z':

                gbase = new Zgraph();

                break;

            case 'T':

                gbase = new Tgraph();

                break;

            case 'O':

                gbase = new Ograph();

                break;

            case 'I':

                gbase = new Igraph();

                break;

            case 'L':

                gbase = new Lgraph();

                break;

            default:

                printf("no %c type\n",cType);

                break;

        }

    }

    int move(int dir){return gbase->move(dir);}

    int roll(){return gbase->roll();}

    void draw(){gbase->draw();}

    void setLocate(int a,int b){gbase->setLocate(a,b);}

    void getLocate(int *a,int* b){gbase->getLocate(a,b);}

    void* getArray(){gbase->getArray();}

    void printG(int color){gbase->printG(color);}

};


graph.cpp


#include "graph.h"


void Gbase::printG(int color)

{

    int i,j;

    CubePoint p;

    for(i = x; i < x+3; i++)

        for(j = y; j < y+3; j++)

        {

            if(a[i - x][j - y] == 1)

            {

                p.setLocate(i,j);

                p.setColor(color);

                p.printPoint();

            }

        }

}

int Gbase::move(int dir)

{

    switch(dir)

    {

        case DOWN:x++;break;

        case LEFT:y--;break;

        case RIGHT:y++;break;

        default:

                break;

    }

    return 0;

}

int Gbase::roll()

{

    int i,j;

    int b[3][3];

    for(i = 0; i < 3; i++)

        for(j = 0; j < 3; j++)

        {

            b[2-j][i] = a[i][j];

        }

    for(i = 0; i < 3; i++)

        for(j = 0; j < 3; j++)

        {

            a[i][j] = b[i][j];

        }

}



main.cpp


#include <cstdlib>

//#include <pthread.h>

#include "cur.h"

#include "cubePoint.h"

#include "game.h"

//#include "graph.h"


using namespace std;


/*

 * 

 */

void* listenKey(void *key)

{

    char* key_;

    key_ = (char*)key;

    while(1)

    {

        system("stty -icanon -echo");

        *key_ = getchar();

        system("stty icanon echo");

    }

}

int main()

{

    pthread_t t1;

    char key;

    system("clear");

    Game g;

    g.createCube();

    key = 's';

    pthread_create(&t1,NULL,listenKey,(void*)(&key));

    while(1)

    {

        fflush(stdout);

        usleep(500000);

        switch(key)

        {

            case 's':

                g.move(DOWN);break;

            case 'a':

                g.move(LEFT);key = 's';break;

            case 'd':

                g.move(RIGHT);key = 's';break;

            case 'w':

                g.roll();key = 's';break;

            default:

                g.move(DOWN);break;

        }

        g.move(DOWN);

    }

    return 0;


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值