更新maze数据结构
							parent
							
								
									71d17de0e7
								
							
						
					
					
						commit
						678655ef5d
					
				| 
						 | 
					@ -0,0 +1,8 @@
 | 
				
			||||||
 | 
					BasedOnStyle: Microsoft
 | 
				
			||||||
 | 
					AccessModifierOffset: -4
 | 
				
			||||||
 | 
					AlignConsecutiveMacros: true
 | 
				
			||||||
 | 
					AlignTrailingComments: true
 | 
				
			||||||
 | 
					AllowShortFunctionsOnASingleLine: Inline
 | 
				
			||||||
 | 
					AllowShortIfStatementsOnASingleLine: false
 | 
				
			||||||
 | 
					BreakBeforeBraces: Allman
 | 
				
			||||||
 | 
					ColumnLimit: 0
 | 
				
			||||||
| 
						 | 
					@ -23,3 +23,7 @@ ConfigData::~ConfigData()
 | 
				
			||||||
void ConfigData::setSymbol(char wall, char empty, char player, char monster, char trap, char exit)
 | 
					void ConfigData::setSymbol(char wall, char empty, char player, char monster, char trap, char exit)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ConfigData::getSymbol(char& wall, char& empty, char& player, char& monster, char& trap, char& exit)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,37 +1,37 @@
 | 
				
			||||||
#pragma once
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include<string>
 | 
					#include "MazeSymbol.h"
 | 
				
			||||||
 | 
					#include <string>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ConfigReader
 | 
					class ConfigReader
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
	ConfigReader();
 | 
					    ConfigReader();
 | 
				
			||||||
	~ConfigReader();
 | 
					    ~ConfigReader();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void load(std::string& path);
 | 
					    void load(std::string &path);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
 | 
					    MazeSymbol symbols; // 存放迷宫符号
 | 
				
			||||||
 | 
					    int difficulty = 0; // 怪物AI难度
 | 
				
			||||||
 | 
					    int mazeWidth = 21;
 | 
				
			||||||
 | 
					    int mazeHeight = 21;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ConfigData
 | 
					class ConfigData
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
	ConfigData();
 | 
					    ConfigData();
 | 
				
			||||||
	~ConfigData();
 | 
					    ~ConfigData();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void setSymbol(char wall, char empty, char player, char monster,char trap, char exit);
 | 
					    void setSymbol(char wall, char empty, char player, char monster, char trap, char exit);
 | 
				
			||||||
	void getSymbol(char& wall, char& empty, char& player, char& monster, char& trap, char& exit);
 | 
					    void getSymbol(char &wall, char &empty, char &player, char &monster, char &trap, char &exit);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void setDiffculty(int level);
 | 
					    void setDiffculty(int level);
 | 
				
			||||||
	int getDiffculty();
 | 
					    int getDiffculty();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
 | 
					    char m_wall, m_empty, m_player, m_monster, m_trap, m_exit;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	char m_wall, m_empty, m_player, m_monster, m_trap, m_exit;
 | 
					    int m_monsterAILevel;
 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	int m_monsterAILevel;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,7 +8,4 @@ Game::~Game()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Game::loadConfig(const std::string& filePath)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,9 +1,19 @@
 | 
				
			||||||
#include "Maze.h"
 | 
					#include "Maze.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Maze::Maze()
 | 
					#include <algorithm>
 | 
				
			||||||
	:width(0),height(0)
 | 
					#include <iostream>
 | 
				
			||||||
{
 | 
					#include <random>
 | 
				
			||||||
 | 
					#include <stack>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct Cell
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int x, y;
 | 
				
			||||||
 | 
					    bool visited;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Maze::Maze()
 | 
				
			||||||
 | 
					    : m_width(0), m_height(0)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Maze::~Maze()
 | 
					Maze::~Maze()
 | 
				
			||||||
| 
						 | 
					@ -12,5 +22,125 @@ Maze::~Maze()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Maze::setMazeSymbols(char wall, char empty, char player, char monster, char trap, char exit)
 | 
					void Maze::setMazeSymbols(char wall, char empty, char player, char monster, char trap, char exit)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Maze::generate(int w, int h, const MazeSymbols &sym)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    m_symbols = sym;
 | 
				
			||||||
 | 
					    m_width = (w % 2 == 0) ? w + 1 : w;
 | 
				
			||||||
 | 
					    m_height = (h % 2 == 0) ? h + 1 : h;
 | 
				
			||||||
 | 
					    m_grid.assign(m_height, std::string(m_width, m_symbols.wall));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    std::vector<std::vector<Cell>> cells(m_height, std::vector<Cell>(m_width));
 | 
				
			||||||
 | 
					    for (int y = 0; y < m_height; ++y)
 | 
				
			||||||
 | 
					        for (int x = 0; x < m_width; ++x)
 | 
				
			||||||
 | 
					            cells[y][x] = {x, y, false};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    auto inside = [&](int x, int y)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return x > 0 && y > 0 && x < m_width - 1 && y < m_height - 1;
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    std::stack<Cell> st;
 | 
				
			||||||
 | 
					    std::random_device rd;
 | 
				
			||||||
 | 
					    std::mt19937 gen(rd());
 | 
				
			||||||
 | 
					    std::uniform_int_distribution<> startX(1, m_width - 2);
 | 
				
			||||||
 | 
					    std::uniform_int_distribution<> startY(1, m_height - 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 起点设为奇数坐标
 | 
				
			||||||
 | 
					    int sx = (startX(gen) / 2) * 2 + 1;
 | 
				
			||||||
 | 
					    int sy = (startY(gen) / 2) * 2 + 1;
 | 
				
			||||||
 | 
					    st.push({sx, sy, true});
 | 
				
			||||||
 | 
					    m_grid[sy][sx] = m_symbols.empty;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // DFS生成
 | 
				
			||||||
 | 
					    while (!st.empty())
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        Cell c = st.top();
 | 
				
			||||||
 | 
					        std::vector<std::pair<int, int>> dirs = {{2, 0}, {-2, 0}, {0, 2}, {0, -2}};
 | 
				
			||||||
 | 
					        std::shuffle(dirs.begin(), dirs.end(), gen);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        bool moved = false;
 | 
				
			||||||
 | 
					        for (auto [dx, dy] : dirs)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            int nx = c.x + dx, ny = c.y + dy;
 | 
				
			||||||
 | 
					            if (inside(nx, ny) && !cells[ny][nx].visited)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                cells[ny][nx].visited = true;
 | 
				
			||||||
 | 
					                m_grid[ny][nx] = m_symbols.empty;
 | 
				
			||||||
 | 
					                m_grid[c.y + dy / 2][c.x + dx / 2] = m_symbols.empty;
 | 
				
			||||||
 | 
					                st.push({nx, ny, true});
 | 
				
			||||||
 | 
					                moved = true;
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!moved)
 | 
				
			||||||
 | 
					            st.pop();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 放置出口与陷阱
 | 
				
			||||||
 | 
					    m_grid[1][1] = m_symbols.empty;                     // 起点
 | 
				
			||||||
 | 
					    m_grid[m_height - 2][m_width - 2] = m_symbols.exit; // 出口
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 随机放置陷阱
 | 
				
			||||||
 | 
					    std::uniform_int_distribution<> tx(1, m_width - 2), ty(1, m_height - 2);
 | 
				
			||||||
 | 
					    for (int i = 0; i < (m_width * m_height) / 80; ++i)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        int x = tx(gen), y = ty(gen);
 | 
				
			||||||
 | 
					        if (m_grid[y][x] == m_symbols.empty)
 | 
				
			||||||
 | 
					            m_grid[y][x] = m_symbols.trap;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Maze::draw(const Position &playerPos, const std::vector<Position> &monsterPos) const
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    for (int y = 0; y < m_height; ++y)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        for (int x = 0; x < m_width; ++x)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            bool drawn = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // 绘制玩家
 | 
				
			||||||
 | 
					            if (playerPos.x == x && playerPos.y == y)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                std::cout << m_symbols.player;
 | 
				
			||||||
 | 
					                continue;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // 绘制怪物
 | 
				
			||||||
 | 
					            for (auto &m : monsterPos)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                if (m.x == x && m.y == y)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    std::cout << m_symbols.monster;
 | 
				
			||||||
 | 
					                    drawn = true;
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (drawn)
 | 
				
			||||||
 | 
					                continue;
 | 
				
			||||||
 | 
					            std::cout << m_grid[y][x];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        std::cout << "\n";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool Maze::isWalkable(const Position &p) const
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (p.x < 0 || p.x >= m_width || p.y < 0 || p.y >= m_height)
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    char c = m_grid[p.y][p.x];
 | 
				
			||||||
 | 
					    return (c == m_symbols.empty || c == m_symbols.trap || c == m_symbols.exit);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool Maze::isExit(const Position &p) const
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return m_grid[p.y][p.x] == m_symbols.exit;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool Maze::checkTrap(const Position &p) const
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return m_grid[p.y][p.x] == m_symbols.trap;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,6 +3,7 @@
 | 
				
			||||||
#include <vector>
 | 
					#include <vector>
 | 
				
			||||||
#include<string>
 | 
					#include<string>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct Position {
 | 
					struct Position {
 | 
				
			||||||
	int x, y;
 | 
						int x, y;
 | 
				
			||||||
	bool operator==(const Position& other) const {
 | 
						bool operator==(const Position& other) const {
 | 
				
			||||||
| 
						 | 
					@ -33,4 +34,5 @@ public:
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
	int m_width, m_height;
 | 
						int m_width, m_height;
 | 
				
			||||||
	std::vector<std::string> m_grid;
 | 
						std::vector<std::string> m_grid;
 | 
				
			||||||
 | 
						MazeSymbols m_symbols;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,65 @@
 | 
				
			||||||
 | 
					#include "MazeSymbol.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					MazeSymbol::MazeSymbol() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					MazeSymbol::~MazeSymbol() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					char MazeSymbol::getWall() const
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return wall;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void MazeSymbol::setWall(char value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    wall = value;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					char MazeSymbol::getEmpty() const
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return empty;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void MazeSymbol::setEmpty(char value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    empty = value;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					char MazeSymbol::getPlayer() const
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return player;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void MazeSymbol::setPlayer(char value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    player = value;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					char MazeSymbol::getMonster() const
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return monster;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void MazeSymbol::setMonster(char value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    monster = value;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					char MazeSymbol::getStrap() const
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return strap;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void MazeSymbol::setStrap(char value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    strap = value;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					char MazeSymbol::getExit() const
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return exit;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void MazeSymbol::setExit(char value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    exit = value;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,43 @@
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class MazeSymbol
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
						MazeSymbol();
 | 
				
			||||||
 | 
						~MazeSymbol();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  char getWall() const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void setWall(char value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  char getEmpty() const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void setEmpty(char value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  char getPlayer() const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void setPlayer(char value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  char getMonster() const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void setMonster(char value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  char getStrap() const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void setStrap(char value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  char getExit() const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void setExit(char value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					  char wall;
 | 
				
			||||||
 | 
					  char empty;
 | 
				
			||||||
 | 
					  char player;
 | 
				
			||||||
 | 
					  char monster;
 | 
				
			||||||
 | 
					  char strap;
 | 
				
			||||||
 | 
					  char exit;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,7 +4,7 @@ Player = @
 | 
				
			||||||
Monster = M
 | 
					Monster = M
 | 
				
			||||||
Trap = X
 | 
					Trap = X
 | 
				
			||||||
Exit = E
 | 
					Exit = E
 | 
				
			||||||
Empty = .
 | 
					Empty =  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[Difficulty]
 | 
					[Difficulty]
 | 
				
			||||||
# 0: 随机移动,1: BFS偏向,2: A*精确追踪
 | 
					# 0: 随机移动,1: BFS偏向,2: A*精确追踪
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue