c语言实现俄罗斯方块核心功能

#include <stdio.h>

#include <stdlib.h>

#include <conio.h>

#include <windows.h>

#include <stdbool.h>

#include <time.h>

// 区域

#define HEIGHT 40

#define WEIGHT 21

int chanum[7] = {2, 1, 2, 4, 2, 4, 4};

int count[7] = {0}; // 下标就是num,count相对应的值为变化的次数,之后通过取余实现循环

int num, score = 0; // num为代表图形的编号

bool isexist[HEIGHT + 1][WEIGHT + 1] = {0};

bool nogameover = 1, isvaild = 1;

bool flag = 0, hh; // 这个标志需要检测当前图形是否发生了碰撞,并且也是下一个图形出现的钥匙(记得还需要清零可以在下一个图形出现后设置)

typedef struct {

    int x;

    int y;

} russian;

russian picture[4]; // 接下来所生成的图形

russian check[4];

// 比对还原函数

void compare1() {

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

        check[i].x = picture[i].x;

        check[i].y = picture[i].y;

    }

}

// 比对继承函数

void compare2() {

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

        picture[i].x = check[i].x;

        picture[i].y = check[i].y;

    }

}

// 比对判断合法

void compare3() {

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

        if (isexist[check[i].y][check[i].x]) {

            isvaild = false;

            break;

        }

    }

}

// 归并三比较函数

void guibing() {

    compare3();

    if (isvaild) {

        compare2();

    } else {

        compare1();

    }

}

void change(int num1, int count1) {

    switch (num1) {

        case 0:

            if (count1 == 0) {

                int tmp1 = picture[1].x - 1;

                int tmp2 = picture[2].y;

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

                    check[i].x = tmp1 + i;

                    check[i].y = tmp2;

                }

                guibing();

            } else {

                int tmp1 = picture[1].x;

                int tmp2 = picture[1].y - 3;

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

                    check[i].x = tmp1;

                    check[i].y = tmp2 + i;

                }

                guibing();

            }

            break;

        case 1:

            break;

        case 2:

            if (count1 == 0) {

                check[0].x -= 2;

                check[1].x--;

                check[1].y--;

                check[3].x++;

                check[3].y--;

                guibing();

            } else {

                check[0].x += 2;

                check[1].x++;

                check[1].y++;

                check[3].x--;

                check[3].y++;

                guibing();

            }

            break;

        case 3:

            if (count1 == 0) {

                check[0].y--;

                check[1].x--;

                check[2].y++;

                check[3].x++;

                check[3].y += 2;

                guibing();

            } else if (count1 == 1) {

                check[0].x++;

                check[1].y--;

                check[2].x--;

                check[3].x -= 2;

                check[3].y++;

                guibing();

            } else if (count1 == 2) {

                check[0].y++;

                check[1].x++;

                check[2].y--;

                check[3].x--;

                check[3].y -= 2;

                guibing();

            } else {

                check[1].x++;

                check[1].y++;

                check[2].x += 2;

                check[3].x += 3;

                check[3].y--;

                guibing();

            }

            break;

        case 4:

            if (count1 == 1) {

                check[3].x++;

                check[3].y--;

                check[2].x += 2;

                check[1].x--;

                check[1].y--;

                guibing();

            } else {

                check[3].x--;

                check[3].y++;

                check[2].x -= 2;

                check[1].x++;

                check[1].y++;

                guibing();

            }

            break;

        case 5:

            if (count1 == 0) {

                check[1].x -= 2;

                check[2].y++;

                check[2].x--;

                check[3].y += 2;

                guibing();

            } else if (count1 == 1) {

                check[0].x++;

                check[0].y++;

                check[1].x++;

                check[1].y--;

                check[3].x--;

                check[3].y++;

                guibing();

            } else if (count1 == 2) {

                check[0].y++;

                check[0].x--;

                check[1].y++;

                check[1].x++;

                check[3].y--;

                check[3].x--;

                guibing();

            } else {

                check[0].x--;

                check[0].y--;

                check[1].x--;

                check[1].y++;

                check[3].x++;

                check[3].y--;

                guibing();

            }

            break;

        case 6:

            if (count1 == 0) {

                check[0].x++;

                check[0].y--;

                check[1].x += 2;

                check[2].y++;

                check[2].x += 3;

                guibing();

            } else if (count1 == 1) {

                check[0].x++;

                check[3].y--;

                check[1].y++;

                check[2].y += 2;

                check[2].x--;

                guibing();

            } else if (count1 == 2) {

                check[0].y++;

                check[1].x--;

                check[2].y--;

                check[2].x -= 2;

                check[3].x++;

                guibing();

            } else {

                check[3].x++;

                check[3].y++;

                check[1].x++;

                check[1].y--;

                check[2].x += 2;

                check[2].y -= 2;

                guibing();

            }

            break;

    }

}

void Initgame() {

    num = rand() % 7;

    switch (num) {

        case 0:

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

                picture[i].x = (WEIGHT / 2 - 1) + i;

                picture[i].y = 1;

                check[i].x = picture[i].x;

                check[i].y = picture[i].y;

            }

            break;

        case 1:

            for (int i = 0; i < 2; i++) {

                picture[i].x = (WEIGHT / 2) + i;

                picture[i].y = 1;

                check[i].x = picture[i].x;

                check[i].y = picture[i].y;

            }

            for (int i = 2; i < 4; i++) {

                picture[i].x = (WEIGHT / 2 - 2) + i;

                picture[i].y = 2;

                check[i].x = picture[i].x;

                check[i].y = picture[i].y;

            }

            break;

        case 2:

            for (int i = 0; i < 2; i++) {

                picture[i].x = (WEIGHT / 2 - 1) + i;

                picture[i].y = 1;

                check[i].x = picture[i].x;

                check[i].y = picture[i].y;

            }

            for (int i = 2; i < 4; i++) {

                picture[i].x = (WEIGHT / 2 - 2) + i;

                picture[i].y = 2;

                check[i].x = picture[i].x;

                check[i].y = picture[i].y;

            }

            break;

        case 3:

            picture[0].x = WEIGHT / 2 - 1;

            picture[0].y = 1;

            check[0].x = picture[0].x;

            check[0].y = picture[0].y;

            for (int i = 1; i < 4; i++) {

                picture[i].x = (WEIGHT / 2) + i - 2;

                picture[i].y = 2;

                check[i].x = picture[i].x;

                check[i].y = picture[i].y;

            }

            break;

        case 4:

            for (int i = 0; i < 2; i++) {

                picture[i].x = WEIGHT / 2 + i;

                picture[i].y = 1;

                check[i].x = picture[i].x;

                check[i].y = picture[i].y;

            }

            for (int i = 2; i < 4; i++) {

                picture[i].x = WEIGHT / 2 - 3 + i;

                picture[i].y = 2;

                check[i].x = picture[i].x;

                check[i].y = picture[i].y;

            }

            break;

        case 5:

            picture[0].x = WEIGHT / 2;

            picture[0].y = 1;

            check[0].x = picture[0].x;

            check[0].y = picture[0].y;

            for (int i = 1; i < 4; i++) {

                picture[i].x = WEIGHT / 2 - 2 + i;

                picture[i].y = 2;

                check[i].x = picture[i].x;

                check[i].y = picture[i].y;

            }

            break;

        case 6:

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

                picture[i].x = i + WEIGHT / 2 - 1;

                picture[i].y = 1;

                check[i].x = picture[i].x;

                check[i].y = picture[i].y;

            }

            picture[3].x = WEIGHT / 2 - 1;

            picture[3].y = 2;

            check[3].x = picture[3].x;

            check[3].y = picture[3].y;

            break;

    }

}

void draw() {

    system("cls");

    // 上边框

    for (int i = 0; i < 2 * WEIGHT + 2; i++) {

        printf("*");

    }

    printf("\n");

    for (int i = 1; i <= HEIGHT; i++) {

        printf("*"); // 左边框

        for (int x = 1; x <= WEIGHT; x++) {

            bool isPicture = false;

            // 检查当前方块

            for (int k = 0; k < 4; k++) {

                if (picture[k].x == x && picture[k].y == i) {

                    isPicture = true;

                    break;

                }

            }

            // 输出方块或空格

            if (isPicture || isexist[i][x]) {

                printf("()");

            } else {

                printf("  ");

            }

        }

        printf("*\n"); // 右边框

    }

    // 下边框

    for (int i = 0; i < 2 * WEIGHT + 2; i++) {

        printf("*");

    }

    printf("\n");

    printf("score = %d\n", score);

}

void move() {

    // 时间操控移动当前图形

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

        picture[i].y++;

        check[i].y = picture[i].y;

    }

    // 碰撞检测

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

        if (picture[i].y == HEIGHT || isexist[picture[i].y + 1][picture[i].x]) {

            flag = 1;

            break;

        }

    }

    if (flag) {

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

            isexist[picture[i].y][picture[i].x] = 1;

        }

        Initgame(); // 产生新图形

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

            count[i] = 0;

        }

        flag = 0;

    }

    // 逐行检测isexist

    for (int i = 1; i <= HEIGHT; i++) {

        bool meet = 1;

        for (int j = 1; j <= WEIGHT; j++) {

            if (isexist[i][j] == 0) {

                meet = 0;

                break;

            }

        }

        if (meet) { // 消行

            for (int m = i; m >= 2; m--) {

                for (int n = 1; n <= WEIGHT; n++) {

                    isexist[m][n] = isexist[m - 1][n];

                }

            }

            for (int n = 1; n <= WEIGHT; n++) {

                isexist[1][n] = 0;

            }

            score += 100;

        }

    }

}

void input() {

    if (_kbhit()) {

        bool canmove = 1;

        switch (_getch()) {

            case 'a':

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

                    if (picture[i].x == 1 || isexist[picture[i].y][picture[i].x - 1]) {

                        canmove = 0;

                        break;

                    }

                }

                if (canmove) {

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

                        picture[i].x--;

                        check[i].x = picture[i].x;

                    }

                }

                break;

            case 'd':

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

                    if (picture[i].x == WEIGHT || isexist[picture[i].y][picture[i].x + 1]) {

                        canmove = 0;

                        break;

                    }

                }

                if (canmove) {

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

                        picture[i].x++;

                        check[i].x = picture[i].x;

                    }

                }

                break;

            case 'q':

                nogameover = 0;

                break;

            case 'w':

                count[num] = (count[num] + 1) % chanum[num];

                isvaild = true;

                change(num, count[num]);

                break;

            case 's':

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

                    hh = 1;

                    if (picture[i].y >= HEIGHT - 2 || isexist[picture[i].y + 2][picture[i].x]) {

                        hh = 0;

                        break;

                    }

                }

                if (hh) {

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

                        picture[i].y += 2;

                        check[i].y = picture[i].y;

                    }

                }

                break;

        }

    }

}

int main() {

    srand(time(0));

    Initgame();

    while (nogameover) {

        draw();

        move();

        input();

        Sleep(100); // 控制游戏速度

    }

    system("pause");

    return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值