用C++寫的推箱子小遊戲2.2(支持步數顯示,回撤,穿牆,闖關,輸入等功能)

歡迎來到jiedai的推箱子。

jiedai用C++寫的推箱子游戲支持步數顯示,回撤,穿牆,闖關,輸入等操作。

1.1的更新增加了步數的輸出,對玩家移動的箭頭進行了改進。

1.2的更新推出了小編提供的地圖,希望大家遊戲愉快。

1.3的更新修正了調試過程中的bug。

經過玩家的強烈要求,小編在1.3的基礎上更新了2.0,創新推出了推箱子穿牆技能,開啓了闖關模式。

2.1的更新,新增了步數查詢功能,以及遊戲返回和退出鍵。

2.2的更新縮短了代碼長度,改進了闖關模式繁瑣的地圖操作。

下面是在控制檯上運行的代碼:

#include<bits/stdc++.h>
#include<windows.h>
#include<conio.h>
using namespace std;
#define VERSION "2.2"
#define M 55
int n,m,wall[M][M],hole[M][M],box[M][M];
int step,dct,query,cross,rx[233],ry[233];
char str[M][M],title[M],o;
char atlas[M][M][M]={
	{"...#@.","@..*..","#*##..","..##*#","..X.&.",".@#..."},
	{"########...####","########..*####","########*....##","######.*..*..##"
	,"@@..##.###.#...","@@.X......*..*.","@@..#.####.####","#####......####"},
	{"####..#...##","##.*..*.#.##","...#.**#....","X*.....#*##.","#.*###**....","##..##.#*..."
	,"###@@@.#.*#.","###@@@@@#.*.","####@@@@@...","#######.#*.#","#######....#","#######...##"},
	{"..@*.##",".@*@*..","&*@*@X.",".@*@*.#","..@*..#"}
};int A[M]={6,8,12,5},B[M]={6,15,12,7};
struct pos{int x,y;}player;
struct node{
    pos man;int dct;
    vector<pos>box;
    node(){box.clear();}
}rec[M*M*M];
void color(int x){SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),x);}
void clean(){system("cls");color(154);printf("歡迎來到jiedai的推箱子%s\n\n",VERSION);color(7);}
bool check(int x,int y,int cross){
    if(!cross)return x<1||x>n||y<1||y>m||wall[x][y];
    return x<0||x>n+1||y<0||y>m+1;
}
bool forward(int rx,int ry){
	int x=player.x+rx,y=player.y+ry,X=x+rx,Y=y+ry;
	if(check(x,y,cross))return 0;
	if(box[x][y])if(check(X,Y,0)||box[X][Y])return 0;
	return 1;
}
bool win(){
	for(int i=0;i<rec[step].box.size();i++)
		if(!hole[rec[step].box[i].x][rec[step].box[i].y])return 0;
	return 1;
}
void pt(){
    memset(box,0,sizeof(box));
    for(int i=0;i<rec[step].box.size();i++)box[rec[step].box[i].x][rec[step].box[i].y]=1;
    player.x=rec[step].man.x;player.y=rec[step].man.y;
    dct=rec[step].dct;
    clean();color(154);
    puts("按方向鍵進行移動,按刪除鍵進行撤銷");
    puts("按空格鍵查詢步數,按#鍵將有神奇的事情發生...");
    puts("按0返回,按Esc鍵退出遊戲");color(7);
    for(int i=0;i<=n+1;i++){
		printf("  ");
        for(int j=0;j<=m+1;j++){
			if(i==player.x&&j==player.y){
                color(15);if(check(i,j,0))color(63);
                if(dct==72)printf("↑");
                else if(dct==77)printf("→");
                else if(dct==80)printf("↓");
                else if(dct==75)printf("←");color(7);
            }else if(i==0||i==n+1||j==0||j==m+1||wall[i][j]){color(3);printf("■");}
			else if(box[i][j]){
				color(14);
                if(hole[i][j])color(12);
                printf("▓");
            }else if(hole[i][j]){color(3);printf("※");}
			else printf("  ");
        }puts("");
    }color(7);
}
void update(){
	node tmp;int i,j;
	for(i=1;i<=n;i++)for(j=1;j<=m;j++)if(box[i][j]){
		pos po;po.x=i,po.y=j;
		tmp.box.push_back(po);
	}tmp.man.x=player.x;tmp.man.y=player.y;
	tmp.dct=dct;rec[step]=tmp;
}
void playing(){
	dct=72;step=0;
	update();pt();
	int winstep=-1;
	while(o=getch()){
		int tp=0;
		if(o==72||o==77||o==80||o==75){
			if(forward(rx[o],ry[o])){
				int x=player.x+rx[o],y=player.y+ry[o];
				if(box[x][y]){box[x][y]=0;box[x+rx[o]][y+ry[o]]=1;}
				player.x=x;player.y=y;step++;
			}else tp=1;
			dct=o;update();
		}else if(o==8){tp=3,step=max(0,step-1);if(step<=winstep)winstep=-1;}
		else if(o==35)cross^=1;
		else if(o==48)break;
		else if(o==27)exit(0);
		else if(o==32)query^=1;
		else if(o!=-32)tp=2;
		pt();color(154);
		if(query)printf("當前步數爲%d\n",step);
		if(win()||winstep!=-1){
			if(winstep==-1)winstep=step;
			printf("恭喜你,你贏了!您用了%d步。\n",winstep);
		}else if(tp==1){color(207);puts("對不起,你無法推動這個方塊!");}
		else if(tp==2){color(207);puts("請使用↑↓←→來移動!");}
		else if(tp==3)puts("回滾成功");
		color(7);
	}
}
void in(){
	memset(wall,0,sizeof(wall));memset(hole,0,sizeof(hole));memset(box,0,sizeof(box));clean();
	puts("第一行輸入兩個整數n和m,表示地圖的大小");puts("接下來n行,每行m個元素。");
	puts("'.'表示空地");puts("'#'表示牆");puts("'*'表示箱子");
	puts("'@'表示洞");puts("'X'表示人" );puts("'&'表示箱子已在洞上");
	scanf("%d%d",&n,&m);int i,j;
	for(i=1;i<=n;i++)scanf("%s",str[i]+1);
	for(i=1;i<=n;i++)for(j=1;j<=m;j++){
		o=str[i][j];
		if(o=='X')player.x=i,player.y=j;
		if(o=='#')wall[i][j]=1;
		if(o=='@'||o=='&')hole[i][j]=1;
		if(o=='*'||o=='&')box[i][j]=1;
	}playing();
}
void pass(){
	memset(wall,0,sizeof(wall));memset(hole,0,sizeof(hole));memset(box,0,sizeof(box));
	clean();puts("1.第一關");puts("2.第二關");puts("3.第三關");puts("4.第四關");
	puts("\n0.返回");puts("Esc.退出遊戲");
	while(o=getch()){
		if(o>='1'&&o<='4'){
			int id=o-48-1;n=A[id];m=B[id];
			for(int i=1;i<=n;i++)for(int j=1;j<=m;j++){
				char o=atlas[id][i-1][j-1];
		    	if(o=='X')player.x=i,player.y=j;
		    	if(o=='#')wall[i][j]=1;
				if(o=='@'||o=='&')hole[i][j]=1;
				if(o=='*'||o=='&')box[i][j]=1;
	   		}playing();break;
		}else if(o==48)break;
	}
}
void Init(){
	sprintf(title,"推箱子%s by jiedai",VERSION);SetConsoleTitle(title);
	rx[72]=-1;rx[80]=1;ry[77]=1;ry[75]=-1;
}
void remain(){
	clean();puts("1.闖關模式");puts("2.輸入模式");puts("Esc.退出遊戲");
	while(o=getch()){
		if(o=='1'){pass();break;}
		else if(o=='2'){in();break;}
		else if(o==27)exit(0);
	}
}
int main(){Init();while(1)remain();}

大家遊戲愉快!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章