俄罗斯方块C++源码

源.cpp


//TETRIS
//源.cpp

#include<iostream>
#include<thread>
#include<graphics.h >
#include"tetromino.h"

using namespace std;

bool panel [ 1000 ][ 1000 ];                    //面板,true=空,false=占据
tetromino *p = nullptr;                     //图形
tetromino *nextp = nullptr;                 //下一个图形
int score = 0;                                      //分数
bool loss;                                              //检测是否失败

void start ();                                          //开始
void initpanel ();                          //初始化面板
void createTetromino ();                    //创造图形
void play ();                               //操作方块
void eliminate ();                          //消除方块
void goDown ( thread& );                    //方块下落
void control ();                            //方块控制
void endgame ();                            //游戏结束
bool leftable ( const tetromino& );         //可以向左
bool rightable ( const tetromino& );            //可以向右
bool spinnable ( const tetromino& );        //可以旋转

int main ( void )
{
    start ();
    initpanel ();
    while ( !loss )
    {
        createTetromino ();
        play ();
        eliminate ();
    }
    endgame ();

    return 0;
}

void initpanel ()           //初始化面板
{
    for ( int i = 0; i < WIDTH; i++ )
    {
        for ( int j = 0; j < HEIGHT; j++ )
        {
            panel [ j ][ i ] = true;
        }
    }
}

void createTetromino ()     //创造图形
{
    int choice;
    if ( !( panel [ 0 ][ 4 ] && panel [ 0 ][ 5 ] && panel [ 0 ][ 6 ] ) )
    {
        loss = false;
        endgame ();
    }
    if ( !nextp )
    {
        srand ( time ( 0 ) );
        choice = rand () % 7;
        switch ( choice )
        {
            case I:
                nextp = new tetromino ( I );
                break;
            case J:
                nextp = new tetromino ( J );
                break;
            case L:
                nextp = new tetromino ( L );
                break;
            case O:
                nextp = new tetromino ( O );
                break;
            case S:
                nextp = new tetromino ( S );
                break;
            case Z:
                nextp = new tetromino ( Z );
                break;
            case T:
                nextp = new tetromino ( T );
                break;
        }
        p = nextp;
    }
    else
    {
        p = nextp;
    }
    choice = rand () % 7;
    switch ( choice )
    {
        case I:
            nextp = new tetromino ( I );
            break;
        case J:
            nextp = new tetromino ( J );
            break;
        case L:
            nextp = new tetromino ( L );
            break;
        case O:
            nextp = new tetromino ( O );
            break;
        case S:
            nextp = new tetromino ( S );
            break;
        case Z:
            nextp = new tetromino ( Z );
            break;
        case T:
            nextp = new tetromino ( T );
            break;
    }
    clearrectangle ( 11 * BORDER , 0 , 17 * BORDER , 4 * BORDER );
    for ( int i = 0; i < 4; i++ )
    {
        solidrectangle ( ( 7.5 + nextp->block [ i ].X )*BORDER , ( nextp->block [ i ].Y )*BORDER , ( 8.5 + nextp->block [ i ].X )*BORDER , ( 1 + nextp->block [ i ].Y )*BORDER );
    }
    p->display ();
}

void play ()                                //操作方块
{
    thread controlThread ( control );
    goDown ( controlThread );
}

void goDown ( thread& thr )                  //方块下落
{
    for ( int i = 0; i < HEIGHT; i++ )
    {
        for ( int j = 0; j < 4; j++ )
        {
            if ( !panel [ p->block [ j ].Y + 1 ][ p->block [ j ].X ] || i == HEIGHT - 1 )
            {
                for ( int k = 0; k < 4; k++ )
                {
                    panel [ p->block [ k ].Y ][ p->block [ k ].X ] = false;
                }
                goto JUMPOUT;
            }
        }
        p->moveDown ();
        Sleep ( p->interval );
    }
    JUMPOUT:
    thr.detach ();
}

void control ()                             //方块控制
{
    while ( 1 )
    {
        if ( _kbhit () )
        {
            switch ( _getch () )
            {
                case 'w':
                    if ( spinnable ( *p ) )
                    {
                        p->spin ();
                        p->decelerate ();
                    }
                    break;
                case 'a':
                    if ( leftable ( *p ) )
                    {
                        p->moveLeft ();
                        p->decelerate ();
                    }
                    break;
                case 'd':
                    if ( rightable ( *p ) )
                    {
                        p->moveRight ();
                        p->decelerate ();
                    }
                    break;
                case 's':
                    p->accelerate ();
                    break;
            }
        }
    }
}

void eliminate ()                           //消除方块
{
    bool flag = true;
    int line = true;
    while ( line )
    {
        line = 0;
        for ( int i = 0; i < 20; i++ )
        {
            flag = true;
            for ( int j = 0; j < 10; j++ )
            {
                if ( panel [ i ][ j ] )
                {
                    flag = false;
                }
            }
            if ( flag )
            {
                line = i;
            }
        }
        if ( line )
        {
            score++;
            for ( int i = line; i > 0; i-- )
            {
                for ( int j = 0; j < 10; j++ )
                {
                    panel [ i ][ j ] = panel [ i - 1 ][ j ];
                    if ( !panel [ i ][ j ] )
                    {
                        solidrectangle ( j*BORDER , i*BORDER , ( j + 1 )*BORDER , ( i + 1 )*BORDER );
                    }
                    else
                    {
                        clearrectangle ( j*BORDER , i*BORDER , ( j + 1 )*BORDER , ( i + 1 )*BORDER );
                    }
                }
            }
        }
    }
    clearrectangle ( 11 * BORDER , 5 * BORDER , 16 * BORDER , 9 * BORDER );
    char str [ 5 ];
    sprintf_s ( str , "%d" , score );
    outtextxy ( 13 * BORDER , 7 * BORDER , str );
}

void endgame ()                             //游戏结束
{
    cleardevice ();
    closegraph ();
    cout << "GAME OVER!" << endl << "YOUR SCORE:" << score << endl;
    system ( "pause" );
    exit ( 0 );
}

void start ()                               //开始
{
    initgraph ( 401 , 400 );                //绘图开始
    char str1 [] = "Press any key to start!";
    outtextxy ( 100 , 200 , str1 );
    char str2 [] = "使用WASD操控";
    outtextxy ( 100 , 300 , str2 );
    while ( !_kbhit () );
    cleardevice ();
    line ( 201 , 0 , 201 , 401 );           //竖线
    line ( 0 , 401 , 201 , 401 );           //横线
    rectangle ( 11 * BORDER - 1 , 0 , 16 * BORDER + 1 , 4 * BORDER + 1 );                                           //显示下一图形
    rectangle ( 11 * BORDER - 1 , 5 * BORDER + 1 , 16 * BORDER + 1 , 9 * BORDER + 1 );                  //显示分数  
}

bool leftable ( const tetromino& tet )          //可以向左
{
    for ( int i = 0; i < 4; i++ )
    {
        if ( !panel [ tet.block [ i ].Y ][ tet.block [ i ].X - 1 ] )
        {
            return false;
        }
    }
    return true;
}
bool rightable ( const tetromino& tet )         //可以向右
{
    for ( int i = 0; i < 4; i++ )
    {
        if ( !panel [ tet.block [ i ].Y ][ tet.block [ i ].X + 1 ] )
        {
            return false;
        }
    }
    return true;
}

bool spinnable ( const tetromino& tet )     //可以旋转
{
    for ( int i = 0; i < 4; i++ )
    {
        if ( !panel [ -p->block [ i ].X + p->center.X + p->center.Y ][ p->block [ i ].Y - p->center.Y + p->center.X ] )
        {
            if ( -p->block [ i ].X + p->center.X + p->center.Y <= 10 && p->block [ i ].Y - p->center.Y + p->center.X <= 20 )
            {
                return false;
            }
        }
    }
    return true;
}

tetromino.h


//TETRIS
//tetromino.h

#ifndef TETROMINO_H
#define TETROMINO_H

#define BORDER 20
#define HEIGHT 20
#define WIDTH 20

#include<conio.h>

enum tetromino_type
{
    I , J , L , O , S , Z , T
};

class tetromino                     //图形
{
public:
    tetromino ( tetromino_type index );
    tetromino_type type;

    int interval = 300;       //降落的间隔
    COORD block [ 4 ];     //方块的位置
    COORD center;           //旋转中心

    void display ();         //显示
    void moveLeft ();        //向左移动
    void moveRight ();       //向右移动
    void moveDown ();        //向下移动
    void spin ();            //旋转
    void accelerate ();      //变速
    void decelerate ();      //减速

    bool left ();               //最左
    bool right ();          //最右
};

#endif

tetromino.cpp


//TETRIS
//tetromino.cpp

#include<graphics.h>
#include"tetromino.h"

using namespace std;

tetromino::tetromino ( tetromino_type index )
{
    switch ( index )
    {
        case I:
            block [ 0 ] = { 5 , 0 };
            block [ 1 ] = { 5 , 1 };
            block [ 2 ] = { 5 , 2 };
            block [ 3 ] = { 5 , 3 };
            center = { 5 , 1.5 };
            type = I;
            break;
        case J:
            block [ 0 ] = { 5 , 0 };
            block [ 1 ] = { 5 , 1 };
            block [ 2 ] = { 5 , 2 };
            block [ 3 ] = { 4 , 2 };
            center = block [ 1 ];
            type = J;
            break;
        case L:
            block [ 0 ] = { 5 , 0 };
            block [ 1 ] = { 5 , 1 };
            block [ 2 ] = { 5 , 2 };
            block [ 3 ] = { 6 , 2 };
            center = block [ 1 ];
            type = L;
            break;
        case O:
            block [ 0 ] = { 5 , 0 };
            block [ 1 ] = { 6 , 0 };
            block [ 2 ] = { 5 , 1 };
            block [ 3 ] = { 6 , 1 };
            center = { 5.5 , 0.5 };
            type = O;
            break;
        case S:
            block [ 0 ] = { 6 , 0 };
            block [ 1 ] = { 5 , 0 };
            block [ 2 ] = { 5 , 1 };
            block [ 3 ] = { 4 , 1 };
            center = block [ 1 ];
            type = S;
            break;
        case Z:
            block [ 0 ] = { 4 , 0 };
            block [ 1 ] = { 5 , 0 };
            block [ 2 ] = { 5 , 1 };
            block [ 3 ] = { 6 , 1 };
            center = block [ 1 ];
            type = Z;
            break;
        case T:
            block [ 0 ] = { 4 , 0 };
            block [ 1 ] = { 5 , 0 };
            block [ 2 ] = { 6 , 0 };
            block [ 3 ] = { 5 , 1 };
            center = block [ 1 ];
            type = T;
            break;
    }
}

void tetromino::display ()         //显示
{
    for ( int i = 0; i < 4; i++ )
    {
        solidrectangle ( block [ i ].X*BORDER , block [ i ].Y*BORDER , ( block [ i ].X + 1 )*BORDER , ( block [ i ].Y + 1 )*BORDER );
    }
}
void tetromino::moveLeft ()        //向左移动
{
    if ( !left () )
    {
        for ( int i = 0; i < 4; i++ )
        {
            clearrectangle ( block [ i ].X*BORDER , block [ i ].Y*BORDER , ( block [ i ].X + 1 )*BORDER , ( block [ i ].Y + 1 )*BORDER );
            block [ i ].X--;
        }
        center.X--;
        display ();
    }
}
void tetromino::moveRight ()       //向右移动
{
    if ( !right () )
    {
        for ( int i = 0; i < 4; i++ )
        {
            clearrectangle ( block [ i ].X*BORDER , block [ i ].Y*BORDER , ( block [ i ].X + 1 )*BORDER , ( block [ i ].Y + 1 )*BORDER );
            block [ i ].X++;
        }
        center.X++;
        display ();
    }
}
void tetromino::moveDown ()        //向下移动
{
    for ( int i = 0; i < 4; i++ )
    {
        clearrectangle ( block [ i ].X*BORDER , block [ i ].Y*BORDER , ( block [ i ].X + 1 )*BORDER , ( block [ i ].Y + 1 )*BORDER );
        block [ i ].Y++;
    }
    center.Y++;
    display ();
}

void tetromino::spin ()                 //旋转
{
    if ( type != O )
    {
        for ( int i = 0; i < 4; i++ )
        {
            clearrectangle ( block [ i ].X*BORDER , block [ i ].Y*BORDER , ( block [ i ].X + 1 )*BORDER , ( block [ i ].Y + 1 )*BORDER );
            int x = block [ i ].X;
            int y = block [ i ].Y;
            block [ i ].X = y - center.Y + center.X;
            block [ i ].Y = -x + center.X + center.Y;
        }
        display ();
    }
}

void tetromino::accelerate ()           //加速
{
    interval = 100;
}

void tetromino::decelerate ()          //减速
{
    interval = 300;
}

bool tetromino::left ()                 //最左
{
    for ( int i = 0; i < 4; i++ )
    {
        if ( block [ i ].X == 0 )
        {
            return true;
        }
    }
    return false;
}

bool tetromino::right ()
{
    for ( int i = 0; i < 4; i++ )
    {
        if ( block [ i ].X == 9 )
        {
            return true;
        }
    }
    return false;
}
  • 6
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值