// 编译器版本 g++8.1.0
// 编译参数 -Weffc++ -Wextra -Wall -std=c++11
#include <cstdio>
#include <cstdlib>
#include <>
/**
* 常量的定义
**/
// 关卡最大高度和宽度
const int MAXHEIGHT = 20;
const int MAXWIDTH = 20;
// 代表位移的四个常量(对应上下左右)
const int DX[4]= {-1,1,0,0};
const int DY[4]= {0,0,-1,1};
/**
* 数据类型定义
**/
// 坐标数据类型
struct PointType
{
int x;
int y;
bool operator==(const PointType& p)
{
if(==this->x&&==this->y)
return true;
return false;
}
bool operator!=(const PointType& p)
{
return !(*this==p);
}
};
// 关卡数据类型
struct LevelType
{
int height; // 关卡的高度,应当小于MAXHEIGHT
int width; // 关卡的宽度,应当小于MAXWIDTH
char levelMap[MAXHEIGHT][MAXWIDTH];
// 关卡每格数据,'P'代表玩家、'B'代表箱子,'G'代表目标点,'#'代表墙,'.'代表空地
};
/**
* 全局变量定义
**/
LevelType Glevel[2]={
{5,5,{
"#####",
"#P#.#",
"#...#",
"#.BG#",
"#####"}},
{6,9,{
"..####...",
"###..####",
"#.....B.#",
"#.#..#B.#",
"#.#P.#",
"#########"}},
}; // 关卡的定义
int GlevelSelect; // 当前正在游玩的关卡
LevelType GnowLevel; // 游戏正在运行中的关卡状态
PointType Gplayer; // 玩家的位置信息
/**
* 载入关卡数据至游戏中并初始化玩家位置
**/
void LoadLevelToGame(LevelType & level)
{
GnowLevel = level;
for(int i=0; i<; i++)
for(int j=0; j<; j++)
if([i][j]=='P')
Gplayer= {i,j};
return;
}
/**
* 更新游戏画面
**/
void Update()
{
// 清空显示画面
system("cls");
// 绘制提示信息
printf("w:Up s:Down a:Left d:Right\n");
printf("r:Restart q:Quit\n\n");
// 绘制关卡信息
for(int i=0; i<; i++)
printf("%s\n",[i]);
return;
}
/**
* 选择关卡
**/
void LevelSelect()
{
// 绘制提示信息
system("cls");
printf("Please choose level.\n");
printf("0=Easy 1=Hard\n\n");
printf("Level:");
scanf("%d",&GlevelSelect);
// 载入关卡数据
LoadLevelToGame(Glevel[GlevelSelect]);
// 更新画面
Update();
return;
}
/**
* 更新游戏胜利画面
**/
void UpdateWin()
{
// 清空显示画面
system("cls");
// 绘制提示信息
printf("YOU WIN!!!\n");
// 等待玩家确认
system("pause");
return;
}
/**
* 游戏初始化
**/
void InitGame()
{
// 初始化显示画面高度和宽度
system("mode con cols=50 lines=20");
return;
}
/**
* 玩家移动函数
* type:移动类型,与上文位移常量对应,0=上,1=下,2=左,3=右
**/
void PlayerMove(int type)
{
// 玩家下一格的前进方向
PointType toPoint = {+DX[type],+DY[type]};
// 玩家当前格位置与触碰到箱子的位置,便于恢复地图状态
PointType beforePlayer = Gplayer;
switch([][])
{
case '.':
case 'G':
// 如果下一格是空地或目标点,直接前进
Gplayer=toPoint;
break;
case '#':
// 如果下一格是墙,忽略输入
break;
case 'B':
// 如果下一格是箱子,对箱子在进行一次判断
PointType boxToPoint = {+DX[type],+DY[type]};
switch([][])
{
case '.':
case 'G':
// 如果下一格是空地或目标点,直接前进
[][]='B';
// 玩家覆盖该位置
Gplayer=toPoint;
break;
// 其他状况忽略输入
}
break;
}
// 更新地图上玩家位置
[][]='P';
// 恢复玩家之前踩着的格子状态,仅存在目标点需要处理
if(beforePlayer!=Gplayer)
{
if(Glevel[GlevelSelect].levelMap[][]=='G')
[][]='G';
else
[][]='.';
}
return;
}
/**
* 获取用户输入
**/
void GetPlayerInput()
{
int input=getch();
switch(input)
{
case 'w':
PlayerMove(0);
break;
case 's':
PlayerMove(1);
break;
case 'a':
PlayerMove(2);
break;
case 'd':
PlayerMove(3);
break;
case 'r':
LoadLevelToGame(Glevel[GlevelSelect]);
break;
case 'q':
exit(0);
break;
default:
break;
}
return;
}
/**
* 判断玩家胜利
**/
bool CheckPlayerWin()
{
bool isWin=true;
for(int i=0; i<; i++)
for(int j=0; j<; j++)
if(Glevel[GlevelSelect].levelMap[i][j]=='G'&&[i][j]!='B')
isWin=false;
return isWin;
}
/**
* 程序入口
**/
int main()
{
// 初始化游戏
InitGame();
while(true)
{
// 加载关卡界面
LevelSelect();
// 游戏开始
while(true)
{
// 获取用户输入并执行相关功能函数
GetPlayerInput();
// 更新画面
Update();
// 判断玩家是否胜利
if(CheckPlayerWin())
{
// 显示胜利画面
UpdateWin();
// 返回到关卡选择界面
break;
}
}
}
return 0;
}