C/C++——控制台俄罗斯方块的实现以及自动操作

阅读: 评论:0

C/C++——控制台俄罗斯方块的实现以及自动操作

C/C++——控制台俄罗斯方块的实现以及自动操作

游戏附件

链接:
提取码: d9tb

游戏画面

手动操作展示
自动操作展示

头文件、全局变量以及函数声明

#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include <time.h>
#include <process.h>
#include <math.h>
// 七种方块类型IJLOSTZ
#define I 0
#define J 1
#define L 2
#define O 3
#define S 4
#define T 5
#define Z 6
COORD block[4],nblock[4],blockchange[4];
int tank[12][24]={0};
int type,ntype,typechange,speed;
int cheatopen=0,score,over=0,best=0;
int blockcolor[7]={11,9,5,14,10,13,12};
int blocktypenum[7]={2,4,4,1,2,4,2};
COORD blocktype[7][4];
COORD changeI[2][4],changeJ[4][4],changeL[4][4],changeS[2][4],changeT[4][4],changeZ[2][4];
HANDLE handle,mutex;
void gotoxy(int x, int y);	//移动光标
void color(int b);			//设置颜色
void initialize();			//初始化各方块的形状和旋转样式
void drawboard();			//绘制界面
void newblock();			//创建新方块
void blocktwist();			//方块旋转
void cheat();				//方块收缩
bool checkbottom();			//检查是否触底
bool checkright();			//检查是否可右移
bool checkleft();			//检查是否可左移
bool checktwist();			//检查是否可旋转
bool checkdie();			//检查是否游戏结束
void checkclear();			//检查是否有可清楚行
void autoplay();			//单步自动操作
void Sautoplay();			//全自动操作
int checkbest(int x,int typechange);	//计算最好的方块位置
void blockmove(int dir);				//方块移动
unsigned int __stdcall Fun(void *pPM);	//子线程控制方块自动下落
void start();							//游戏流程控制和交互

主要函数:

void start()
{for(int i=0;i<11;i++)for(int j=0;j<24;j++)tank[i][j]=0;for(int j=0;j<24;j++)tank[0][j]=1,tank[11][j]=1;//drawboard();newblock();char ch;score=0;over=0;speed=(int)(1000/log((double)score+7.38));color(15);gotoxy(13,8);printf("SCORE:%d",score);gotoxy(13,9);printf("INTERVAL:%dms",speed);mutex=CreateMutex(NULL,FALSE,NULL);handle=(HANDLE)_beginthreadex(NULL,0,Fun,NULL,0,NULL);   while(1){if (kbhit()){	ch=getch();WaitForSingleObject(mutex,INFINITE);switch(ch){case 'R':if(cheatopen)cheat();break;case 'E':if(cheatopen)autoplay();break;case 'a':case 'A':if(checkleft())blockmove(2);break;case 'w':case 'W':if(checktwist())blocktwist();break;case 'd':case 'D':if(checkright())blockmove(1);break;case 's':case 'S':while(!checkbottom()){Sleep(25);blockmove(0);}break;case 0x1B:over=1;}ReleaseMutex(mutex);if(cheatopen&&ch=='O')Sautoplay();}if(over)break;}WaitForSingleObject(handle,INFINITE);CloseHandle(handle);CloseHandle(mutex);color(15);gotoxy(0,22);printf("GAME OVER!");if(score>best)best=score,printf("NEW RECORD!");system("pause");
}
void blockmove(int d)
{for(int i=0;i<4;i++){gotoxy(block[i].X,block[i].Y);if(block[i].X>0&&block[i].Y>0)printf("  ");}switch(d){case 0:for(int i=0;i<4;i++)block[i].Y++;break;case 1:for(int i=0;i<4;i++)block[i].X++;break;case 2:for(int i=0;i<4;i++)block[i].X--;break;}color(blockcolor[type]);for(int i=0;i<4;i++){gotoxy(block[i].X,block[i].Y);if(block[i].Y>0)printf("■");}
}
void checkclear()
{int i,j,k,num=0,times=0;for(i=0;i<=20;i++){num=0;for(j=1;j<=10;j++)if(tank[j][i+3])num++;if(num==10){times+=1;Sleep(100);for(k=i;k>0;k--){gotoxy(1,k);for(j=1;j<=10;j++){tank[j][k+3]=tank[j][k+2];if(tank[j][k+3]){color(tank[j][k+3]);printf("■");}else printf("  ");}}printf("a");}}score+=(times*times);speed=(int)(1000/log((double)score+7.38));color(15);gotoxy(13,8);printf("SCORE:%d",score);gotoxy(13,9);printf("INTERVAL:%dms",speed);
}

有关自动操作:

思路,遍历当前下落方块的所有位置,所有旋转方向下落后的位置并用checkbest函数对该位置打分,选择打分最高的位置和旋转方向操作。

void autoplay()
{int k,x,bestnum=0,bestx=5,besttype=0,num=0;for(k=0;k<blocktypenum[type];k++){for(x=1;x<=10;x++){num=checkbest((x+3)%10+1,k);if(bestnum<num){bestnum=num;bestx=(x+3)%10+1;besttype=k;}}}//for(int i=0;i<4;i++)if(block[i].Y>0){gotoxy(block[i].X,block[i].Y);printf("  ");}//block[0].X=bestx;block[0].Y=block[0].Y;switch(type){case I: for(int i=1;i<4;i++){block[i].X=block[0].X+changeI[besttype][i].X;block[i].Y=block[0].Y+changeI[besttype][i].Y;}break;case J: for(int i=1;i<4;i++){block[i].X=block[0].X+changeJ[besttype][i].X;block[i].Y=block[0].Y+changeJ[besttype][i].Y;}break;case L: for(int i=1;i<4;i++){block[i].X=block[0].X+changeL[besttype][i].X;block[i].Y=block[0].Y+changeL[besttype][i].Y;}break;case S: for(int i=1;i<4;i++){block[i].X=block[0].X+changeS[besttype][i].X;block[i].Y=block[0].Y+changeS[besttype][i].Y;}break;case T: for(int i=1;i<4;i++){block[i].X=block[0].X+changeT[besttype][i].X;block[i].Y=block[0].Y+changeT[besttype][i].Y;}break;case Z: for(int i=1;i<4;i++){block[i].X=block[0].X+changeZ[besttype][i].X;block[i].Y=block[0].Y+changeZ[besttype][i].Y;}break;case O: block[1].X=block[0].X+1;block[1].Y=block[0].Y;block[2].X=block[0].X;block[2].Y=block[0].Y-1;block[3].X=block[0].X+1;block[3].Y=block[0].Y-1;break;}//color(blockcolor[type]);for(int i=0;i<4;i++){gotoxy(block[i].X,block[i].Y);if(block[i].Y>0)printf("■");}while(!checkbottom()){Sleep(25);blockmove(0);}
}
int checkbest(int x,int tpc)
{COORD temp[4];temp[0].X=x;temp[0].Y=block[0].Y;switch(type){case I: for(int i=1;i<4;i++){temp[i].X=temp[0].X+changeI[tpc][i].X;temp[i].Y=temp[0].Y+changeI[tpc][i].Y;}break;case J: for(int i=1;i<4;i++){temp[i].X=temp[0].X+changeJ[tpc][i].X;temp[i].Y=temp[0].Y+changeJ[tpc][i].Y;}break;case L: for(int i=1;i<4;i++){temp[i].X=temp[0].X+changeL[tpc][i].X;temp[i].Y=temp[0].Y+changeL[tpc][i].Y;}break;case S: for(int i=1;i<4;i++){temp[i].X=temp[0].X+changeS[tpc][i].X;temp[i].Y=temp[0].Y+changeS[tpc][i].Y;}break;case T: for(int i=1;i<4;i++){temp[i].X=temp[0].X+changeT[tpc][i].X;temp[i].Y=temp[0].Y+changeT[tpc][i].Y;}break;case Z: for(int i=1;i<4;i++){temp[i].X=temp[0].X+changeZ[tpc][i].X;temp[i].Y=temp[0].Y+changeZ[tpc][i].Y;}break;case O: temp[1].X=temp[0].X+1;temp[1].Y=temp[0].Y;temp[2].X=temp[0].X;temp[2].Y=temp[0].Y-1;temp[3].X=temp[0].X+1;temp[3].Y=temp[0].Y-1;break;}for(int i=0;i<4;i++){if(tank[temp[i].X][temp[i].Y+3])return -1;if(temp[i].X<1||temp[i].X>10||temp[i].Y>20)return -1;}int z=0;while(1){for(int i=0;i<4;i++)if(temp[i].Y>=20||tank[temp[i].X][temp[i].Y+4])z=1;if(z)break;for(int k=0;k<4;k++)temp[k].Y++;}int num=0;for(int i=0;i<4;i++){tank[temp[i].X][temp[i].Y+3]=1;}for(int i=0;i<4;i++){//打分区域开始if(tank[temp[i].X][temp[i].Y+4])num+=4;if((!tank[temp[i].X][temp[i].Y+4])&&(temp[i].Y!=20))num-=16;if((!tank[temp[i].X][temp[i].Y+4])&&(!tank[temp[i].X][temp[i].Y+5])&&(temp[i].Y!=20)&&(temp[i].Y!=19))num-=32;if(tank[temp[i].X+1][temp[i].Y+3])num+=4;if(tank[temp[i].X-1][temp[i].Y+3])num+=4;if(tank[temp[i].X+1][temp[i].Y+3]&&tank[temp[i].X-1][temp[i].Y+3])num+=4;if(temp[i].Y>=20)num+=6;if(temp[i].Y<=0)num-=1000;num+=temp[i].Y;//打分区域结束}int bnum;for(int k=0;k<=20;k++){bnum=0;for(int j=1;j<=10;j++)if(tank[j][k+3])bnum++;if(bnum==10)num+=60;}for(int i=0;i<4;i++){tank[temp[i].X][temp[i].Y+3]=0;}return num;
}

注:checkbest打分标准直接决定了自动操作的技术!!!

本文发布于:2024-02-02 11:53:04,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170684598343619.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23