C++ 迷宫游戏实现代码
题目 通过让游戏角色自动寻找迷宫出口,走出迷宫,来练习C++面向对象之封装的基础知识。迷宫图如下所示,其中X表示墙。
1、程序分析
走出去的原理:遵循右手规则或左手规则。右手扶墙走,就会走出迷宫,反之,亦然。
step1 创建迷宫类,打印出迷宫地图。
step2 创建走迷宫的人的类。
2、程序实现
MazeMap.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
#ifndef MAZEMAP_H #define MAZEMAP_H #include <iostream> #include <Windows.h> //COORD //在二维数组里,1代表墙,0代表路 #define WALL 1 #define ROAD 0 class MazeMap { public : MazeMap( char wall = 'X' ); ~MazeMap(); /*设置迷宫地图*/ void setMazeMap( int *mazemap, int row, int col); void pintMazeMap(); int ** getMap(); //返回地图二维数组指针 const char m_cRoad; //常数据成员:路 void setExitPosition( int x, int y); //设置迷宫出口 COORD m_COORDExitPostion; //迷宫的出口 private : const char m_cWall; //常数据成员:墙 int ** m_pMap; //指向迷宫地图二维数组的二级指针 int m_iMapRow; //二维数组的行数 int m_iMapCol; //二维数组的列数 }; #endif |
MazeMap.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
|
#include "MazeMap.h" /************************** *函数名称:MazeMap() *函数功能:构造函数,初始化参数 *函数参数:wall 墙的表示符号 *修改时间:2016.7.18 ***************************/ MazeMap::MazeMap( char wall):m_cWall(wall),m_cRoad( ' ' ) { m_pMap = NULL; } /************************* *函数名称:~MazeMap() *函数功能:析构函数,释放动态申请的内存空间 *修改时间:2016.7.18 **************************/ MazeMap::~MazeMap() { if (m_pMap) { for ( int i = 0; i < m_iMapRow; i++) { delete m_pMap[i]; m_pMap[i] = NULL; } delete m_pMap; } } /******************************** *函数名称:setMazeMap() *函数功能:设置迷宫地图,传递参数 *函数参数:*mazemap 存储地图数据的二维数组的指针 * row 二维数组的行数 * col 二维数组的列数 *修改时间:2016.7.18 **********************************/ void MazeMap::setMazeMap( int *mazemap, int row, int col) { m_iMapRow = row; m_iMapCol = col; //为存储迷宫地图的二维数组动态分配内存空间 m_pMap = new int *[m_iMapRow]; //分配m_iMapRow个存储int类型指针的内存空间 for ( int i = 0; i < m_iMapRow; i++) m_pMap[i] = new int [m_iMapCol]; //分配m_iMapCol个存储int类型的内存空间 //将二维数组迷宫地图的数据拷贝给二级指针 for ( int i = 0; i < m_iMapRow; i++) { for ( int j = 0; j < m_iMapCol; j++) { m_pMap[i][j] = *mazemap; mazemap++; } } } /************************************************ *函数名称:pintMazeMap() *函数功能:打印迷宫地图 *修改时间:2016.7.18 *************************************************/ void MazeMap::pintMazeMap() { system ( "cls" ); for ( int i = 0; i < m_iMapRow; i++) { for ( int j = 0; j < m_iMapCol; j++) { if (m_pMap[i][j]) //数组元素为1,则打印代表墙的字符 std::cout << m_cWall; else //否则,打印代表路的字符 std::cout << m_cRoad; } std::cout << std::endl; } } /************************************************ *函数名称:getMap() *函数功能:返回地图二维数组指针 *返 回 值:二级指针 *修改时间:2016.7.18 *************************************************/ int ** MazeMap::getMap() { return m_pMap; } /************************************************ *函数名称:setExitPosition() *函数功能:设置迷宫的出口 *函数参数:x 迷宫出口位置所在行数 y 迷宫出口位置所在列数 *修改时间:2016.7.18 *************************************************/ void MazeMap::setExitPosition( int x, int y) { m_COORDExitPostion.X = x; m_COORDExitPostion.Y = y; } |
MazeMan.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
#ifndef MAZEMAN_H #define MAZEMAN_H #include <Windows.h> #include "MazeMap.h" enum direction{U,D,L,R}; class MazeMan { public : MazeMan( char man = 'T' , char manface = R); void setPosition( int x, int y); //设置游戏角色位置 void setMap(MazeMap *map); //设置地图对象 bool walkUp(); //向上走 bool walkDown(); //向下走 bool walkLeft(); //向左走 bool walkRight(); //向右走 void moveForward(direction direct); //根据传入的方向让游戏角色前进一步 void start(); //游戏开始函数 private : char m_cMan; //代表游戏角色的字符 char m_cManFace; //游戏角色的朝向 int m_iSteps; //记录游戏角色已经走的步数 COORD m_COORDManCurrentPosition; //游戏角色的当前位置 MazeMap *m_pMap; //地图对象 }; #endif |
MazeMan.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
|
#include "MazeMan.h" /************************* *函数名称:MazeMan() *函数功能:构造函数,初始化数据成员 *函数参数:man 表示游戏角色的字符 manface 游戏角色的朝向 *修改时间:2016.7.18 **************************/ MazeMan::MazeMan( char man, char manface) { m_cMan = man; m_cManFace = manface; m_iSteps = 0; } /******************************* *函数名称:setMap() *函数功能:设置地图对象中的地图 *函数参数:*map 地图对象的指针 *修改时间:2016.7.18 ********************************/ void MazeMan::setMap(MazeMap *map) { m_pMap = map; } /****************************** *函数名称:setPosition() *函数功能:设置游戏角色位置 *函数参数:x 角色所在位置的横坐标 y 角色所在位置的纵坐标 *修改时间:2016.7.18 ********************************/ void MazeMan::setPosition( int x, int y) { unsigned long numWritten; //获得命令行窗口的窗口句柄 HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE); m_COORDManCurrentPosition.X = x; m_COORDManCurrentPosition.Y = y; //在指定坐标位置填充指定的字符,这里我们在游戏角色的当前位置填充代表游戏角色的字符,使游戏角色采出现 FillConsoleOutputCharacter(handle,m_cMan,1,m_COORDManCurrentPosition,&numWritten); //参数说明:控制台屏幕缓冲区句柄,要向控制台缓冲区写入的字符;应写入的字符单元数; //一个COORD结构,它指定字符的字符是要写的第一个单元格的坐标; //指向接收的实际写入控制台屏幕缓冲区的字符数的变量的指针。 } /************************************************ *函数名称:moveForward() *函数功能:根据传入的方向让游戏角色前进一步 *函数参数:direct 移动的方向 *修改时间:2016.7.18 *************************************************/ void MazeMan::moveForward(direction direct) { unsigned long numWritten; //获取命令行窗口的窗口句柄 HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE); //在指定坐标位置填充指定的字符,这里我们在游戏角色的当前位置填充空格,使游戏角色消失 FillConsoleOutputCharacter(handle,m_pMap->m_cRoad,1,m_COORDManCurrentPosition,&numWritten); switch (direct) { case U: m_COORDManCurrentPosition.Y -= 1; break ; case D: m_COORDManCurrentPosition.Y += 1; break ; case L: m_COORDManCurrentPosition.X -= 1; break ; case R: m_COORDManCurrentPosition.X += 1; break ; default : break ; } //游戏角色坐标更新,在新的坐标 FillConsoleOutputCharacter(handle,m_cMan,1,m_COORDManCurrentPosition,&numWritten); //移动完成后跟新游戏角色的朝向 m_cManFace = direct; } /************************************************ *函数名称:walkUp() *函数功能:向上走一步,若成功,则返回ture;若失败,则返回false *修改时间:2016.7.18 *************************************************/ bool MazeMan::walkUp() { if (m_pMap->getMap()[m_COORDManCurrentPosition.Y - 1][m_COORDManCurrentPosition.X]) return false ; else moveForward(U); return true ; } /************************************************ *函数名称:walkDown() *函数功能:向下走一步,若成功,则返回ture;若失败,则返回false *修改时间:2016.7.18 *************************************************/ bool MazeMan::walkDown() { if (m_pMap->getMap()[m_COORDManCurrentPosition.Y + 1][m_COORDManCurrentPosition.X]) return false ; else moveForward(D); return true ; } /************************************************ *函数名称:walkLeft() *函数功能:向左走一步,若成功,则返回ture;若失败,则返回false *修改时间:2016.7.18 *************************************************/ bool MazeMan::walkLeft() { if (m_pMap->getMap()[m_COORDManCurrentPosition.Y][m_COORDManCurrentPosition.X - 1]) return false ; else moveForward(L); return true ; } /************************************************ *函数名称:walkRight() *函数功能:向右走一步,若成功,则返回ture;若失败,则返回false *修改时间:2016.7.18 *************************************************/ bool MazeMan::walkRight() { if (m_pMap->getMap()[m_COORDManCurrentPosition.Y][m_COORDManCurrentPosition.X + 1]) return false ; else moveForward(R); return true ; } /************************************************ *函数名称:start() *函数功能:游戏开始函数 *修改时间:2016.7.18 *************************************************/ void MazeMan::start() { while ( true ) { m_pMap->pintMazeMap(); switch (m_cManFace) { case U: //游戏角色朝上时,先向右,再向上,再向左,最后向下(右手原则) walkRight() || walkUp() || walkLeft() || walkDown(); break ; case D: walkLeft() || walkDown() || walkRight() || walkUp(); break ; case L: walkUp() || walkLeft() || walkDown() || walkRight(); break ; case R: walkDown() || walkRight() || walkUp() || walkLeft(); break ; default : break ; } m_iSteps++; if (m_COORDManCurrentPosition.X == m_pMap->m_COORDExitPostion.X && m_COORDManCurrentPosition.Y == m_pMap->m_COORDExitPostion.Y) break ; std::cout << "已经走了" << m_iSteps - 1 << "步" ; Sleep(500); } } |
Main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
#include "MazeMap.h" #include "MazeMan.h" #define MapRow 11 //迷宫地图的行数 #define MapCol 11 //迷宫地图的列数 int main() { //定义并初始化存储地图数据的二维数组 int map[MapRow][MapCol] = { {WALL, WALL, WALL, WALL, WALL, WALL, WALL, WALL, WALL, WALL, WALL}, {WALL, ROAD, ROAD, ROAD, WALL, ROAD, ROAD, ROAD, ROAD, ROAD, ROAD}, {WALL, ROAD, WALL, WALL, WALL, ROAD, WALL, WALL, WALL, ROAD, WALL}, {WALL, ROAD, ROAD, ROAD, WALL, ROAD, ROAD, ROAD, WALL, ROAD, WALL}, {WALL, ROAD, WALL, ROAD, WALL, ROAD, WALL, ROAD, WALL, WALL, WALL}, {WALL, ROAD, WALL, ROAD, ROAD, ROAD, WALL, ROAD, WALL, ROAD, WALL}, {WALL, ROAD, WALL, WALL, WALL, ROAD, WALL, WALL, WALL, ROAD, WALL}, {WALL, ROAD, WALL, ROAD, WALL, ROAD, ROAD, ROAD, WALL, ROAD, WALL}, {WALL, WALL, WALL, ROAD, WALL, WALL, WALL, ROAD, WALL, ROAD, WALL}, {ROAD, ROAD, ROAD, ROAD, ROAD, ROAD, ROAD, ROAD, ROAD, ROAD, WALL}, {WALL, WALL, WALL, WALL, WALL, WALL, WALL, WALL, WALL, WALL, WALL} }; //从堆中实例化地图对象 MazeMap *mm = new MazeMap(); mm->setMazeMap(&map[0][0],MapRow,MapCol); mm->setExitPosition(10,1); mm->pintMazeMap(); //从堆中实例化游戏角色对象 MazeMan *man = new MazeMan(); //设置角色起始位置 man->setPosition(0,9); //设置游戏要走的地图 man->setMap(mm); //用new的方式从堆中实例化的对象,使用完毕之后需要手动释放内存 man->start(); delete mm; mm = NULL; delete man; man = NULL; std::cout << "闯关成功!" << std::endl; system ( "pause" ); } |
3、运行结果
T代表人
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!