俄罗斯方块_代码+解析

目录

1.完整代码:

2.代码解析

2-1:头文件;

2-2:常量的定义与声明;

2-3:变量的定义与声明;

2-4:各类函数的声明;

2-5:程序主干-主函数;

2-6:移动光标函数;

2-7:设置颜色函数;

2-8:初始化函数;

2-9:游戏开始设置;

2-10:画地图函数;

2-11:判断方块是否可以下落的函数;

2-12:打印方块函数;

2-13:清除方块函数;

2-14:修改地图函数;

2-15:旋转方块函数;

2-16:输入函数;

2-17:打印得分函数;

2-18:判断游戏结束函数;


1.完整代码:

#include<bits/stdc++.h>
#include<windows.h>
#include<conio.h>
using namespace std;
#define Y 22
#define X 14
#define WHITE 7
#define WAIT_TIME 100
int Map[Y][X];
int z[6][4][2],which,_long[6],zx,zy,sw,sc;
char c;
int df;
void color(int a);
void gotoxy(int i,int j);
void csh();
void start();
void drawmap();
bool candown();
void drawz();
void clsz();
void change();
void turn(string s);
void _cin();
void printdf();
bool gameover();
int main(){
	start();
	while(true){
		system("cls");
		for(int y=0;y<Y;y++)
			for(int x=0;x<X;x++)
				Map[y][x]=0;
		for(int y=0;y<Y;y++)
			Map[y][0]=Map[y][X-1]=7;
		for(int x=0;x<X;x++)
			Map[0][x]=Map[Y-1][x]=7;
		df=0;
		which=0;
		csh();
		drawmap();
		for(int i=0;i<Y;i++){
			gotoxy(i,X*2+2);
			for(int j=0;j<X;j++)
				printf("%d",Map[i][j]);
			printf("\n");
		}
		while(true){
			while(true){
				df++;
				zy++;
				if(!candown())
					break;
				zy--;
				clsz();
				zy++;
				drawz();
				_cin();
				_cin();
				if(!candown())
					break;
				printdf();
				_sleep(WAIT_TIME);
			}
			change();
			if(gameover()){
				sw=0;
				sc=0;
				system("cls");
				system("color 1E");
				gotoxy(10,18);
				printf("游戏结束!\n");
				gotoxy(12,17);
				printf("最终得分:%d\n",df/10);
				while(true){
					gotoxy(8,0);
					if(sw==0)
						printf("  <  <  <  <  <  <  <  <  <  <  <  <  <  <  <");
					if(sw==1)
						printf(" <  <  <  <  <  <  <  <  <  <  <  <  <  <  < ");
					if(sw==2)
						printf("<  <  <  <  <  <  <  <  <  <  <  <  <  <  <  ");
					gotoxy(14,0);
					if(sw==0)
						printf(">  >  >  >  >  >  >  >  >  >  >  >  >  >  >  ");
					if(sw==1)
						printf(" >  >  >  >  >  >  >  >  >  >  >  >  >  >  > ");
					if(sw==2)
						printf("  >  >  >  >  >  >  >  >  >  >  >  >  >  >  >");
					if(kbhit()!=0){
						getch();
						sc++;
						if(sc==2)
							break;
					}
					sw=(sw+1)%3;
					_sleep(100);
				}
				break; 
			}
			which=rand()%6;
			csh();
			color(WHITE);
			for(int i=0;i<Y;i++){
				gotoxy(i,X*2+2);
				for(int j=0;j<X;j++)
					printf("%d",Map[i][j]);
				printf("\n");
			}
		}
	}
	return 0;
}
void color(int a){
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),a);
	return;
}
void gotoxy(int i,int j){
    COORD position={j,i};
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),position);
    return;
}
void csh(){
	bool _bool[6][4][4]={{{0,1,0,0},
						  {0,1,0,0},
						  {0,1,1,0},
						  {0,0,0,0}},
						  
						 {{0,0,1,0},
						  {0,0,1,0},
						  {0,1,1,0},
						  {0,0,0,0}},
						  
						 {{0,0,0,0},
						  {0,1,1,0},
						  {1,1,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},
						  {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,0,0,0}}};
	for(int sw=0;sw<6;sw++)
		_long[sw]=-1;
	for(int sw=0;sw<6;sw++)
		for(int y=0;y<4;y++)
			for(int x=0;x<4;x++)
				if(_bool[sw][y][x]){
					_long[sw]++;
					z[sw][_long[sw]][0]=y;
					z[sw][_long[sw]][1]=x;
				}
	zx=X/2-3;
	zy=-2;
	return;
}
void start(){
	system("color 1E");
	system("mode con cols=45 lines=25");
	system("title 俄罗斯方块");
	MessageBox(NULL,"按a键左移,按d键右移,w,s键旋转,p键暂停","游戏规则:",MB_OK);
	srand(time(NULL));
	CONSOLE_CURSOR_INFO cursor_info={1,0};
    SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE),&cursor_info);
	return;
}
void drawmap(){
	gotoxy(0,0);
	color(WHITE);
	for(int y=0;y<Y;y++){
		for(int x=0;x<X;x++){
			if(Map[y][x]>0){
				color(Map[y][x]);
				printf("■");
			}
			else	printf("  ");
		}
		printf("\n");
	}
	for(int x=1;x<X-1;x++)
		Map[0][x]=0;
	return;
}
bool candown(){
	for(int l=0;l<=_long[which];l++)
		if(Map[z[which][l][0]+zy+1][z[which][l][1]+zx+1]>0&&z[which][l][0]+zy>=0)
			return false;
	return true;
}
void drawz(){
	color(which+1);
	for(int l=0;l<=_long[which];l++){
		if(z[which][l][0]+zy>-1){
			gotoxy(z[which][l][0]+zy+1,(z[which][l][1]+zx+1)*2);
			printf("■");
		}
	}
	return;
}
void clsz(){
	for(int l=0;l<=_long[which];l++){
		if(z[which][l][0]+zy>-1){
			gotoxy(z[which][l][0]+zy+1,(z[which][l][1]+zx+1)*2);
			printf("  ");
		}
	}
	return;
}
void change(){
	for(int l=0;l<=_long[which];l++)
		if(z[which][l][0]+zy>-1)
			Map[z[which][l][0]+zy][z[which][l][1]+zx+1]=which+1;
	bool s;
	for(int y=1;y<Y-1;y++){
		s=true;
		for(int x=1;x<X-1;x++)
			s=(s&&(Map[y][x]>0));
		if(s==true){
			for(int i=y;i>0;i--)
				for(int x=1;x<X-1;x++)
					Map[i][x]=Map[i-1][x];
			for(int x=1;x<X-1;x++)
				Map[0][x]=7;
			df+=30;
			drawmap();
		}
	}
	return;
}
void turn(string s){
	if(s=="left"){
		for(int l=0;l<=_long[which];l++){
			int y=z[which][l][0],x=z[which][l][1];
			z[which][l][0]=3-x;z[which][l][1]=y;
		}
	}
	if(s=="right"){
		for(int l=0;l<=_long[which];l++){
			int y=z[which][l][0],x=z[which][l][1];
			z[which][l][0]=x;z[which][l][1]=3-y;
		}
	}
	return;
}
void _cin(){
	if(kbhit()!=0){
		while(kbhit()!=0)
			c=getch();
		switch(c){
			case 'a':case 'A':{
				zx--;
				if(candown()){
					zx++;
					clsz();
					zx--;
					drawz();
				}else
					zx++;
				break;
			}
			case 'd':case 'D':{
				zx++;
				if(candown()){
					zx--;
					clsz();
					zx++;
					drawz();
				}else
					zx--;
				break;
			}
			case 'w':case 'W':{
				turn("left");
				if(!candown())
					turn("right");
				else{
					turn("right");
					clsz();
					turn("left");
					drawz();
				}
				break;
			}
			case 's':case 'S':{
				turn("right");
				if(!candown())
					turn("left");
				else{
					turn("left");
					clsz();
					turn("right");
					drawz();
				}
				break;
			}
			case ' ':{
				clsz();
				int dl=0;
				while(candown()){
					zy++;
					dl++;
				}	
				zy--;
				dl--;
				df+=dl;
				drawz();
				break;
			}
			case 'p':case 'P':{
				getch();
				break;
			}
			default:break;
		}
	}
	return;
}
void printdf(){
	gotoxy(Y,0);
	color(WHITE);
	printf("得分:%d",df/10);
	return;
}
bool gameover(){
	for(int x=1;x<X-1;x++)
		if(Map[0][x]>0)
			return true;
	return false;
}

2.代码解析

2-1:头文件;

#include<bits/stdc++.h>
#include<windows.h>
#include<conio.h>
using namespace std;

 三个头文件,包括了kbhit函数,getch函数,移动光标函数,设置颜色函数,各类常量,变量等

2-2:常量的定义与声明;

#define Y 22
#define X 14
#define WHITE 7
#define WAIT_TIME 100

四个常量分别为地图的长和宽,颜色——白色,和等待时间

2-3:变量的定义与声明;

int Map[Y][X];
int z[6][4][2],which,_long[6],zx,zy,sw,sc;
char c;
int df;

这几个变量分别记录地图信息,下落方块信息,输入字符与得分

2-4:各类函数的声明;

void color(int a);//设置颜色
void gotoxy(int i,int j);//移动光标
void csh();//初始化
void start();//游戏开始设置
void drawmap();//画地图
bool candown();//判断方块是否可以落下
void drawz();//画方块
void clsz();//清除方块
void change();//改变地图
void turn(string s);//旋转方块
void _cin();//输入
void printdf();//输出得分
bool gameover();//判断游戏结束

(自己看看吧)

2-5:程序主干-主函数;

int main(){
	start();
	while(true){//循环游戏
		system("cls");
		for(int y=0;y<Y;y++)
			for(int x=0;x<X;x++)
				Map[y][x]=0;
		for(int y=0;y<Y;y++)
			Map[y][0]=Map[y][X-1]=7;
		for(int x=0;x<X;x++)
			Map[0][x]=Map[Y-1][x]=7;
		df=0;
		which=0;
		csh();
		drawmap();
		for(int i=0;i<Y;i++){
			gotoxy(i,X*2+2);
			for(int j=0;j<X;j++)
				printf("%d",Map[i][j]);
			printf("\n");
		}
		while(true){
			while(true){
				df++;//增加得分
				zy++;//下移方块
				if(!candown())
					break;
				zy--;
				clsz();
				zy++;
				drawz();
				_cin();
				_cin();
				if(!candown())
					break;
				printdf();
				_sleep(WAIT_TIME);
			}
			change();
			if(gameover()){//游戏结束设置
				sw=0;
				sc=0;
				system("cls");
				system("color 1E");
				gotoxy(10,18);
				printf("游戏结束!\n");
				gotoxy(12,17);
				printf("最终得分:%d\n",df/10);
				while(true){
					gotoxy(8,0);
					if(sw==0)
						printf("  <  <  <  <  <  <  <  <  <  <  <  <  <  <  <");
					if(sw==1)
						printf(" <  <  <  <  <  <  <  <  <  <  <  <  <  <  < ");
					if(sw==2)
						printf("<  <  <  <  <  <  <  <  <  <  <  <  <  <  <  ");
					gotoxy(14,0);
					if(sw==0)
						printf(">  >  >  >  >  >  >  >  >  >  >  >  >  >  >  ");
					if(sw==1)
						printf(" >  >  >  >  >  >  >  >  >  >  >  >  >  >  > ");
					if(sw==2)
						printf("  >  >  >  >  >  >  >  >  >  >  >  >  >  >  >");
					if(kbhit()!=0){
						getch();
						sc++;
						if(sc==2)
							break;
					}
					sw=(sw+1)%3;
					_sleep(100);
				}
				break; 
			}
			which=rand()%6;
			csh();
			color(WHITE);
			for(int i=0;i<Y;i++){
				gotoxy(i,X*2+2);
				for(int j=0;j<X;j++)
					printf("%d",Map[i][j]);
				printf("\n");
			}
		}
	}
	return 0;
}

可以将每次下落过程看作一次循环,如果方块下落到底部,则退出循环,每次循环结束,观察方块是否达到地图顶部,如果是,则游戏结束

2-6:移动光标函数;

void gotoxy(int i,int j){
    COORD position={j,i};
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),position);
    return;
}

可以将光标移到指定位置的函数

2-7:设置颜色函数;

void color(int a){
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),a);
	return;
}

 设置输出字符的颜色

2-8:初始化函数;

void csh(){
	bool _bool[6][4][4]={{{0,1,0,0},    //下落方块的形状
						  {0,1,0,0},
						  {0,1,1,0},
						  {0,0,0,0}},
						  
						 {{0,0,1,0},
						  {0,0,1,0},
						  {0,1,1,0},
						  {0,0,0,0}},
						  
						 {{0,0,0,0},
						  {0,1,1,0},
						  {1,1,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},
						  {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,0,0,0}}};
	for(int sw=0;sw<6;sw++)
		_long[sw]=-1;
	for(int sw=0;sw<6;sw++)
		for(int y=0;y<4;y++)
			for(int x=0;x<4;x++)
				if(_bool[sw][y][x]){
					_long[sw]++;
					z[sw][_long[sw]][0]=y;
					z[sw][_long[sw]][1]=x;
				}
	zx=X/2-3;
	zy=-2;
	return;
}

2-9:游戏开始设置;

void start(){
	system("color 1E");//设置颜色
	system("mode con cols=45 lines=25");//设置屏幕长宽
	system("title 俄罗斯方块");//设置标题
	MessageBox(NULL,"按a键左移,按d键右移,w,s键旋转,p键暂停","游戏规则:",MB_OK);//弹窗
	srand(time(NULL));
	CONSOLE_CURSOR_INFO cursor_info={1,0};
    SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE),&cursor_info);//清除光标
	return;
}

2-10:画地图函数;

void drawmap(){
	gotoxy(0,0);
	color(WHITE);
	for(int y=0;y<Y;y++){
		for(int x=0;x<X;x++){
			if(Map[y][x]>0){
				color(Map[y][x]);
				printf("■");
			}
			else	printf("  ");
		}
		printf("\n");
	}
	for(int x=1;x<X-1;x++)
		Map[0][x]=0;
	return;
}

2-11:判断方块是否可以下落的函数;

bool candown(){
	for(int l=0;l<=_long[which];l++)
		if(Map[z[which][l][0]+zy+1][z[which][l][1]+zx+1]>0&&z[which][l][0]+zy>=0)
			return false;
	return true;
}

2-12:打印方块函数;

void drawz(){
	color(which+1);
	for(int l=0;l<=_long[which];l++){
		if(z[which][l][0]+zy>-1){
			gotoxy(z[which][l][0]+zy+1,(z[which][l][1]+zx+1)*2);
			printf("■");
		}
	}
	return;
}

2-13:清除方块函数;

void clsz(){
	for(int l=0;l<=_long[which];l++){
		if(z[which][l][0]+zy>-1){
			gotoxy(z[which][l][0]+zy+1,(z[which][l][1]+zx+1)*2);
			printf("  ");
		}
	}
	return;
}

2-14:修改地图函数;

void change(){
	for(int l=0;l<=_long[which];l++)
		if(z[which][l][0]+zy>-1)
			Map[z[which][l][0]+zy][z[which][l][1]+zx+1]=which+1;
	bool s;
	for(int y=1;y<Y-1;y++){
		s=true;
		for(int x=1;x<X-1;x++)
			s=(s&&(Map[y][x]>0));
		if(s==true){
			for(int i=y;i>0;i--)
				for(int x=1;x<X-1;x++)
					Map[i][x]=Map[i-1][x];
			for(int x=1;x<X-1;x++)
				Map[0][x]=7;
			df+=30;
			drawmap();
		}
	}
	return;
}

2-15:旋转方块函数;

void turn(string s){
	if(s=="left"){
		for(int l=0;l<=_long[which];l++){
			int y=z[which][l][0],x=z[which][l][1];
			z[which][l][0]=3-x;z[which][l][1]=y;
		}
	}
	if(s=="right"){
		for(int l=0;l<=_long[which];l++){
			int y=z[which][l][0],x=z[which][l][1];
			z[which][l][0]=x;z[which][l][1]=3-y;
		}
	}
	return;
}

2-16:输入函数;

void _cin(){
	if(kbhit()!=0){
		while(kbhit()!=0)
			c=getch();
		switch(c){
			case 'a':case 'A':{//向左移
				zx--;
				if(candown()){
					zx++;
					clsz();
					zx--;
					drawz();
				}else
					zx++;
				break;
			}
			case 'd':case 'D':{//向右移
				zx++;
				if(candown()){
					zx--;
					clsz();
					zx++;
					drawz();
				}else
					zx--;
				break;
			}
			case 'w':case 'W':{
				turn("left");
				if(!candown())
					turn("right");
				else{
					turn("right");
					clsz();
					turn("left");
					drawz();
				}
				break;
			}
			case 's':case 'S':{
				turn("right");
				if(!candown())
					turn("left");
				else{
					turn("left");
					clsz();
					turn("right");
					drawz();
				}
				break;
			}
			case ' ':{
				clsz();
				int dl=0;
				while(candown()){
					zy++;
					dl++;
				}	
				zy--;
				dl--;
				df+=dl;
				drawz();
				break;
			}
			case 'p':case 'P':{
				getch();
				break;
			}
			default:break;
		}
	}
	return;
}

2-17:打印得分函数;

void printdf(){
	gotoxy(Y,0);
	color(WHITE);
	printf("得分:%d",df/10);
	return;
}

2-18:判断游戏结束函数;

bool gameover(){
	for(int x=1;x<X-1;x++)
		if(Map[0][x]>0)
			return true;
	return false;
}

 至此,文章结束,希望大佬们多多支持

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值