学习c++有一段时间了,之前在慕课网碰到的一道题,老师给的,
大致说下吧,P代表人,开始时P在起点,然后P根据地图(‘#’代表墙,空格代表路)来判断前进的方向,并且为了实现动画效果,可以用这样一个函数
void Person::goto_Pos(Coor c)
{
COORD cd;
cd.X = c.y+1;
cd.Y = c.x;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), cd);
}
该函数可以将光标定位到坐标(cx.X,cx.Y)位置,光标的位置坐标是这样的:x从左到右增加,y从上到下增加
而地图是用字符数组画出来的,所以地图的坐标是这样的:
所以要想将光标定位到地图的(x,y)处,就是将光标移动到(y,x)处;
还有一点要注意的是,为了实现动画效果,先将光标定位到先前位置,擦除该字符,然后将光标定位到当前位置,擦除此处的字符(墙或者路),再输出人的字符(‘P’),所以用的是’\b’,所以应该将光标定位到地图坐标再往右移动一位,先做个小例子熟悉一下这个函数的用法吧
# include<iostream>
# include<string>
# include<windows.h>
using namespace std;
void gotoxy(int x, int y)
{
COORD cd;
cd.X = x;
cd.Y = y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), cd);
Sleep(1000);
}
int main()
{
cout << "1,2,3,4,5,6,7,8,9";
for (int i = 1;i <= 9;i++)
{
gotoxy(2*i-1, 0);
cout << '\b' << 2 * i;
}
gotoxy(0, 5);
system("pause");
return 0;
}
好了,以下是自己做的迷宫游戏源码
Maze.h:
#pragma once
# include"Person.h"
const int ROW = 12;
const int COLUMN = 6;
const char WALL = '#';
const char ROAD = ' ';
class Maze
{
friend class Person;
public:
//默认构造函数
Maze(char Map[ROW][COLUMN]);
void SetMap(char Map[ROW][COLUMN]);
void DrawMaze();
bool isOutOfMaze(int x, int y);
private:
char MazeMap[ROW][COLUMN];
static int iRow;
static int iColumn;
static char cWall;
static char cRoad;
};
Maze.cpp
# include"Maze.h"
# include<iostream>
using std::cout;
using std::endl;
int Maze::iRow=ROW;
int Maze::iColumn=COLUMN;
char Maze::cWall=WALL;
char Maze::cRoad=ROAD;
Maze::Maze(char Map[ROW][COLUMN])
{
SetMap(Map);
}
bool Maze::isOutOfMaze(int x, int y)
{
if (x == 8 && y == 2)
return false;
else if (y == 0 || y == iColumn - 1)
{
if (MazeMap [x][y] == cRoad)
return true;
}
else if (x == 0 || x == iRow - 1)
{
if (MazeMap[x][y] == cRoad)
return true;
}
return false;
}
void Maze::DrawMaze()
{
for (int i = 0;i < iRow;++i)
{
for (int j = 0;j < iColumn;++j)
cout << MazeMap[i][j];
cout << endl;
}
}
void Maze::SetMap(char map[ROW][COLUMN])
{
for (int x = 0;x < ROW;++x)
for (int y = 0;y < COLUMN;++y)
{
MazeMap[x][y] = map[x][y];
}
}
Person.h
#pragma once
# ifndef PERSON_H
# define PERSON_H
# include"Maze.h"
# include<iostream>
class Maze;
//enum Direction
//{
// UP = 0, DOWN, LEFT, RIGHT
//}Dir;
struct Coor
{
int x;
int y;
};
class Person
{
public:
Person(char person, Coor pos,Coor Prev);
void goto_Pos(Coor c);
void goUp();
void goDown();
void goLeft();
void goRight();
void start(Maze m);
void pervToCurr();
void showCount();
void judgeDir(Maze m);
private:
char cPerson;
Coor Position;//当前位置
Coor prevPosition;//当前位置
char Road;
char Wall;
int count;
enum dir{STOP=0,UP,DOWN,LEFT,RIGHT}perDir;
};
# endif
Person.cpp
# include"Person.h"
# include<Windows.h>
# include"Maze.h"
# include<iostream>
using namespace std;
Person::Person(char person = 'P', Coor pos = { 8,2 }, Coor Prev = { 2,8 }) :cPerson(person), Position(pos), prevPosition(Prev), count(0)
{
Road = Maze::cRoad;
Wall = Maze::cWall;
perDir = UP;//默认朝向上方
}
void Person::goto_Pos(Coor c)
{
COORD cd;
cd.X = c.y+1;
cd.Y = c.x;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), cd);
}
void Person::pervToCurr()
{
Coor c = {prevPosition.x,(prevPosition.y+1)};
goto_Pos(prevPosition);
cout <<'\b';
cout << ROAD;
goto_Pos(Position);
cout <<'\b'<<cPerson;
count++;
Sleep(1000);
showCount();
}
void Person::goUp()
{
prevPosition = Position;
Position.x--;
pervToCurr();
}
void Person::goDown()
{
prevPosition = Position;
Position.x++;
pervToCurr();
}
void Person::goLeft()
{
prevPosition = Position;
Position.y--;
pervToCurr();
}
void Person::goRight()
{
prevPosition = Position;
Position.y++;
pervToCurr();
}
void Person::start(Maze m)
{
bool gameOver = false;
pervToCurr();
while (!gameOver)
{
judgeDir(m);
Coor c = Position;
switch (perDir)
{
case UP://如果上面没墙,网上走
if(m.MazeMap[c.x-1][c.y]==ROAD)
goUp();
break;
case DOWN:
if(m.MazeMap[c.x + 1][c.y] == ROAD)
goDown();
break;
case LEFT:
if(m.MazeMap[c.x ][c.y-1] == ROAD)
goLeft();
break;
case RIGHT:
if (m.MazeMap[c.x][c.y+1] == ROAD)
goRight();
break;
default:
break;
}
gameOver = (m.isOutOfMaze)(Position.x, Position.y);
}
if (gameOver)
cout << "哈哈,终于出来了,继续努力!!" << endl;
}
void Person::showCount()
{
Coor c = { 12,0 };
goto_Pos(c);
cout << "步数:" << count;
}
void Person::judgeDir(Maze m)
{
Coor c = Position;
//看右边有没有墙
switch (perDir)
{
case UP:
//右边有墙:
if ((m.MazeMap[c.x][c.y + 1] == WALL) && (m.MazeMap[c.x - 1][c.y] == ROAD))
//右边有墙,上边没墙,人脸朝’上‘
perDir = UP;
else if ((m.MazeMap[c.x][c.y + 1] == WALL) && (m.MazeMap[c.x - 1][c.y] == WALL) && (m.MazeMap[c.x][c.y - 1] == ROAD))
//右边有墙,上边有墙,左边没墙,人脸朝‘左’
perDir = LEFT;
else if ((m.MazeMap[c.x][c.y + 1] == WALL) && (m.MazeMap[c.x - 1][c.y] == WALL) && (m.MazeMap[c.x][c.y - 1] == WALL))
右边有墙,上边有墙,左边有墙,人脸朝‘下’
perDir = DOWN;
//右边没墙,方向向右
else if (m.MazeMap[c.x][c.y + 1] == ROAD)
perDir = RIGHT;
break;
//下面的只是相对的改下方向即可
case DOWN:
//(对于人来说)右边有墙,即左边:
if ((m.MazeMap[c.x][c.y - 1] == WALL) && (m.MazeMap[c.x + 1][c.y] == ROAD))
//右(左)边有墙,上(下)边没墙,人脸朝’上‘(下)
perDir = DOWN;
else if ((m.MazeMap[c.x][c.y - 1] == WALL) && (m.MazeMap[c.x + 1][c.y] == WALL) && (m.MazeMap[c.x][c.y +1] == ROAD))
//右(左)边有墙,上(下)边有墙,左(右)边没墙,人脸朝‘左’(右)
perDir = RIGHT;
else if ((m.MazeMap[c.x][c.y + 1] == WALL) && (m.MazeMap[c.x - 1][c.y] == WALL) && (m.MazeMap[c.x][c.y - 1] == WALL))
右(左)边有墙,上(下)边有墙,左(右)边有墙,人脸朝‘下’(上)
perDir = UP;
//右(左)边没墙,方向向右(左)
else if (m.MazeMap[c.x][c.y - 1] == ROAD)
perDir = LEFT;
break;
case LEFT:
//右(上)边有墙:
if ((m.MazeMap[c.x-1][c.y ] == WALL) && (m.MazeMap[c.x][c.y-1] == ROAD))
//右(上)边有墙,上(左)边没墙,人脸朝’上‘(左)
perDir = LEFT;
else if ((m.MazeMap[c.x-1][c.y ] == WALL) && (m.MazeMap[c.x][c.y-1] == WALL) && (m.MazeMap[c.x+1][c.y] == ROAD))
//右(上)边有墙,上(左)边有墙,左(下)边没墙,人脸朝‘左’(下)
perDir = DOWN;
else if ((m.MazeMap[c.x-1][c.y ] == WALL) && (m.MazeMap[c.x][c.y-1] == WALL) && (m.MazeMap[c.x+1][c.y] == WALL))
右(上)边有墙,上(左)边有墙,左(下)边有墙,人脸朝‘下’(右)
perDir = RIGHT;
//右(上)边没墙,方向向右(上)
else if (m.MazeMap[c.x-1][c.y ] == ROAD)
perDir = UP;
break;
case RIGHT:
//右(下)边有墙:
if ((m.MazeMap[c.x+1][c.y] == WALL) && (m.MazeMap[c.x][c.y+1] == ROAD))
//右(下)边有墙,上(右)边没墙,人脸朝’上‘(右)
perDir = RIGHT;
else if ((m.MazeMap[c.x+1][c.y ] == WALL) && (m.MazeMap[c.x ][c.y+1] == WALL) && (m.MazeMap[c.x-1][c.y ] == ROAD))
//右(下)边有墙,上(右)边有墙,左(上)边没墙,人脸朝‘左’(上)
perDir = UP;
else if ((m.MazeMap[c.x+1][c.y ] == WALL) && (m.MazeMap[c.x][c.y+1] == WALL) && (m.MazeMap[c.x-1][c.y] == WALL))
//右(下)边有墙,上(右)边有墙,左(上)边有墙,人脸朝‘下’(左)
perDir = LEFT;
//右(下)边没墙,方向向右(下)
else if (m.MazeMap[c.x+1][c.y] == ROAD)
perDir = DOWN;
break;
}
}
main.cpp
# include<iostream>
# include"Maze.h"
# include"Person.h"
using namespace std;
int main()
{
char defMap[ROW][COLUMN] = {
WALL,WALL,ROAD,WALL,WALL,WALL,
WALL,WALL,ROAD,WALL,WALL,WALL,
WALL,ROAD,ROAD,WALL,WALL,WALL,
WALL,ROAD,ROAD,ROAD,ROAD,WALL,
WALL,WALL,WALL,ROAD,WALL,WALL,
WALL,WALL,ROAD,ROAD,ROAD,WALL,
WALL,ROAD,WALL,WALL,ROAD,WALL,
WALL,ROAD,ROAD,ROAD,ROAD,WALL,
WALL,WALL,ROAD,WALL,WALL,WALL,
};
Maze m(defMap);
m.DrawMaze();
Person person('P', { 8,2 }, {8,2});
person.start(m);
system("pause");
return 0;
}