采用全局变量的形式,设置游戏的场景
const char Scence[] = "########\n# .. p #\n# oo #\n# #\n########\n";
const int Swith = 8;
const int Shight = 5;
注:其中“#”代表墙壁,“.”代表箱子到达的最终地方,“o”代表箱子,“p”代表推箱子的人
enum Object {
Space, Wall, Goal, Block, Block_on_Goal, Man, Man_on_Goal, Unknown,
};
注:后面会设置一个枚举类型的数组。
void initialize(Object *s, int w, int h, const char *S) {
const char* d = S;
int x = 0;
int y = 0;
while (*d != '\0') {
Object t;
switch (*d) {
case '#':t = Wall;
break;
case ' ':t = Space;
break;
case 'o':t = Block;
break;
case 'O':t = Block_on_Goal;
break;
case '.':t = Goal;
break;
case 'p':t = Man;
break;
case'P':t = Man_on_Goal;
break;
case'\n':x = 0;
y = y+1;
t = Unknown;
break;
default:t = Unknown;
break;
}
++d;
if (t != Unknown) {
s[y*w + x] = t;
++x;
}
}
}
对游戏进行初始化,由于设置了一个枚举类型数组,将游戏中的字符采用枚举类型表示。
void draw(Object *s, int w, int h) {
const char font[] = { ' ','#','.','o','O','p','P' };
for (int y = 0; y < h; y++) {
for (int x = 0; x < w; x++) {
Object o = s[y*w + x];
cout << font[o];
}
cout << endl;
}
}
输出游戏场景。
void update(Object *s, char input, int w, int h) {
int dx = 0;
int dy = 0;
switch (input){
case 'a':dx = -1;
break;
case 's':dx = 1;
break;
case 'w':dy = -1;
break;
case 'z':dy = 1;
break;
}
int i = 0;
for (i = 0; i < w*h; i++) {
if (s[i] == Man || s[i] == Man_on_Goal) {
break;
}
}
int x = i % w;
int y = i / w;
int tx = x + dx;
int ty = y + dy;
if (tx < 0 || ty < 0 || tx >= w || ty >= h) {
return;
}
int p = y * w + x;
int tp = ty * w + tx;
if (s[tp] == Space || s[tp] == Goal) {
s[tp] = (s[tp] == Goal) ? Man_on_Goal : Man;
s[p] = (s[p] == Man_on_Goal) ? Goal : Space;
}
else if (s[tp] == Block || s[tp] == Block_on_Goal) {
int tx2 = tx + dx;
int ty2 = ty + dy;
if (tx2 < 0 || ty2 < 0 || tx2 >= w || ty2 >= h) {
return;
}
int tp2 = (ty + dy)*w + (tx + dx);
if (s[tp2] == Space || s[tp2] == Goal) {
s[tp2] = (s[tp2] == Goal) ? Block_on_Goal : Block;
s[tp] = (s[tp] == Block_on_Goal) ? Man_on_Goal : Man;
s[p] = (s[p] == Man_on_Goal) ? Goal : Space;
}
}
}
更新游戏场景,其中分为两种情况:
1、p在移动的过程中,没有遇到o,移动后只需要对p的当前位置和p移动后的位置,进行相应改变;
2、p在移动的过程中遇到箱子,移动过程中,需要改变3个位置;
bool checkClear(Object *s, int w, int h) {
for (int i = 0; i < w*h; i++) {
if (s[i] == Block) {
return false;
}
}
return true;
}
判断箱子有没有到达指定位置。
int main() {
Object* arr = new Object[Swith*Shight];
//int arr[Swith][Shight];
//初始化场景
initialize(arr, Swith, Shight, Scence);
while (true) {
draw(arr, Swith, Shight);
if (checkClear(arr, Swith, Shight)) {
break;
}
//获取输入
cout << "a:letf s:right w:up z:down.command?" << endl;
char input;
cin >> input;
update(arr, input, Swith, Shight);
}
delete[] arr;
return 0;
}
游戏的整体过程如上。
注:
1、c++中,如果字符串常量要中途换行显示,必须在行末加上符号\;
2、采用枚举类型数组,不会导致因疏忽而带入无意义的值的情况,在调试的过程中可以看见枚举类型的名字,使用起来方便。
3、实际上枚举类型是一种用于列举的类型,可以通过new生成,也可以作为参数返回值。
4、通过new创建的数组释放时必须使用·delete[]。