大一下学期实训所做。

/***********************************
	源码:俄罗斯方块
	作者:王卫祥&KX&2017211836
	版本:18070701
	代码使用请保留版权 
***********************************/



#include <stdio.h>
#include <windows.h>
#include <conio.h>
#include <time.h>

#define X(x) (2+2*(x))//棋盘坐标转屏幕绝对坐标 
#define Y(y) (y)//棋盘坐标转屏幕绝对坐标 
#define Grade(score) ((score)/50)//由分数计算等级 
#define BorderCode "▓"//边框字符
#define SpaceCode " "//空白处字符
#define BlockCode "■"//方块字符

int block[7][4][4][4]=
{
	{//第一种方块:正方形 
		{
			{1,1,0,0},
			{1,1,0,0},
			{0,0,0,0},
			{0,0,0,0}
		},
		{
			{1,1,0,0},
			{1,1,0,0},
			{0,0,0,0},
			{0,0,0,0}
		},
		{
			{1,1,0,0},
			{1,1,0,0},
			{0,0,0,0},
			{0,0,0,0}
		},
		{
			{1,1,0,0},
			{1,1,0,0},
			{0,0,0,0},
			{0,0,0,0}
		},
	},
	{//第二种方块:直线 
		{
			{0,0,0,0},
			{1,1,1,1},
			{0,0,0,0},
			{0,0,0,0}
		},
		{
			{0,1,0,0},
			{0,1,0,0},
			{0,1,0,0},
			{0,1,0,0}
		},
		{
			{0,0,0,0},
			{1,1,1,1},
			{0,0,0,0},
			{0,0,0,0}
		},
		{
			{0,1,0,0},
			{0,1,0,0},
			{0,1,0,0},
			{0,1,0,0}
		},
	},
	{//第三种方块:S形 
		{
			{1,0,0,0},
			{1,1,0,0},
			{0,1,0,0},
			{0,0,0,0}
		},
		{
			{0,1,1,0},
			{1,1,0,0},
			{0,0,0,0},
			{0,0,0,0}
		},
		{
			{1,0,0,0},
			{1,1,0,0},
			{0,1,0,0},
			{0,0,0,0}
		},
		{
			{0,1,1,0},
			{1,1,0,0},
			{0,0,0,0},
			{0,0,0,0}
		},
	},
	{//第四种方块:Z形 
		{
			{0,1,0,0},
			{1,1,0,0},
			{1,0,0,0},
			{0,0,0,0}
		},
		{
			{1,1,0,0},
			{0,1,1,0},
			{0,0,0,0},
			{0,0,0,0}
		},
		{
			{0,1,0,0},
			{1,1,0,0},
			{1,0,0,0},
			{0,0,0,0}
		},
		{
			{1,1,0,0},
			{0,1,1,0},
			{0,0,0,0},
			{0,0,0,0}
		},
	},
	{//第五种方块:J形 
		{
			{1,0,0,0},
			{1,1,1,0},
			{0,0,0,0},
			{0,0,0,0}
		},
		{
			{0,1,1,0},
			{0,1,0,0},
			{0,1,0,0},
			{0,0,0,0}
		},
		{
			{0,0,0,0},
			{1,1,1,0},
			{0,0,1,0},
			{0,0,0,0}
		},
		{
			{0,1,0,0},
			{0,1,0,0},
			{1,1,0,0},
			{0,0,0,0}
		},
	},
	{//第六种方块:┷形 
		{
			{0,1,0,0},
			{1,1,1,0},
			{0,0,0,0},
			{0,0,0,0}
		},
		{
			{0,1,0,0},
			{0,1,1,0},
			{0,1,0,0},
			{0,0,0,0}
		},
		{
			{0,0,0,0},
			{1,1,1,0},
			{0,1,0,0},
			{0,0,0,0}
		},
		{
			{0,1,0,0},
			{1,1,0,0},
			{0,1,0,0},
			{0,0,0,0}
		},
	},
	{//第七种方块:L形 
		{
			{0,0,1,0},
			{1,1,1,0},
			{0,0,0,0},
			{0,0,0,0}
		},
		{
			{0,1,0,0},
			{0,1,0,0},
			{0,1,1,0},
			{0,0,0,0}
		},
		{
			{0,0,0,0},
			{1,1,1,0},
			{1,0,0,0},
			{0,0,0,0}
		},
		{
			{1,1,0,0},
			{0,1,0,0},
			{0,1,0,0},
			{0,0,0,0}
		},
	},
};
int type,rotate,posiX,posiY;//当前下落方块的类型、旋转角度类型、(0,0)在屏幕上的位置 
int preType,preRotate;//下一个方块的类型、旋转角度类型
int width=10,height=30;//棋盘大小
int sta[20][10];//静态方块
int actExist=0;//下落方块是否存在 
int score;//本局得分 

void printGround();//打印背景 
void menu(int x,int y);//主菜单 
void start();//初始化游戏 
void run();//运行游戏 
void operate();//用户操控游戏 
void creatAct();//创建新的活动方块 
void rotateAct();//旋转活动方块 
void moveAct(int dire);//移动活动方块 
void clearAct();//在屏幕上清除活动方块 
void printAct();//在屏幕上打印活动方块 
void clearStaLine();//清除静态方块补全的行 
void clearSta();//清除所有静态方块 
int canFall();//判断活动方块是否可继续下落 
int isDeath();//判断玩家是否死亡 
void tipDeath();//提示用户死亡 
void act2Sta();//活动方块转静态方块 
void printScore();//打印分数、等级 
void printLine(int num,char *c);//在屏幕上打印num个字符c
//int getMaxScore();//获取最高分数 
//void puttMaxScore(); //写入最高分数 
void gotoxy(int x, int y); //光标定位
void setColor(unsigned short foreColor,unsigned short backGroundColor);//改变打印颜色 
void hideCursor();//隐藏光标 

int main(int argc, char *argv[])
{
	system("title 俄罗斯方块");
	system("mode con cols=39 lines=22");
	system("color F0");
	hideCursor();
	while(1)
		menu(7,8);
	getch();
	return 0;
}

void printGround()
{
    int i;
    setColor(3,15);
    gotoxy(0,0);
    for(i=0;i<20;i++)
    {
        printf("%s",BorderCode);
        printLine(10,SpaceCode);
        printf("%s",BorderCode);
        printLine(6,SpaceCode);
        printf("%s",BorderCode);
        printf("\n");
    }
    printLine(19,BorderCode);
    return;
}

void menu(int x,int y)
{
	char key;
	printGround();
	gotoxy(x,y);
	printf("俄罗斯方块");
	gotoxy(x,y+3);
	printf("1.开始游戏");
	gotoxy(x,y+4);
	printf("0.退出游戏");
	key=getch();
	switch(key)
	{
		case '1':start();run();break;
		case '0':exit(0);break;
	}

}

void start()
{
	int i,j;
	score=0;
	actExist=0;
	clearSta();
	printGround();
	setColor(0,15);
	gotoxy(X(11),Y(0));
	//maxScore=getMaxScore();
	//printf("最高分:%4d",maxScore);
	gotoxy(X(11),Y(2));
	printf("分数:");
	gotoxy(X(11),Y(4));
	printf("等级:");
	gotoxy(X(11),Y(6));
	printf("下一个:");
	gotoxy(X(11),Y(16));
	printf("1.暂停游戏");
	gotoxy(X(11),Y(17));
	printf("2.重新开始");
	gotoxy(X(11),Y(18));
	printf("0.退出游戏");
	printScore();
	srand((unsigned) time(NULL));
	creatAct();
}

void run()
{
	int delayTime;
 	clock_t lastTime=clock();
	while(1)
	{
		if(!actExist)
		{
			posiX=4;
			posiY=-2;
			type=preType;
			rotate=preRotate;
			creatAct();
			if(isDeath())
			{
				tipDeath();
				getch();
				break;
			}
			actExist=1;
			printAct();
		}
		delayTime=1000-Grade(score)*5;
		if(delayTime<200)
		{
			delayTime=200;
		}
		if(1000*((double)(clock()-lastTime)/CLOCKS_PER_SEC)>delayTime)
		{
			moveAct(3);
			lastTime= clock();
		}
		if(kbhit())
		{
			operate();
		}
	}
}

void operate()
{
	char key;
	if(!kbhit())
	{
		return;
	}
	key=getch();
	switch(key)
	{
		case 'a':
		case 'A':
		case 75:
			moveAct(0);break;
		case 'w':
		case 'W':
		case 72:
			rotateAct();break;
		case 'd':
		case 'D':
		case 77:
			moveAct(2);break;
		case 's':
		case 'S':
		case 80:
			moveAct(3);break;
		case ' ':
		case '\r':
			while(canFall())moveAct(3);break;
		case '1':
			getch();break;
		case '2':
			start();run();break;
		case '0':
			exit(0);break;
	}
}

void rotateAct()
{
	int canRotate=1;
	int i,j;
	for(i=0;i<4 && canRotate;i++)
	{
		for(j=0;j<4 && canRotate;j++)
		{
			if(block[type][(rotate+1)%4][i][j]==1 && (posiX+j <0 || posiX+j>=10 || posiY+i>=20 || sta[posiY+i][posiX+j]==1))
			{
				canRotate=0;
			}
		}
	}
	if(canRotate)
	{
		clearAct();
		rotate=rotate==3?0:rotate+1;
		printAct();

	}
}

void creatAct()
{
	preType=rand()%7;
	preRotate=rand()%4;
	int i,j;
	for(i=0;i<4;i++)
	{
		for(j=0;j<4;j++)
		{
			gotoxy(X(13+j),Y(8+i));
			if(block[preType][preRotate][i][j]==1)
			{
				printf("%s",BlockCode);
			}
			else
			{
				printf("%s",SpaceCode);
			}

		}
	}
}

void printAct()
{
	int i,j;
	setColor((type+preType+preRotate+score)%15,15);
	for(i=0;i<4;i++)
	{
		for(j=0;j<4;j++)
		{
			if(block[type][rotate][i][j]==1 && posiY+i>=0)
			{
				gotoxy(X(posiX+j),Y(posiY+i));
				printf("%s",BlockCode);
			}
		}
	}
}


void clearAct()
{
	int i,j;
	for(i=0;i<4;i++)
	{
		for(j=0;j<4;j++)
		{
			if(posiX+j>=0 && posiX+j<10 && posiY+i>=0 && posiY+i<20 && sta[posiY+i][posiX+j]==0)
			{
				gotoxy(X(posiX+j),Y(posiY+i));
				printf("%s",SpaceCode);
			}
		}
	}
}

void moveAct(int dire)
{
	int i,j;
	int canMove=1;
	if(dire==0)//左
	{
		for(i=0;i<4;i++)
		{
			for(j=0;j<4;j++)
			{
				if(block[type][rotate][i][j]==1 && (posiX+j<=0 || (posiY>0 && sta[posiY+i][posiX+j-1]==1)))
				{
					return;
				}
			}
		}
		clearAct();
		posiX--;
		printAct();

	}
	else if(dire==2)//右
	{
		for(i=0;i<4;i++)
		{
			for(j=0;j<4;j++)
			{
				if(block[type][rotate][i][j]==1 && (posiX+j>=9 || (posiY>0 &&sta[posiY+i][posiX+j+1]==1)))
				{
					return;
				}
			}
		}
		clearAct();
		posiX++;
		printAct();
	}
	else if(dire==3)//下
	{
		if(canFall())
		{
			clearAct();
			posiY++;
			printAct();
		}
		else
		{
			act2Sta();
			clearStaLine();
			actExist=0;
		}
	}
}

void clearStaLine()//清除排完的行
{
	int clearNum=0;
	int i,j;
	for(i=19;i>=0;i--)
	{
		for(j=0;j<10;j++)
		{
			if(sta[i][j]==0)
			{
				break;
			}
		}
		if(j==10)//第i行可以清空
		{
			clearNum++;
			score+=clearNum*i+Grade(score);//加分
			continue;
		}
		else if(clearNum!=0)
		{

			for(j=0;j<10;j++)
			{
				sta[i+clearNum][j]=sta[i][j];
			}
		}
	}
	while(clearNum)//顶部新生成的行赋值为0 
	{
		clearNum--;
		for(j=0;j<9;j++)
		{
			sta[clearNum][j]=0;
		}
	}
	setColor(8,15);
	for(i=0;i<20;i++)
	{
		for(j=0;j<10;j++)
		{
			gotoxy(X(j),Y(i));
			printf("%s",sta[i][j]==1?BlockCode:SpaceCode);
		}
	}
	printScore();

	/*
	if(score>maxScore)
	{
		maxScore=score;
		putMaxScore();
		printScore();

	}
	*/

}


void clearSta()
{
	int i,j;
	for(i=0;i<20;i++)
	{
		for(j=0;j<10;j++)
		{
			sta[i][j]=0;
		}
	}
}

int canFall()
{
	int i,j;
	for(i=0;i<4;i++)
	{
		for(j=0;j<4;j++)
		{
			if(block[type][rotate][i][j]==1 && (posiY+i>=19 || (posiY+i+1>=0 && sta[posiY+i+1][posiX+j]==1)))
			{
				return 0;
			}
		}
	}
	return 1;
}

int isDeath()
{
	if(sta[0][5]==1)
	{
		return 1;
	}
	return 0;
}

void tipDeath()
{
	gotoxy(X(11),Y(12));
	setColor(12,15);
	printf("游戏结束");
}

void act2Sta()
{
	int i,j;
	for(i=0;i<4;i++)
	{
		for(j=0;j<4;j++)
		{
			if(block[type][rotate][i][j]==1)
			{
				sta[posiY+i][posiX+j]=block[type][rotate][i][j];
			}
		}
	}
}

void printScore()
{
	//gotoxy(X(14),Y(0));
	//printf("%5d",maxScore);
	gotoxy(X(14),Y(2));
	printf("%5d",score);
	gotoxy(X(14),Y(4));
	printf("%5d",Grade(score));
}

void printLine(int num,char *c)
{
    int i;
    for(i=0;i<num;i++)
    {
        printf("%s",c);
    }
    return;
}

/*
int getMaxScore()
{
	FILE *fp;
	fp=fopen("tetris/maxScore.txt","r");
	if(fp==NULL)
	{
		maxScore=0;
	}
	else
	{
		fscanf(fp,"%d",&maxScore);
		fclose(fp);
	}
	return maxScore;
}

void putMaxScore()
{
	FILE *fp;
	fp=fopen("tetris/maxScore.txt","w");
	fprintf(fp,"%d",maxScore);
	fclose(fp);
}
*/

void gotoxy(int x, int y) //光标定位
{
    COORD pos;
    pos.X = x;
    pos.Y = y;
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),pos);
}

void setColor(unsigned short foreColor,unsigned short backGroundColor)
{
	HANDLE handle=GetStdHandle(STD_OUTPUT_HANDLE);//获取当前窗口句柄
	SetConsoleTextAttribute(handle,foreColor+backGroundColor*0x10);//设置颜色
}

void hideCursor()
{
	CONSOLE_CURSOR_INFO cursor_info = {1, 0};
	SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
}

/****Powered by KX****/
/*****KX收藏站*****/

运行效果:

C语言俄罗斯方块

下载EXE可运行文件


我一直在开辟我的天空