俄罗斯方块(C语言)

当时不会C++,只好用C写了。

先附上效果图

这里写图片描述
这里写图片描述
这里写图片描述

附上代码:

#include <iostream>
#include <conio.h>
#include <stdlib.h>
#include <time.h>
#include <Windows.h>
#define FORM_SIZE 3
#define ROW 23                  //运动空间——行数
#define COLUMN 14               //运动空间——列数
#define RANDOM_TRANSLATION 7        //center横坐标随机产生4种
#define ORDINATE 2              //center纵坐标初始值
#define DISPLACEMENT 3          //center横坐标平移
#define TEMP 1
#define WIN 15                  //消去WIN行胜利
#define DIE_LINE 1              //到DIE_LINE行数屎
#define UPDATE_TIME 40          //更新时间
#define SPACE  "  "             
#define SQURE "■"
using namespace std;

COORD far_away = { 0,24 };
int time_down = 0;
int scoure=0;                   //得分

enum color{blue=121,green=114,lake_blue=115,red=124,gray=120,pink=117,yellow=126};      //enum颜色

struct squre{                   //声明方块结构
    int state;
    COORD pos[FORM_SIZE];
    COORD center;
    int form;
    int color;
};

static struct fixed{
    short fix[ROW][COLUMN];     //记录空间中每个坐标的状态,0为无,1为存在squre
    int color[ROW][COLUMN];
};

struct fixed initial_fixed(struct fixed * fixed);                   //初始化fixed方块
inline void gotoxy(COORD pos);                                      //移动光标到pos位置
void print_squre(struct squre * form, char ch[]);                   //打印方块
void print_fixed(struct fixed * fixed);                             //打印fixed的方块
void move_squre(struct squre * form, short xdir, short ydir);       //x轴移动xdir个单位,y轴移动ydir个单位
squre create_squre();                                               //创造方块
static squre form1();                                               //7种类型的方块
static squre form2();                                               
static squre form3();                                               
static squre form4();
static squre form5();
static squre form6();
static squre form7();
squre turn(squre * pform);                                          //方块转动
bool turn_success(struct squre * form, struct fixed * fixed);       //是否能够转动成功
static inline COORD tempXY();                                       
bool is_buttom(struct squre * form, struct fixed * fixed);                  //判断是否到达底部
bool is_wall(struct squre * form, struct fixed * fixed, short dir);         //判断是否碰到墙壁/fixed的方块
struct fixed fix_squre(struct squre * form, struct fixed * fixed);          //fixed方块
static bool check_full(const struct fixed * fixed, const int line);         //判断是否存在满行
static bool is_blank(const struct fixed * fixed, const short line);             //是否是空白行
static bool is_in_line(const short y, const short line[], const short t);       
static void update_fixed(struct fixed * fixed, short line[], short t);          //更新fixed的方块
void eliminate(struct fixed * fixed, struct squre * form);                  //消行
bool is_die(struct fixed * fixed);                                          //判断是否死亡
void add_one(short line, char ch[]);                                        
void scoure_board();                                                        //得分板
void print_scoure();                                                        //打印分数
void print_next(const struct squre * form);
void time_board();                                                          //时间板

HANDLE hSqureConsole = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_SCREEN_BUFFER_INFO bInfo;

int main()
{
    GetConsoleScreenBufferInfo(hSqureConsole, &bInfo);
    COORD size = { 70, 25 };
    SetConsoleScreenBufferSize(hSqureConsole, size);
    SMALL_RECT rc = { 0, 0, 60, 23 };                                   //不能大于缓冲区大小
    SetConsoleWindowInfo(hSqureConsole, true, &rc);
    system("color 73");
    struct fixed fixed;
    initial_fixed(&fixed);
    print_fixed(&fixed);

    scoure_board();

    struct squre form_temp = create_squre();
    time_board();

    int is_out=0;
    while (!is_out)
    {
        //Sleep(11);
        fflush(stdin);
        struct squre form = form_temp;
        form_temp = create_squre();
        print_squre(&form, SQURE);

        print_next(&form_temp);

        bool isout = 0;
        while (!isout)
        {
            char ch;
            if (_kbhit())
            {
                ch = _getch();
                switch (ch)
                {
                case 72:
                    if (!turn_success(&form, &fixed))
                    {
                        print_squre(&form, SPACE);
                        turn(&form);
                        print_squre(&form, SQURE);
                    }
                    break;
                case 75:
                    if (!is_wall(&form, &fixed, -1))
                    {
                        move_squre(&form, -1, 0);
                    }
                    break;
                case 77:
                    if (!is_wall(&form, &fixed, +1))
                    {
                        move_squre(&form, +1, 0);
                    }
                    break;
                case 80:
                    if (!is_buttom(&form, &fixed))
                    {
                        move_squre(&form, 0, +1);
                    }
                    break;
                default :
                    break;
                }
            }
            Sleep(15);
            if (0 == ++time_down % 15)
            {
                if (is_buttom(&form, &fixed))
                {
                    fix_squre(&form, &fixed);
                    eliminate(&fixed, &form);
                    isout = 1;
                    if (scoure >= WIN || is_die(&fixed))
                        is_out = 1;
                }
                else
                    move_squre(&form, 0, +1);
            }
        }
    }
}

bool is_die(struct fixed * fixed)
{
    for (int i = 1; i < COLUMN - 1; i++)
    {
        if (fixed->fix[DIE_LINE][i] == 1)
            return 1;
    }
    return 0;
}

inline void gotoxy(COORD pos)
{
    pos.X *= 2;
    SetConsoleCursorPosition(hSqureConsole, pos);
}

void move_squre(struct squre * form,short xdir,short ydir)
{
    print_squre(form, SPACE);
    form->center.X += xdir;
    form->center.Y += ydir;
    for (int i = 0; i < FORM_SIZE; i++)
    {
        form->pos[i].X += xdir;
        form->pos[i].Y += ydir;
    }
    print_squre(form, SQURE);

}

bool is_buttom(struct squre * form, struct fixed * fixed)
{
    short x, y;
    y = form->center.X;             //**********     COORD的X与Y 和 二维数组的一维二维要分清
    x = form->center.Y;             //**********     这里X赋给y,Y赋给x,体现COORD与数组的一二维的区别
    if (fixed->fix[x+1][y])
        return 1;
    for (int i = 0; i < FORM_SIZE; i++)
    {
        y = form->pos[i].X;         //同理↑↑
        x = form->pos[i].Y;
        if (fixed->fix[x+1][y])
            return 1;
    }
    return 0;
}

bool is_wall(struct squre * form, struct fixed * fixed,short dir)
{
    short x, y;
    x = form->center.X;
    y = form->center.Y;
    if (fixed->fix[y][x + dir])
        return 1;
    for (int i = 0; i < FORM_SIZE; i++)
    {
        x = form->pos[i].X;
        y = form->pos[i].Y;
        if (fixed->fix[y][x + dir])
            return 1;
    }
    return 0;
}

struct fixed fix_squre(struct squre * form, struct fixed * fixed)
{
    COORD pos;
    pos.X = form->center.X;
    pos.Y = form->center.Y;
    fixed->fix[pos.Y][pos.X] = 1;
    fixed->color[pos.Y][pos.X] = form->color;
    for (int i = 0; i < FORM_SIZE; i++)
    {
        pos.X = form->pos[i].X;
        pos.Y = form->pos[i].Y;
        fixed->fix[pos.Y][pos.X] = 1;
        fixed->color[pos.Y][pos.X] = form->color;
    }
    return *fixed;
}

struct fixed  initial_fixed(struct fixed * fixed)
{
    for (int i = 0; i < ROW; i++)
    {
        for (int j = 0; j < COLUMN; j++)
        {
            if (j == 0 || j == COLUMN - 1 || i == ROW - 1)
                fixed->fix[i][j] = 1;
            else
                fixed->fix[i][j] = 0;
        }
    }
    return *fixed;
}

void print_fixed(struct fixed * fixed)
{
    COORD pos;
    pos.X = 1;
    pos.Y = ROW-1;
    gotoxy(pos);
    for (int i = 1; i < COLUMN-1; i++)
        cout << " ̄";
}

squre turn(squre * pform)
{
    if (pform->form != 1)
    {
        int tempX;
        for (int i = 0; i < 3; i++)
        {
            pform->pos[i].X -= pform->center.X;
            //pform->pos[i].X /= 2;
            pform->pos[i].Y -= pform->center.Y;
            tempX = pform->pos[i].X;
            pform->pos[i].X = (short)((-pform->pos[i].Y)*(pform->state) + pform->center.X);
            pform->pos[i].Y = (short)(tempX*(pform->state) + pform->center.Y);
        }
        if (pform->form == 2)
        {
            pform->state *= -1;
        }
    }
    return *pform;
}

bool turn_success(struct squre * form, struct fixed * fixed)
{
    struct squre form_temp = *form;
    turn(&form_temp);
    short x, y;
    x = form_temp.center.X;
    y = form_temp.center.Y;
    if (fixed->fix[y][x])
        return 1;
    for (int i = 0; i < FORM_SIZE; i++)
    {
        x = form_temp.pos[i].X;
        y = form_temp.pos[i].Y;
        if (fixed->fix[y][x])
            return 1;
    }
    return 0;
}

void print_squre(struct squre * form,char ch[])
{
    COORD pos;
    pos.X = form->center.X;
    pos.Y = form->center.Y;
    gotoxy(pos);
    SetConsoleTextAttribute(hSqureConsole, form->color);
    fputs(ch, stdout);
    for (int i = 0; i < FORM_SIZE; i++)
    {
        pos.X = form->pos[i].X;
        pos.Y = form->pos[i].Y;
        gotoxy(pos);
        fputs(ch, stdout);
    }
}

squre create_squre()        //产生随机squre类型
{
    srand(time(NULL));
    short random = rand() % 7;
    typedef squre (*random_squre)();
    random_squre psqure[7] = {
        form1, form2, form3, form4, form5, form6, form7
    };
    return psqure[random]();
}

static squre form1()        //类型1:L型
{
    COORD temp = tempXY();
    squre form{
        1,
        { { temp.X - TEMP, temp.Y - 1 }, { temp.X - TEMP, temp.Y }, { temp.X + TEMP, temp.Y } },
        { temp.X, temp.Y },
        4,
        pink
    };

    srand(time(NULL));
    short t = rand() % form.form;
    while (t--)
    {
        turn(&form);
    }
    return form;
}

static squre form2()        //类型2:L型镜像
{
    COORD temp = tempXY();
    squre form{
        1,
        { { temp.X + TEMP, temp.Y - 1 }, { temp.X - TEMP, temp.Y }, { temp.X + TEMP, temp.Y } },
        { temp.X, temp.Y },
        4,
        gray
    };

    srand(time(NULL));
    short t = rand() % form.form;
    while (t--)
    {
        turn(&form);
    }
    return form;
}

static squre form3()        //类型:T型
{
    COORD temp = tempXY();
    squre form{
        1,
        { { temp.X, temp.Y - 1 }, { temp.X - TEMP, temp.Y }, { temp.X + TEMP, temp.Y } },
        { temp.X, temp.Y },
        4,
        yellow
    };

    srand(time(NULL));
    short t = rand() % form.form;
    while (t--)
    {
        turn(&form);
    }
    return form;
}

static squre form4()        //类型4:ㄣ型
{
    COORD temp = tempXY();
    squre form{
        1,
        { { temp.X, temp.Y - 1 }, { temp.X - TEMP, temp.Y }, { temp.X - TEMP, temp.Y + 1 } },
        { temp.X, temp.Y },
        2,
        green
    };

    srand(time(NULL));
    short t = rand() % form.form;
    while (t--)
    {
        turn(&form);
    }
    return form;
}

static squre form5()        //类型5:ㄣ型镜像
{
    COORD temp = tempXY();
    squre form{
        1,
        { { temp.X - TEMP, temp.Y - 1 }, { temp.X - TEMP, temp.Y }, { temp.X, temp.Y + 1 } },
        { temp.X, temp.Y },
        2,
        lake_blue
    };

    srand(time(NULL));
    short t = rand() % form.form;
    while (t--)
    {
        turn(&form);
    }
    return form;
}

static squre form6()        //类型6:|型
{
    COORD temp = tempXY();
    squre form{
        1,
        { { temp.X, temp.Y - 2 }, { temp.X, temp.Y - 1 }, { temp.X, temp.Y + 1 } },
        { temp.X, temp.Y },
        2,
        red
    };

    srand(time(NULL));
    short t = rand() % form.form;
    while (t--)
    {
        turn(&form);
    }
    return form;
}

static squre form7()        //类型7:■型
{
    COORD temp = tempXY();
    squre form{
        1,
        { { temp.X - TEMP, temp.Y - 1 }, { temp.X - TEMP, temp.Y }, { temp.X, temp.Y - 1 } },
        { temp.X, temp.Y },
        1,
        blue
    };
    return form;
}

static inline COORD tempXY()
{
    COORD temp;
    srand(time(NULL));
    temp.X = rand() % RANDOM_TRANSLATION + DISPLACEMENT;
    temp.Y = ORDINATE;
    return temp;
}

static bool check_full(const struct fixed * fixed, const int line)      //检查是否满行 no problem
{
    for (int i = 1; i < COLUMN - 1; i++)
    {
        if (!fixed->fix[line][i])
            return 0;
    }
    return 1;
}

static void update_fixed(struct fixed * fixed, short line[],short t)
{
    SetConsoleTextAttribute(hSqureConsole, 127);
    for (int k = t - 1; k >= 0; k--)
    {
        add_one(line[k],"+1");
        Sleep(20);
    }
    SetConsoleTextAttribute(hSqureConsole, 119);
    short heighest;
    for (int i = line[0] -1 ; i > 0; i--)
    {
        if (is_blank(fixed, i))
        {
            heighest = i;
            break;
        }
    }
    for (int i = 1; i < COLUMN - 1; i++)
    {
        for (int j = line[t - 1] - 1; j > heighest; j--)
        {
            COORD pos;
            if (j >= line[0])
            {
                short layer;
                if (layer = is_in_line(j, line, t))
                {
                    if (fixed->fix[j][i] == 0)
                    {
                        fixed->fix[j + layer][i] = 0;
                    }
                    else
                    {
                        fixed->fix[j][i] = 0;
                        pos.X = i;
                        pos.Y = j;
                        gotoxy(pos);
                        SetConsoleTextAttribute(hSqureConsole, 119);
                        cout << SPACE;
                        fixed->fix[j + layer][i] = 1;
                        fixed->color[j + layer][i] = fixed->color[j][i];
                        fixed->color[j][i] = 119;
                        pos.X = i;
                        pos.Y = j + layer;
                        gotoxy(pos);
                        SetConsoleTextAttribute(hSqureConsole, fixed->color[pos.Y][pos.X]);
                        cout << SQURE;
                        Sleep(UPDATE_TIME);
                    }
                }
            }
            else
            {
                if (fixed->fix[j][i] == 0)
                {
                    fixed->fix[j + t][i] = 0;
                }
                else
                {
                    fixed->fix[j][i] = 0;
                    pos.X = i;
                    pos.Y = j;
                    gotoxy(pos);
                    SetConsoleTextAttribute(hSqureConsole, 119);
                    cout << SPACE;
                    fixed->fix[j + t][i] = 1;
                    fixed->color[j + t][i] = fixed->color[j][i];
                    fixed->color[j][i] = 119;
                    pos.X = i;
                    pos.Y = j + t;
                    gotoxy(pos);
                    SetConsoleTextAttribute(hSqureConsole, fixed->color[pos.Y][pos.X]);
                    cout << SQURE;
                    Sleep(UPDATE_TIME);
                }
            }
        }
    }
    print_scoure();
    for (int k = t - 1; k >= 0; k--)
    {
        add_one(line[k], "  ");
        Sleep(20);
    }
}

static bool is_in_line(const short y, const short line[],const short t)
{
    for (int i = 0; i < t - 1; i++)
    {
        if (y == line[i])
            return 0;
    }
    for (int i = t-1; i >= 0; i--)
    {
        if (y > line[i])
            return i + 1;
    }
}

static bool is_blank(const struct fixed * fixed,const short line)       //no problem
{
    for (int i = 1; i < COLUMN - 1; i++)
    {
        if (fixed->fix[line][i])
            return 0;
    }
    return 1;
}

void eliminate(struct fixed * fixed, struct squre * form)           //no problem
{
    short line[4];
    short t=0;
    for (int i = 0; i < 3; i++)
    {
        if (check_full(fixed, form->pos[i].Y))
        {
            line[t++] = form->pos[i].Y;
        }
    }
    if (check_full(fixed, form->center.Y))
        line[t++] = form->center.Y;
    //********      no problem
    int repeat_time=0;
    for (int i = 0; i < t - 1; i++)
    {
        for (int j = i; j < t - 1; j++)
        {
            if (line[i] == line[j + 1] && line[i] != ROW)
            {
                line[j + 1] = ROW;
                repeat_time++;
            }
        }
    }
    t -= repeat_time;
    //********      no problem

    for (int i = 0; i < t - 1; i++)
    {
        for (int j = i + 1; j < t; j++)
        {
            if (line[i] > line[j])
            {
                int temp;
                temp = line[i];
                line[i] = line[j];
                line[j] = temp;
            }
        }
    }
    COORD pos;
    int etime;
    if (t)
    {
        etime = 840 / (COLUMN * t);
    }
    else
        etime = 60;
    for (int i = 1; i < COLUMN - 1; i++)
    {
        for (int j = 0; j < t; j++)
        {
            pos.X = i;
            pos.Y = line[j];
            gotoxy(pos);
            cout << "□";
            Sleep(etime / 2);
            gotoxy(pos);
            SetConsoleTextAttribute(hSqureConsole, 119);
            cout << SPACE;
        }
        Sleep(etime / 2);
    }
    if (t)
    {
        scoure += t;
        update_fixed(fixed, line, t);
    }
}

void add_one(short line, char ch[])
{
    COORD pos;
    pos.X = COLUMN;
    pos.Y = line;
    gotoxy(pos);
    fputs(ch, stdout);
}

void scoure_board()
{
    COORD pos;
    pos.X = COLUMN + 3;
    pos.Y = 2;
    gotoxy(pos);
    SetConsoleTextAttribute(hSqureConsole, 115);
    cout << "通关条件:消除" << WIN << "行";
    pos.Y += 2;
    gotoxy(pos);
    cout << "得分:" << scoure;
    pos.Y += 2;
    gotoxy(pos);
    cout << "Next squre:";
    pos.Y += ROW / 2;
    gotoxy(pos);
    cout << "操作:";
    pos.Y += 2;
    pos.X += 3;
    gotoxy(pos);
    cout << "↑ ↓ ← →";
}

void print_scoure()
{
    COORD pos;
    pos.X = COLUMN + 6;
    pos.Y = 4;
    gotoxy(pos);
    SetConsoleTextAttribute(hSqureConsole, 115);
    cout << scoure;
}

void print_next(const struct squre * form)
{
    COORD pos;
    pos.X = COLUMN + 6;
    pos.Y = 8;
    for (int i = 0; i < 4; i++)
    {
        gotoxy(pos);
        cout << "          ";
        pos.Y += 1;
    }
    pos.Y = 10;
    pos.X += 2;
    short a[3][2];
    struct squre temp;
    temp = * form;
    for (int i = 0; i < 3; i++)
    {
        a[i][0] = temp.center.X - temp.pos[i].X;
        a[i][1] = temp.center.Y - temp.pos[i].Y;
    }

    SetConsoleTextAttribute(hSqureConsole, temp.color);
    temp.center.X = pos.X;
    temp.center.Y = pos.Y;
    gotoxy(temp.center);
    cout << SQURE;
    for (int i = 0; i < 3; i++)
    {
        temp.pos[i].X = temp.center.X - a[i][0];
        temp.pos[i].Y = temp.center.Y - a[i][1];
        gotoxy(temp.pos[i]);
        cout << SQURE;
    }
    SetConsoleTextAttribute(hSqureConsole, 115);

}

void time_board()
{
    COORD pos;
    pos.X = COLUMN / 2 - 1;
    pos.Y = 3;
    gotoxy(pos);
    cout << "time:";
    Sleep(300);
    for (int i = 3; i > 0; i--)
    {
        pos.X = COLUMN / 2 + 2;
        gotoxy(pos);
        cout << i;
        Sleep(500);
    }
    pos.X = COLUMN / 2 - 1;
    gotoxy(pos);
    cout << "        ";
}

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值