由于C++面向对象的编程方式,注重于数据的处理,所以一个类的设计显得尤为重要。
这里我就设计了一个迷宫类,其属性有迷宫大小,空格(可行路径)的数目,入口坐标,出口坐标,主角老鼠的坐标,以及bool变量pass,表示判断此次生成的迷宫是否可以成功从入口到出口。
private里的函数有构造迷宫(通过rand系函数随机生成路径,’#’代表路障,’ ‘代表可通过路径,’*’代表老鼠),判断迷宫是否可行和清理由判断迷宫留下的路径。
实现代码如下:
#include <iostream>
#include <getch.h>
#include <cstdlib>
using namespace std;
#define MAX 15
class Maze
{
private:
char map[MAX][MAX];
int spacenum;
char in_x,in_y;
char out_x,out_y;
char pos_x,pos_y;
bool pass;
void create_Maze(void)
{
srand(time(NULL));
for (int i = 0; i < MAX; ++i)
{
for (int j = 0; j < MAX; ++j)
{
map[i][j] = '#';//铺满路障
}
}
map[in_x][in_y] = ' ';//入口设置
map[out_x][out_y] = ' ';//出口设置
for (int i = 0; i < spacenum;)
{
char x = rand()%(MAX-2)+1;//由于要设置墙壁(1和MAX-1为墙壁),所以从1~MAX-2的随机生成空格
char y = rand()%(MAX-2)+1;
if (map[x][y] == '#')
{
map[x][y] = ' ';
i++;
}
}
}
bool check_map(int x,int y)//判断迷宫是否可以走出去
{
map[x][y] = '*';
if(x == out_x && y == out_y) pass = true;
if(pass != true && map[x][y+1] == ' ') check_map(x, y+1);
if(pass != true && map[x+1][y] == ' ') check_map(x+1, y);
if(pass != true && map[x][y-1] == ' ') check_map(x, y-1);
if(pass != true && map[x-1][y] == ' ') check_map(x-1, y);
if(pass != true)
map[x][y] = ' ';
return pass;
}
void clear_maze(void)//将check_map留下的路径清空
{
for (int i = 0; i < MAX; i++)
{
for (int j = 0; j < MAX; j++)
{
if('*' == map[i][j])
{
map[i][j] = ' ';
}
}
}
map[in_x][in_y] = '*';//顺便在入口设置老鼠位置
}
public:
Maze(char in_x_,char in_y_,char out_x_,char out_y_,int space_num)
{
in_x = in_x_;//构造函数赋值类属性
in_y = in_y_;
out_x = out_x_;
out_y = out_y_;
spacenum = space_num;
pos_x = in_x_;
pos_y = in_y_;
pass = false;
do
{
create_Maze();
}
while(!check_map(in_x,in_y));//若地图不能通过则继续创建新地图
clear_maze();//清除路径
}
void Maze_show(void)//显示地图
{
system("clear");
for (int i = 0; i < MAX; ++i)
{
for (int j = 0; j < MAX; ++j)
{
cout << map[i][j] << " ";
}
cout << endl;
}
}
void up(void)//通过键盘的上下左右控制老鼠的行动
{
if(pos_y <= 0) return;
if (map[pos_x][pos_y-1] != '#')
{
map[pos_x][pos_y] = ' ';
pos_y--;
map[pos_x][pos_y] = '*';
}
}
void down(void)
{
if(pos_y >= MAX-1) return;
if (map[pos_x][pos_y+1] != '#')
{
map[pos_x][pos_y] = ' ';
pos_y++;
map[pos_x][pos_y] = '*';
}
}
void right(void)
{
if(pos_x >= MAX-1) return;
if (map[pos_x+1][pos_y] != '#')
{
map[pos_x][pos_y] = ' ';
pos_x++;
map[pos_x][pos_y] = '*';
}
}
void left(void)
{
if(pos_x <= 0) return;
if (map[pos_x-1][pos_y] != '#')
{
map[pos_x][pos_y] = ' ';
pos_x--;
map[pos_x][pos_y] = '*';
}
}
bool is_pass(void)//判断老鼠是否到达出口
{
if (pos_x == out_x && pos_y == out_y)
{
return true;
}
else
{
return false;
}
}
};
int main(int argc, char const *argv[])
{
Maze maze(0,1,14,13,130);//迷宫对象初始化
while(1)
{
maze.Maze_show();
if (maze.is_pass() == true)
{
cout<<"Congratulations!"<<endl;
break;
}
switch(getch())//通过键值判断老鼠走向
{
case 183:maze.left();break;
case 184:maze.right();break;
case 185:maze.down();break;
case 186:maze.up();break;
default:break;
}
}
return 0;
}
头文件getch.h是个人封装的,如下
#ifndef __GETCH__HH__
#define __GETCH__HH__
#include <stdio.h>
#include <termios.h>
#include <unistd.h>
int getch(void)
{
//get terminal profile(backup)
struct termios old;
int ret = tcgetattr(STDIN_FILENO, &old);
if (ret < 0)
{
perror("tcgetattr");
return -1;
}
//new terminal profile and cancel echo and ensure
struct termios _new = old;
_new.c_lflag &= ~(ICANON|ECHO);
//set the terminal profile
ret = tcsetattr(STDIN_FILENO, TCSANOW, &_new);
if (ret < 0)
{
perror("tcgsetattr");
return -2;
}
//get info through new profile
int key_value = 0;
do
{
key_value += getchar();
} while (stdin->_IO_read_end - stdin->_IO_read_ptr);
//reset terminal profile
ret = tcsetattr(STDIN_FILENO, TCSANOW, &old);
if (ret < 0)
{
perror("tcsetattr");
return -3;
}
//return the key value
return key_value;
}
#endif