【小游戏】俄罗斯方块(C++版)

来源:互联网 发布:java b2b2c 开源下载 编辑:程序博客网 时间:2024/05/18 00:21
大一作品,留念
#include<stdio.h>#include<time.h>#include<conio.h>//kbhit#include<stdlib.h>//rand,srand#include<windows.h>#define wide 15#define hight 18#define period 500typedef struct point{int h;int w;}point;/*1 ■■■■                 1*4 -> 4*1  ■             ■  2■■■   3 ■■■         2*3 -> 3*2  ■■          ■■       2*3 -> 3*2  4 ■■         5     ■■  ■■             ■  6 ■■   2*2  7  ■■■      2*3->3*2最大面积为4*41234■■■■1234■■■■1234■■■■1234■■■■按W键旋转九十度*/char map[hight][wide]={0};//1:□ 2:■  其余的都是空格 char类型节约空间char stay[hight][wide]={0};//残留方块struct point size;//活动方块的大小 前一个代表 高度 后一个代表 宽度 ,主要用于触碰处理char sqr[4][4];//活动方块数组struct point posi={1,wide/2-2};//方块顶点坐标char situ=0;//旋转状况0 正常 1 顺时针90度 2:180 3:270int grade=0,line=0;//char sqr[4][4];//point newspr={1,wide/2};//------------函数声明void showmap();void setmap();    int keypre(char k);//按下某键int getrand(int,int);//取一个范围内的随机数int setini(int type);//初始化方块,类型,看表吧void turn90();int isagain();//判断活动区是否与stay区重复int exsqr(char row);//判断stay区某一行是否存在方块,存在返回1,不存在返回0void judge();//层满处理int main(){int last=0,t;    int i;srand(time(NULL));//随机图形setini(getrand(1,7));//屏幕渲染do{t=clock();if(t-last>=period){//周期性刷新last=t;system("cls");if(keypre('s')==0)break;setmap();printf("-----------当前分数:%d,已消除行:%d-----------\n",grade,line);showmap();}if(kbhit()==1){system("cls");if(keypre(getch())==0)break;setmap();printf("-----------当前分数:%d,已消除行:%d-----------\n",grade,line);showmap();}}while(1);system("cls");printf("----------------得分:%d   消除:%d-------------------\n",grade,line);setmap();showmap();printf("----------------游戏结束!谢谢玩耍!----------------\n");printf("按回车键退出!\n");while(getchar()!='\n');return 0;}int keypre(char k)//按下某键{int i,j,real=0;char top[wide];if(k=='s'){posi.h++;if(isagain())//下一步是否会重合real=1;//那么下一步不能走了//留在当前位置if(real){grade+=18;//留步加分posi.h--;//留在上一步for(i=0;i<size.h ;i++)//就留下来了{for(j=0;j<size.w;j++){if(sqr[i][j]==2)//只记录实体stay[i+posi.h][j+posi.w ]=2;}}//出新的judge();//层满判断return (setini(getrand(1,7)));}}else if(k=='a'||k=='A'){posi.w --;if(isagain())posi.w ++;//移动取消}else if(k=='d'||k=='D'){posi.w ++;if(isagain())posi.w --;//移动取消}else if(k=='w'||k=='W')turn90();else if(k=='s'||k=='S'){posi.h++;if(isagain())posi.h --;//移动取消}//左右分界判断if(posi.w+size.w>wide-1)posi.w=wide-1-size.w;if(posi.w <1)posi.w=1;return 1;}void setmap()//初始化地图,并置{int i,j;//画地图区域for(i=0;i<hight;i++){for(j=0;j<wide;j++){if(i==0||i==hight-1||j==0||j==wide-1)map[i][j]=1;//边界elsemap[i][j]=0;//空白}}//画活动方块for(i=0;i<size.h ;i++){for(j=0;j<size.w ;j++){map[posi.h+i][posi.w+j]=sqr[i][j];}}//画残留for(i=0;i<hight;i++){for(j=0;j<wide;j++){if(stay[i][j]==2)map[i][j]=2;}}}//将数组转换为图形void showmap(){int i,j;for(i=0;i<hight;i++){for(j=0;j<wide;j++){if(map[i][j]==1)printf("□");else if(map[i][j]==2)printf("■");elseprintf("  ");}printf("\n");}}int getrand(int min,int max)//取一个范围内的随机数{return (min+rand()%(max-min+1));}void turn90()//活动方块顺时针旋转九十度{int i,j;char a[4][4];//临时变量    char temp[4][4];    //方块备份    for(i=0;i<4;i++)for(j=0;j<4;j++)temp[i][j]=sqr[i][j];for(i=0;i<4;i++)for(j=0;j<4;j++)a[j][i]=sqr[i][j];//斜线对称//左右对称,即是转动九十度i=size.h ;size.h =size.w;size.w =i;for(i=0;i<size.h ;i++)for(j=0;j<size.w ;j++)sqr[i][size.w-1-j]=a[i][j];    if(isagain())        for(i=0;i<4;i++)            for(j=0;j<4;j++)                sqr[i][j]=temp[i][j];}int setini(int type)//初始化方块,类型,看表吧{int i,j;for(i=0;i<4;i++)for(j=0;j<4;j++)sqr[i][j]=0;//归零switch(type){case 1:size.h =1;size.w =4;sqr[0][0]=2;sqr[0][1]=2;sqr[0][2]=2;sqr[0][3]=2;break;case 2:size.h =2;size.w =3;sqr[0][0]=2;sqr[1][0]=2;sqr[1][1]=2;sqr[1][2]=2;break;case 3:size.h =2;size.w =3;sqr[0][2]=2;sqr[1][0]=2;sqr[1][1]=2;sqr[1][2]=2;break;case 4:size.h =2;size.w =3;sqr[0][1]=2;sqr[0][2]=2;sqr[1][0]=2;sqr[1][1]=2;break;case 5:size.h =2;size.w =3;sqr[0][0]=2;sqr[0][1]=2;sqr[1][1]=2;sqr[1][2]=2;break;case 6:size.h =2;size.w =2;sqr[0][0]=2;sqr[0][1]=2;sqr[1][0]=2;sqr[1][1]=2;break;case 7:size.h =2;size.w =3;sqr[0][1]=2;sqr[1][0]=2;sqr[1][1]=2;sqr[1][2]=2;break;}posi.h =1;posi.w =(wide-size.w )/2;if(isagain())//刚刚初始化你就重合了,你说你是不是挂了?return 0;return 1;/*1 ■■■■                 1*4 -> 4*1   ■             ■  2■■■   3 ■■■         2*3 -> 3*2  ■■          ■■       2*3 -> 3*2  4 ■■     5    ■■    ■■             ■  6 ■■   2*2  7  ■■■      2*3->3*2*/}void judge()//层满处理{int i,j,full,k,esqr;for(i=1;i<hight-1;i++)//除掉边界{full=1;for(j=1;j<wide-1;j++)//除掉边界{if(stay[i][j]!=2)//存在不为方块的full=0;//假空}if(full)//真空{line++;//已消除grade+=90;//消除加五倍分数for(j=1;j<wide-1;j++)//除掉边界stay[i][j]=0;//置零}}//全部除完之后for(i=hight-2;i>=2;i--){    int s=i;if(exsqr(i)==0)//本层为空{    //上层下移while(s>=1 && exsqr(--s)==0)                //该层不存在方块                //继续向上寻找                ;for(j=1;j<wide-1;j++){stay[i][j]=stay[s][j];//上层下移stay[s][j]=0;//上层清空}}}}int isagain()//判断活动区是否与stay区重复{int i,j;for(i=0;i<size.h ;i++){for(j=0;j<size.w ;j++){if(sqr[i][j]==2)//是实体,i,j是框内代号{    if(posi.h +i >hight-2)                    return 1;    else if(stay[posi.h +i][posi.w +j]==2)//框内位置转换为map位置return 1;}}}return 0;//未重复}int exsqr(char row)//判断stay区某一行是否存在方块,存在返回1,不存在返回0{int j;for(j=1;j<wide-1;j++)//出掉边界if(stay[row][j]==2)return 1;return 0;}

0 0