#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;
}