|
|
|
@ -0,0 +1,798 @@
|
|
|
|
|
#include<stdio.h> //标准输入输出
|
|
|
|
|
#include<windows.h> //控制控制台
|
|
|
|
|
#include<conio.h> //接收键盘信号
|
|
|
|
|
#include<time.h> //调用随机数函数
|
|
|
|
|
|
|
|
|
|
#define FrameX 13 // 游戏窗口左上角X坐标
|
|
|
|
|
#define FrameY 3 //游戏窗口左上角Y坐标
|
|
|
|
|
#define Frame_gao 20 //游戏窗口高度
|
|
|
|
|
#define Frame_kuan 18 //游戏窗口宽度
|
|
|
|
|
|
|
|
|
|
int i, j, temp, temp1, temp2; //定义全局变量, temp表示存储方块变量的值
|
|
|
|
|
int a[80][80] = {0}; //0表示无方块,1表示有方块, 2为边界
|
|
|
|
|
int b[4]; //四个方块,值为0,1
|
|
|
|
|
struct fangkuai
|
|
|
|
|
{
|
|
|
|
|
int x, y; //横纵坐标值
|
|
|
|
|
int flag; //方块类型序号
|
|
|
|
|
int next; //下一个方块序号
|
|
|
|
|
int speed; // 方块速度
|
|
|
|
|
int number; //方块个数
|
|
|
|
|
int score; //分数
|
|
|
|
|
int level; //游戏等级
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
HANDLE hOut; //控制台控制
|
|
|
|
|
|
|
|
|
|
/********函数声明**********/
|
|
|
|
|
void gotoxy(int x, int y); //光标移动到指定位置
|
|
|
|
|
int color(int c); //控制台文字颜色
|
|
|
|
|
void DrawGameframe(); //绘制游戏边界
|
|
|
|
|
void Flag(struct fangkuai *); //产生随机数
|
|
|
|
|
void Makefangkuai(struct fangkuai *); //制作方块
|
|
|
|
|
void printfangkuai(struct fangkuai *); //打印~
|
|
|
|
|
void cleanfangkuai(struct fangkuai *); //清除~
|
|
|
|
|
int ifMove(struct fangkuai *); //判断是否可移动
|
|
|
|
|
void Del_fullline(struct fangkuai *); //判断是否满行,并删除满行方块
|
|
|
|
|
void Gamebegin(); //游戏开始
|
|
|
|
|
void welcome(); //欢迎菜单
|
|
|
|
|
void explation(); //规则说明
|
|
|
|
|
void Replay(struct fangkuai *); //重新游戏
|
|
|
|
|
void title(); //界面上方标题
|
|
|
|
|
void close(); //关闭游戏
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*****控制文字颜色*******/
|
|
|
|
|
int color(int c){
|
|
|
|
|
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),c); //只在windows上改变文字颜色
|
|
|
|
|
return 0;
|
|
|
|
|
} //0~15,共16种颜色
|
|
|
|
|
/*用法:
|
|
|
|
|
coler(数字)
|
|
|
|
|
printf
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/*******文字显示位置********/
|
|
|
|
|
void gotoxy(int x, int y)
|
|
|
|
|
{
|
|
|
|
|
COORD pos;
|
|
|
|
|
pos.X = x;
|
|
|
|
|
pos.Y = y;
|
|
|
|
|
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),pos);
|
|
|
|
|
}
|
|
|
|
|
/*
|
|
|
|
|
用法:
|
|
|
|
|
gotoxy(30,10) 横向空30个单位,纵向空10个单位
|
|
|
|
|
printf
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/*****设置开始界面标题*****/
|
|
|
|
|
void title()
|
|
|
|
|
{
|
|
|
|
|
color(15);
|
|
|
|
|
gotoxy(30,3);
|
|
|
|
|
printf(" 俄 罗 斯 方 块");
|
|
|
|
|
color(11);
|
|
|
|
|
gotoxy(17,5);
|
|
|
|
|
printf("■");
|
|
|
|
|
gotoxy(17,6);
|
|
|
|
|
printf("■■");
|
|
|
|
|
gotoxy(17,7);
|
|
|
|
|
printf("■");
|
|
|
|
|
|
|
|
|
|
color(10);
|
|
|
|
|
gotoxy(25,5);
|
|
|
|
|
printf("■■");
|
|
|
|
|
gotoxy(25,6);
|
|
|
|
|
printf("■■");
|
|
|
|
|
|
|
|
|
|
color(13);
|
|
|
|
|
gotoxy(33,6);
|
|
|
|
|
printf("■■■■");
|
|
|
|
|
|
|
|
|
|
color(4);
|
|
|
|
|
gotoxy(45,5);
|
|
|
|
|
printf("■■");
|
|
|
|
|
gotoxy(45,6);
|
|
|
|
|
printf(" ■");
|
|
|
|
|
gotoxy(45,7);
|
|
|
|
|
printf(" ■");
|
|
|
|
|
|
|
|
|
|
color(12);
|
|
|
|
|
gotoxy(53,5);
|
|
|
|
|
printf("■■");
|
|
|
|
|
gotoxy(53,6);
|
|
|
|
|
printf(" ■■");
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*****设置菜单选项*****/
|
|
|
|
|
void welcome(){
|
|
|
|
|
int i = 1, j = 1;
|
|
|
|
|
int n;
|
|
|
|
|
color(14);
|
|
|
|
|
for(i = 9; i <= 20; i++){
|
|
|
|
|
for(j = 15; j <= 60; j++){
|
|
|
|
|
gotoxy(j, i);
|
|
|
|
|
if(i == 9 || i == 20){
|
|
|
|
|
printf("=");
|
|
|
|
|
}
|
|
|
|
|
else if(j == 15 || j == 59){
|
|
|
|
|
printf("||");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
color(12);
|
|
|
|
|
gotoxy(25,12);
|
|
|
|
|
printf("1.开始游戏");
|
|
|
|
|
gotoxy(40,12);
|
|
|
|
|
printf("2.说明和规则");
|
|
|
|
|
gotoxy(33,17);
|
|
|
|
|
printf("3.退出游戏\n");
|
|
|
|
|
gotoxy(31,19);
|
|
|
|
|
printf("本游戏纯属内测");
|
|
|
|
|
gotoxy(28,22);
|
|
|
|
|
color(3);
|
|
|
|
|
printf("请选择[1 2 3]:{ }\b\b");
|
|
|
|
|
color(14);
|
|
|
|
|
scanf("%d", &n);
|
|
|
|
|
switch(n)
|
|
|
|
|
{
|
|
|
|
|
case 1:
|
|
|
|
|
{
|
|
|
|
|
system("cls"); //清屏
|
|
|
|
|
DrawGameframe();
|
|
|
|
|
Gamebegin();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 2:
|
|
|
|
|
explation();
|
|
|
|
|
break;
|
|
|
|
|
case 3:
|
|
|
|
|
close();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****游戏窗口界面*****/
|
|
|
|
|
void DrawGameframe()
|
|
|
|
|
{
|
|
|
|
|
gotoxy((FrameX+Frame_kuan-7), FrameY-2);
|
|
|
|
|
color(11);
|
|
|
|
|
printf("俄罗斯方块");
|
|
|
|
|
|
|
|
|
|
color(12);
|
|
|
|
|
gotoxy(FrameX,FrameY);
|
|
|
|
|
printf("┎");
|
|
|
|
|
|
|
|
|
|
gotoxy(FrameX + 2*Frame_kuan-2,FrameY);
|
|
|
|
|
printf("┒");
|
|
|
|
|
|
|
|
|
|
gotoxy(FrameX,FrameY + Frame_gao);
|
|
|
|
|
printf("┖");
|
|
|
|
|
|
|
|
|
|
gotoxy(FrameX+ 2*Frame_kuan-2,FrameY + Frame_gao);
|
|
|
|
|
printf("┚");
|
|
|
|
|
a[FrameX+ 2*Frame_kuan-2][FrameY + Frame_gao] = 2;
|
|
|
|
|
/****上横框*****/
|
|
|
|
|
for(i = 2; i < 2 * Frame_kuan-2; i += 2){
|
|
|
|
|
gotoxy(FrameX + i, FrameY);
|
|
|
|
|
printf("━");
|
|
|
|
|
}
|
|
|
|
|
/*****下横框*****/
|
|
|
|
|
for(i = 2; i < 2 * Frame_kuan-2; i += 2){
|
|
|
|
|
gotoxy(FrameX + i, FrameY + Frame_gao);
|
|
|
|
|
printf("━");
|
|
|
|
|
a[FrameX + i][FrameY + Frame_gao] = 2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/****竖框****/
|
|
|
|
|
for(i = 1; i < Frame_gao; i++){ //左
|
|
|
|
|
gotoxy(FrameX, FrameY+i);
|
|
|
|
|
printf("┃");
|
|
|
|
|
a[FrameX][FrameY + i] = 2;
|
|
|
|
|
}
|
|
|
|
|
for(i = 1; i < Frame_gao; i++){
|
|
|
|
|
gotoxy(FrameX + 2 * Frame_kuan-2, FrameY+i);
|
|
|
|
|
printf("┃");
|
|
|
|
|
a[FrameX + 2 * Frame_kuan-2][FrameY+i] = 2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/****提示****/
|
|
|
|
|
color(2);
|
|
|
|
|
gotoxy(FrameX + 2* Frame_kuan + 3,FrameY + 7);
|
|
|
|
|
printf("**********");
|
|
|
|
|
gotoxy(FrameX + 2* Frame_kuan + 3,FrameY + 13);
|
|
|
|
|
printf("**********");
|
|
|
|
|
color(3);
|
|
|
|
|
gotoxy(FrameX + 2* Frame_kuan + 3,FrameY + 6);
|
|
|
|
|
printf("下一个方块:");
|
|
|
|
|
|
|
|
|
|
color(14);
|
|
|
|
|
gotoxy(FrameX + 2* Frame_kuan + 3,FrameY + 17);
|
|
|
|
|
printf("空格:暂停游戏");
|
|
|
|
|
gotoxy(FrameX + 2* Frame_kuan + 3,FrameY + 19);
|
|
|
|
|
printf("ESC:退出游戏");
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/****制作方块*****/
|
|
|
|
|
void Makefangkuai(struct fangkuai *tetris)
|
|
|
|
|
{
|
|
|
|
|
a[tetris->x][tetris->y] = b[0];
|
|
|
|
|
switch(tetris->flag)
|
|
|
|
|
{
|
|
|
|
|
case 1: //田字方块
|
|
|
|
|
{
|
|
|
|
|
a[tetris->x][tetris->y-1]=b[1];
|
|
|
|
|
a[tetris->x+2][tetris->y-1]=b[2];
|
|
|
|
|
a[tetris->x+2][tetris->y]=b[3];
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 2: //直线方块:----
|
|
|
|
|
{
|
|
|
|
|
a[tetris->x-2][tetris->y]=b[1];
|
|
|
|
|
a[tetris->x+2][tetris->y]=b[2];
|
|
|
|
|
a[tetris->x+4][tetris->y]=b[3];
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 3: //直线方块: |
|
|
|
|
|
{
|
|
|
|
|
a[tetris->x][tetris->y-1]=b[1];
|
|
|
|
|
a[tetris->x][tetris->y-2]=b[2];
|
|
|
|
|
a[tetris->x][tetris->y+1]=b[3];
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 4: //T字方块
|
|
|
|
|
{
|
|
|
|
|
a[tetris->x-2][tetris->y]=b[1];
|
|
|
|
|
a[tetris->x+2][tetris->y]=b[2];
|
|
|
|
|
a[tetris->x][tetris->y+1]=b[3];
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 5: //T字顺时针转90度方块
|
|
|
|
|
{
|
|
|
|
|
a[tetris->x][tetris->y-1]=b[1];
|
|
|
|
|
a[tetris->x][tetris->y+1]=b[2];
|
|
|
|
|
a[tetris->x-2][tetris->y]=b[3];
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 6: //T字顺时针转180度方块
|
|
|
|
|
{
|
|
|
|
|
a[tetris->x][tetris->y-1]=b[1];
|
|
|
|
|
a[tetris->x-2][tetris->y]=b[2];
|
|
|
|
|
a[tetris->x+2][tetris->y]=b[3];
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 7: //T字顺时针转270度方块
|
|
|
|
|
{
|
|
|
|
|
a[tetris->x][tetris->y-1]=b[1];
|
|
|
|
|
a[tetris->x][tetris->y+1]=b[2];
|
|
|
|
|
a[tetris->x+2][tetris->y]=b[3];
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 8: //Z字方块
|
|
|
|
|
{
|
|
|
|
|
a[tetris->x][tetris->y+1]=b[1];
|
|
|
|
|
a[tetris->x-2][tetris->y]=b[2];
|
|
|
|
|
a[tetris->x+2][tetris->y+1]=b[3];
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 9: //Z字顺时针转90度方块
|
|
|
|
|
{
|
|
|
|
|
a[tetris->x][tetris->y-1]=b[1];
|
|
|
|
|
a[tetris->x-2][tetris->y]=b[2];
|
|
|
|
|
a[tetris->x-2][tetris->y+1]=b[3];
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 10: //Z字顺时针转180度方块
|
|
|
|
|
{
|
|
|
|
|
a[tetris->x][tetris->y-1]=b[1];
|
|
|
|
|
a[tetris->x-2][tetris->y-1]=b[2];
|
|
|
|
|
a[tetris->x+2][tetris->y]=b[3];
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 11: //Z字顺时针转270度方块
|
|
|
|
|
{
|
|
|
|
|
a[tetris->x][tetris->y+1]=b[1];
|
|
|
|
|
a[tetris->x+2][tetris->y-1]=b[2];
|
|
|
|
|
a[tetris->x+2][tetris->y]=b[3];
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 12: //7字方块
|
|
|
|
|
{
|
|
|
|
|
a[tetris->x][tetris->y-1]=b[1];
|
|
|
|
|
a[tetris->x][tetris->y+1]=b[2];
|
|
|
|
|
a[tetris->x-2][tetris->y-1]=b[3];
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 13: //7字顺时针转90度方块
|
|
|
|
|
{
|
|
|
|
|
a[tetris->x-2][tetris->y]=b[1];
|
|
|
|
|
a[tetris->x-2][tetris->y+1]=b[2];
|
|
|
|
|
a[tetris->x+2][tetris->y]=b[3];
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 14: //7字顺时针转180度方块
|
|
|
|
|
{
|
|
|
|
|
a[tetris->x][tetris->y-1]=b[1];
|
|
|
|
|
a[tetris->x][tetris->y+1]=b[2];
|
|
|
|
|
a[tetris->x+2][tetris->y+1]=b[3];
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 15: //7字顺时针转270度方块
|
|
|
|
|
{
|
|
|
|
|
a[tetris->x-2][tetris->y]=b[1];
|
|
|
|
|
a[tetris->x+2][tetris->y-1]=b[2];
|
|
|
|
|
a[tetris->x+2][tetris->y]=b[3];
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 16: //倒7字方块
|
|
|
|
|
{
|
|
|
|
|
a[tetris->x][tetris->y+1]=b[1];
|
|
|
|
|
a[tetris->x][tetris->y-1]=b[2];
|
|
|
|
|
a[tetris->x+2][tetris->y-1]=b[3];
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 17: //倒7字顺指针转90度方块
|
|
|
|
|
{
|
|
|
|
|
a[tetris->x-2][tetris->y]=b[1];
|
|
|
|
|
a[tetris->x-2][tetris->y-1]=b[2];
|
|
|
|
|
a[tetris->x+2][tetris->y]=b[3];
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 18: //倒7字顺时针转180度方块
|
|
|
|
|
{
|
|
|
|
|
a[tetris->x][tetris->y-1]=b[1];
|
|
|
|
|
a[tetris->x][tetris->y+1]=b[2];
|
|
|
|
|
a[tetris->x-2][tetris->y+1]=b[3];
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 19: //倒7字顺时针转270度方块
|
|
|
|
|
{
|
|
|
|
|
a[tetris->x-2][tetris->y]=b[1];
|
|
|
|
|
a[tetris->x+2][tetris->y+1]=b[2];
|
|
|
|
|
a[tetris->x+2][tetris->y]=b[3];
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/****打印方块*****/
|
|
|
|
|
|
|
|
|
|
void Printfangkuai(struct fangkuai *tetris)
|
|
|
|
|
{
|
|
|
|
|
for(i = 0; i < 4; i++)
|
|
|
|
|
{
|
|
|
|
|
b[i] = 1;
|
|
|
|
|
}
|
|
|
|
|
Makefangkuai(tetris);
|
|
|
|
|
for(i = tetris->x-2; i <= tetris->x+4; i += 2){
|
|
|
|
|
for(j = tetris->y-2; j <= tetris->y+1; j++){
|
|
|
|
|
if(a[i][j] == 1 && j > FrameY){
|
|
|
|
|
gotoxy(i, j);
|
|
|
|
|
printf("■");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****打印信息******/
|
|
|
|
|
gotoxy(FrameX + 2 * Frame_kuan+3,FrameY + 1);
|
|
|
|
|
color(4);
|
|
|
|
|
printf("等级: ");
|
|
|
|
|
color(12);
|
|
|
|
|
printf("%d", tetris->level);
|
|
|
|
|
|
|
|
|
|
gotoxy(FrameX + 2 * Frame_kuan+3,FrameY + 3);
|
|
|
|
|
color(4);
|
|
|
|
|
printf("分数: ");
|
|
|
|
|
color(12);
|
|
|
|
|
printf("%d", tetris->score);
|
|
|
|
|
|
|
|
|
|
gotoxy(FrameX + 2 * Frame_kuan+3,FrameY + 5);
|
|
|
|
|
color(4);
|
|
|
|
|
printf("速度: ");
|
|
|
|
|
color(12);
|
|
|
|
|
printf("%dms", tetris->speed);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*****判断是否可移动*****/
|
|
|
|
|
int ifMove(struct fangkuai *tetris)
|
|
|
|
|
{
|
|
|
|
|
if(a[tetris->x][tetris->y] != 0){ //中心方块处不为空
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if(//当为田字方块且除中心方块位置外,其他"口"字方块位置上无图案时,返回值为1,即可移动
|
|
|
|
|
( tetris->flag==1 && ( a[tetris->x][tetris->y-1]==0 &&
|
|
|
|
|
a[tetris->x+2][tetris->y-1]==0 && a[tetris->x+2][tetris->y]==0 ) ) ||
|
|
|
|
|
//或为直线方块且除中心方块位置外,其他"口"字方块位置上无图案时,返回值为1,即可移动
|
|
|
|
|
( tetris->flag==2 && ( a[tetris->x-2][tetris->y]==0 &&
|
|
|
|
|
a[tetris->x+2][tetris->y]==0 && a[tetris->x+4][tetris->y]==0 ) ) ||
|
|
|
|
|
|
|
|
|
|
( tetris->flag==3 && ( a[tetris->x][tetris->y-1]==0 &&
|
|
|
|
|
a[tetris->x][tetris->y-2]==0 && a[tetris->x][tetris->y+1]==0 ) ) ||
|
|
|
|
|
|
|
|
|
|
( tetris->flag==4 && ( a[tetris->x-2][tetris->y]==0 &&
|
|
|
|
|
a[tetris->x+2][tetris->y]==0 && a[tetris->x][tetris->y+1]==0 ) ) ||
|
|
|
|
|
|
|
|
|
|
( tetris->flag==5 && ( a[tetris->x][tetris->y-1]==0 &&
|
|
|
|
|
a[tetris->x][tetris->y+1]==0 && a[tetris->x-2][tetris->y]==0 ) ) ||
|
|
|
|
|
|
|
|
|
|
( tetris->flag==6 && ( a[tetris->x][tetris->y-1]==0 &&
|
|
|
|
|
a[tetris->x-2][tetris->y]==0 && a[tetris->x+2][tetris->y]==0 ) ) ||
|
|
|
|
|
|
|
|
|
|
( tetris->flag==7 && ( a[tetris->x][tetris->y-1]==0 &&
|
|
|
|
|
a[tetris->x][tetris->y+1]==0 && a[tetris->x+2][tetris->y]==0 ) ) ||
|
|
|
|
|
|
|
|
|
|
( tetris->flag==8 && ( a[tetris->x][tetris->y+1]==0 &&
|
|
|
|
|
a[tetris->x-2][tetris->y]==0 && a[tetris->x+2][tetris->y+1]==0 ) ) ||
|
|
|
|
|
|
|
|
|
|
( tetris->flag==9 && ( a[tetris->x][tetris->y-1]==0 &&
|
|
|
|
|
a[tetris->x-2][tetris->y]==0 && a[tetris->x-2][tetris->y+1]==0 ) ) ||
|
|
|
|
|
|
|
|
|
|
( tetris->flag==10 && ( a[tetris->x][tetris->y-1]==0 &&
|
|
|
|
|
a[tetris->x-2][tetris->y-1]==0 && a[tetris->x+2][tetris->y]==0 ) ) ||
|
|
|
|
|
|
|
|
|
|
( tetris->flag==11 && ( a[tetris->x][tetris->y+1]==0 &&
|
|
|
|
|
a[tetris->x+2][tetris->y-1]==0 && a[tetris->x+2][tetris->y]==0 ) ) ||
|
|
|
|
|
|
|
|
|
|
( tetris->flag==12 && ( a[tetris->x][tetris->y-1]==0 &&
|
|
|
|
|
a[tetris->x][tetris->y+1]==0 && a[tetris->x-2][tetris->y-1]==0 ) ) ||
|
|
|
|
|
|
|
|
|
|
( tetris->flag==13 && ( a[tetris->x-2][tetris->y]==0 &&
|
|
|
|
|
a[tetris->x-2][tetris->y+1]==0 && a[tetris->x+2][tetris->y]==0 ) ) ||
|
|
|
|
|
|
|
|
|
|
( tetris->flag==14 && ( a[tetris->x][tetris->y-1]==0 &&
|
|
|
|
|
a[tetris->x][tetris->y+1]==0 && a[tetris->x+2][tetris->y+1]==0 ) ) ||
|
|
|
|
|
|
|
|
|
|
( tetris->flag==15 && ( a[tetris->x-2][tetris->y]==0 &&
|
|
|
|
|
a[tetris->x+2][tetris->y-1]==0 && a[tetris->x+2][tetris->y]==0 ) ) ||
|
|
|
|
|
|
|
|
|
|
( tetris->flag==16 && ( a[tetris->x][tetris->y+1]==0 &&
|
|
|
|
|
a[tetris->x][tetris->y-1]==0 && a[tetris->x+2][tetris->y-1]==0 ) ) ||
|
|
|
|
|
|
|
|
|
|
( tetris->flag==17 && ( a[tetris->x-2][tetris->y]==0 &&
|
|
|
|
|
a[tetris->x-2][tetris->y-1]==0 && a[tetris->x+2][tetris->y]==0 ) ) ||
|
|
|
|
|
|
|
|
|
|
( tetris->flag==18 && ( a[tetris->x][tetris->y-1]==0 &&
|
|
|
|
|
a[tetris->x][tetris->y+1]==0 && a[tetris->x-2][tetris->y+1]==0 ) ) ||
|
|
|
|
|
|
|
|
|
|
( tetris->flag==19 && ( a[tetris->x-2][tetris->y]==0 &&
|
|
|
|
|
a[tetris->x+2][tetris->y+1]==0 && a[tetris->x+2][tetris->y]==0 ) )
|
|
|
|
|
)
|
|
|
|
|
{
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****清除方块轨迹******/
|
|
|
|
|
void Cleanfangkuai(struct fangkuai *tetris)
|
|
|
|
|
{
|
|
|
|
|
for(i = 0; i < 4; i++){
|
|
|
|
|
b[i] = 0;
|
|
|
|
|
}
|
|
|
|
|
Makefangkuai(tetris);
|
|
|
|
|
for(i = tetris->x-2; i <= tetris->x+4; i += 2){
|
|
|
|
|
for(j = tetris->y-2; j <= tetris->y + 1; j++){
|
|
|
|
|
if(a[i][j] == 0 && j > FrameY){
|
|
|
|
|
gotoxy(i, j);
|
|
|
|
|
printf(" "); //将上一个方块的轨迹以空格代替
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/******判断满行并删除******/
|
|
|
|
|
void Del_fullline(struct fangkuai *tetris)
|
|
|
|
|
{
|
|
|
|
|
int k, del_rows = 0;
|
|
|
|
|
for(j = FrameY+Frame_gao-1; j >= FrameY+1; j--){
|
|
|
|
|
k=0;
|
|
|
|
|
for(i = FrameX+2; i < FrameX + 2* Frame_kuan - 2; i += 2){ //从左下角开始向右上方遍历
|
|
|
|
|
if(a[i][j] == 1){
|
|
|
|
|
k++;
|
|
|
|
|
if(k == Frame_kuan - 2) //k代表i——横坐标
|
|
|
|
|
{
|
|
|
|
|
for(k = FrameX + 2; k < FrameX + 2 * Frame_kuan - 2; k += 2)
|
|
|
|
|
{
|
|
|
|
|
a[k][j] = 0;
|
|
|
|
|
gotoxy(k, j);
|
|
|
|
|
printf(" "); //删除整行
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for(k = j-1; k > FrameY; k--) //k代表j——纵坐标
|
|
|
|
|
{
|
|
|
|
|
for(i = FrameX + 2; i < FrameX + 2 * Frame_kuan-2; i += 2)
|
|
|
|
|
{
|
|
|
|
|
if(a[i][k] == 1)
|
|
|
|
|
{
|
|
|
|
|
a[i][k] == 0;
|
|
|
|
|
gotoxy(i,k);
|
|
|
|
|
printf(" ");
|
|
|
|
|
a[i][k+1] == 1;
|
|
|
|
|
gotoxy(i, k+1);
|
|
|
|
|
printf("■");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
j++;
|
|
|
|
|
del_rows++; //记录删除行数
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
tetris->score += 100*del_rows; //得分
|
|
|
|
|
if(del_rows > 0 && (tetris->score % 1000 == 0 || (tetris->score / 1000) > (tetris->level-1)))
|
|
|
|
|
{
|
|
|
|
|
tetris->speed -= 20;
|
|
|
|
|
tetris->level++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*****随机产生方块*****/
|
|
|
|
|
void Flag(struct fangkuai *tetris)
|
|
|
|
|
{
|
|
|
|
|
tetris->number++;
|
|
|
|
|
srand(time(NULL)); //初始化随机数
|
|
|
|
|
if(tetris->number == 1)
|
|
|
|
|
{
|
|
|
|
|
tetris->flag == rand()%19+1; //rand产生随机数,除取余,结果为0~18
|
|
|
|
|
}
|
|
|
|
|
tetris->next = rand()%19+1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******开始游戏********/
|
|
|
|
|
void Gamebegin()
|
|
|
|
|
{
|
|
|
|
|
int n;
|
|
|
|
|
struct fangkuai t, *tetris = &t; //定义变量
|
|
|
|
|
char ch;
|
|
|
|
|
tetris->number = 0; //初始方块数为0
|
|
|
|
|
tetris->speed = 300; //初始化速度
|
|
|
|
|
tetris->score = 0; //初始得分
|
|
|
|
|
tetris->level = 1; //初始等级
|
|
|
|
|
while(1)
|
|
|
|
|
{
|
|
|
|
|
Flag(tetris);
|
|
|
|
|
temp = tetris->flag; //temp将下一个方块输入到游戏中
|
|
|
|
|
tetris->x = FrameX + 2 * Frame_kuan + 6;
|
|
|
|
|
tetris->y = FrameY +10;
|
|
|
|
|
tetris->flag = tetris->next;
|
|
|
|
|
Printfangkuai(tetris);
|
|
|
|
|
tetris->x = FrameX + Frame_kuan;
|
|
|
|
|
tetris->y = FrameY -1;
|
|
|
|
|
tetris->flag = temp;
|
|
|
|
|
|
|
|
|
|
//按键操作
|
|
|
|
|
while(1) //控制方块变化,直至不再下落
|
|
|
|
|
{
|
|
|
|
|
label:Printfangkuai(tetris); //打印方块
|
|
|
|
|
Sleep(tetris->speed); //延缓时间
|
|
|
|
|
Cleanfangkuai(tetris); //清除痕迹
|
|
|
|
|
temp1 = tetris->x; //标定中心方块横坐标的值
|
|
|
|
|
temp2 = tetris->flag; //记住当前俄罗斯方块的序号
|
|
|
|
|
if(kbhit()) //判断是否有键盘输入(kbhit)
|
|
|
|
|
{
|
|
|
|
|
ch = getch(); //用ch接收
|
|
|
|
|
if((ch == 75) || (ch == 'a' || ch == 'A'))
|
|
|
|
|
{
|
|
|
|
|
tetris->x-=2; //方向键左或A,则向左移动,中心横坐标减2
|
|
|
|
|
}
|
|
|
|
|
if((ch == 77) || (ch == 'd' || ch == 'D'))
|
|
|
|
|
{
|
|
|
|
|
tetris->x+=2; //方向键右或D,则向右移动,中心横坐标加2
|
|
|
|
|
}
|
|
|
|
|
if((ch == 0x28) || (ch == 's' || ch == 'S')) //下键或S,则向下加速
|
|
|
|
|
{
|
|
|
|
|
if(ifMove(tetris) != 0)
|
|
|
|
|
{
|
|
|
|
|
tetris->y+=2;
|
|
|
|
|
}
|
|
|
|
|
if(ifMove(tetris) == 0)
|
|
|
|
|
{
|
|
|
|
|
tetris->y = FrameY + Frame_gao - 2;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if((ch == 72) || (ch == 'w' || ch == 'W')) //按上键和W改变方块形状
|
|
|
|
|
{
|
|
|
|
|
if( tetris->flag>=2 && tetris->flag<=3 )
|
|
|
|
|
{
|
|
|
|
|
tetris->flag++;
|
|
|
|
|
tetris->flag%=2;
|
|
|
|
|
tetris->flag+=2;
|
|
|
|
|
}
|
|
|
|
|
if( tetris->flag>=4 && tetris->flag<=7 )
|
|
|
|
|
{
|
|
|
|
|
tetris->flag++;
|
|
|
|
|
tetris->flag%=4;
|
|
|
|
|
tetris->flag+=4;
|
|
|
|
|
}
|
|
|
|
|
if( tetris->flag>=8 && tetris->flag<=11 )
|
|
|
|
|
{
|
|
|
|
|
tetris->flag++;
|
|
|
|
|
tetris->flag%=4;
|
|
|
|
|
tetris->flag+=8;
|
|
|
|
|
}
|
|
|
|
|
if( tetris->flag>=12 && tetris->flag<=15 )
|
|
|
|
|
{
|
|
|
|
|
tetris->flag++;
|
|
|
|
|
tetris->flag%=4;
|
|
|
|
|
tetris->flag+=12;
|
|
|
|
|
}
|
|
|
|
|
if( tetris->flag>=16 && tetris->flag<=19 )
|
|
|
|
|
{
|
|
|
|
|
tetris->flag++;
|
|
|
|
|
tetris->flag%=4;
|
|
|
|
|
tetris->flag+=16;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if(ch == 32){ //空格,暂停
|
|
|
|
|
Printfangkuai(tetris);
|
|
|
|
|
while(1)
|
|
|
|
|
{
|
|
|
|
|
if(kbhit())
|
|
|
|
|
{
|
|
|
|
|
ch == getch(); //再按,继续游戏
|
|
|
|
|
if(ch == 32)
|
|
|
|
|
{
|
|
|
|
|
goto label;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(ch == 27) //按ESC退出至菜单界面
|
|
|
|
|
{
|
|
|
|
|
system("cls");
|
|
|
|
|
memset(a,0,6400*sizeof(int)); //初始化BOX数据
|
|
|
|
|
welcome();
|
|
|
|
|
}
|
|
|
|
|
if(ifMove(tetris) == 0) //如果不可动,上述操作无效
|
|
|
|
|
{
|
|
|
|
|
tetris->x = temp1;
|
|
|
|
|
tetris->flag = temp2;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
goto label;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
tetris->y++; //若无操作指令,则方块自由下落
|
|
|
|
|
if(ifMove(tetris) == 0) //若方块不可移动,则方块放置于此
|
|
|
|
|
{
|
|
|
|
|
tetris->y--;
|
|
|
|
|
Printfangkuai(tetris);
|
|
|
|
|
Del_fullline(tetris);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for(i = tetris->y; i < tetris->y+1; i++) //方块触及顶部,游戏结束
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
if(i == FrameY)
|
|
|
|
|
{
|
|
|
|
|
system("cls");
|
|
|
|
|
gotoxy(29,7);
|
|
|
|
|
printf(" \n");
|
|
|
|
|
color(12);
|
|
|
|
|
printf("\t\t\t■■■■ ■ ■ ■■■\n");
|
|
|
|
|
printf("\t\t\t■ ■■ ■ ■ ■\n");
|
|
|
|
|
printf("\t\t\t■■■■ ■ ■ ■ ■ ■\n");
|
|
|
|
|
printf("\t\t\t■ ■ ■■ ■ ■\n");
|
|
|
|
|
printf("\t\t\t■■■■ ■ ■ ■■■\n");
|
|
|
|
|
gotoxy(17,18);
|
|
|
|
|
color(14);
|
|
|
|
|
printf("我还要玩------1");
|
|
|
|
|
gotoxy(44,18);
|
|
|
|
|
printf("我不玩了------2\n");
|
|
|
|
|
int n;
|
|
|
|
|
gotoxy(32,20);
|
|
|
|
|
printf("选择【1/2】:");
|
|
|
|
|
color(11);
|
|
|
|
|
scanf("%d", &n);
|
|
|
|
|
switch(n)
|
|
|
|
|
{
|
|
|
|
|
case 1:
|
|
|
|
|
{
|
|
|
|
|
system("cls");
|
|
|
|
|
Replay(tetris); //重新开始游戏
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 2:
|
|
|
|
|
exit(0);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
tetris->flag = tetris->next; //清除右边窗口的下一个方块
|
|
|
|
|
tetris->x = FrameX + 2 * Frame_kuan +6;
|
|
|
|
|
tetris->y = FrameY + 10;
|
|
|
|
|
Cleanfangkuai(tetris);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/******重新开始******/
|
|
|
|
|
void Replay(struct fangkuai *tetris)
|
|
|
|
|
{
|
|
|
|
|
system("cls");
|
|
|
|
|
memset(a,0,6400*sizeof(int)); //memset——初始化数组(数组名,数据,数组个数*长度)
|
|
|
|
|
DrawGameframe();
|
|
|
|
|
Gamebegin();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******规则说明*******/
|
|
|
|
|
void explation()
|
|
|
|
|
{
|
|
|
|
|
int i, j = 1;
|
|
|
|
|
system("cls");
|
|
|
|
|
color(13);
|
|
|
|
|
gotoxy(32,3);
|
|
|
|
|
printf("按键说明");
|
|
|
|
|
color(2);
|
|
|
|
|
for(i == 6; i <= 16; i++) //y轴坐标值
|
|
|
|
|
{
|
|
|
|
|
for(j = 15; j <= 60; j++)
|
|
|
|
|
{
|
|
|
|
|
gotoxy(j,i);
|
|
|
|
|
if(i == 6 || i == 16)
|
|
|
|
|
{
|
|
|
|
|
printf("=");
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
else if(j == 15 || j == 59)
|
|
|
|
|
{
|
|
|
|
|
printf("||");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
color(3);
|
|
|
|
|
gotoxy(18,7);
|
|
|
|
|
printf("tip1:玩家可以通过A、D或左右方向键控制方向");
|
|
|
|
|
color(10);
|
|
|
|
|
gotoxy(18,9);
|
|
|
|
|
printf("tip2:通过W或上方向键使方块逆时针旋转");
|
|
|
|
|
color(14);
|
|
|
|
|
gotoxy(18,11);
|
|
|
|
|
printf("tip3:通过S或下方向键加速方块下落");
|
|
|
|
|
color(11);
|
|
|
|
|
gotoxy(18,13);
|
|
|
|
|
printf("tip4:按空格暂停游戏,再按空格继续");
|
|
|
|
|
color(4);
|
|
|
|
|
gotoxy(18,15);
|
|
|
|
|
printf("tip5:按ESC退出游戏");
|
|
|
|
|
getch(); //按任意键返回主菜单
|
|
|
|
|
system("cls");
|
|
|
|
|
main();
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/****退出游戏****/
|
|
|
|
|
void close()
|
|
|
|
|
{
|
|
|
|
|
exit(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int main(){
|
|
|
|
|
title();
|
|
|
|
|
welcome();
|
|
|
|
|
}
|
|
|
|
|
|