配置文件读取

remote
InkSoul 2025-10-26 21:27:15 +08:00
parent 678655ef5d
commit fbbc6e20af
12 changed files with 256 additions and 199 deletions

View File

@ -1,4 +1,8 @@
#include "Config.h" #include "Config.h"
#include <algorithm>
#include <fstream>
#include <iostream>
#include <sstream>
ConfigReader::ConfigReader() ConfigReader::ConfigReader()
{ {
@ -8,22 +12,78 @@ ConfigReader::~ConfigReader()
{ {
} }
void ConfigReader::load(std::string& path) std::string ConfigReader::trim(const std::string &s)
{ {
auto start = s.find_first_not_of(" \t\r\n");
auto end = s.find_last_not_of(" \t\r\n");
if (start == std::string::npos)
return "";
return s.substr(start, end - start + 1);
} }
ConfigData::ConfigData() bool ConfigReader::load(std::string &path)
{ {
} std::ifstream file(path);
if (!file.is_open())
{
std::cerr << "无法打开配置文件: " << path << std::endl;
return false;
}
ConfigData::~ConfigData() std::string line, section;
{
}
void ConfigData::setSymbol(char wall, char empty, char player, char monster, char trap, char exit) while (std::getline(file, line))
{ {
} line = trim(line);
void ConfigData::getSymbol(char& wall, char& empty, char& player, char& monster, char& trap, char& exit) if (line.empty() || line[0] == ';' || line[0] == '#')
{ continue;
// 识别 [Section]
if (line.front() == '[' && line.back() == ']')
{
section = line.substr(1, line.size() - 2);
continue;
}
// 解析 Key = Value
size_t eq = line.find('=');
if (eq == std::string::npos)
continue;
std::string key = trim(line.substr(0, eq));
std::string value = trim(line.substr(eq + 1));
// 根据 section 分发
if (section == "Symbols")
{
if (key == "Wall")
symbols.setWall(value[0]);
else if (key == "Empty")
symbols.setEmpty(value[0]);
else if (key == "Player")
symbols.setPlayer(value[0]);
else if (key == "Monster")
symbols.setMonster(value[0]);
else if (key == "Trap")
symbols.setTrap(value[0]);
else if (key == "Exit")
symbols.setExit(value[0]);
}
else if (section == "Difficulty")
{
if (key == "MonsterAI")
difficulty = std::stoi(value);
}
else if (section == "Maze")
{
if (key == "Width")
mazeWidth = std::stoi(value);
else if (key == "Height")
mazeHeight = std::stoi(value);
}
}
file.close();
return true;
} }

View File

@ -1,6 +1,6 @@
#pragma once #pragma once
#include "MazeSymbol.h" #include "MazeData.h"
#include <string> #include <string>
class ConfigReader class ConfigReader
@ -9,29 +9,17 @@ public:
ConfigReader(); ConfigReader();
~ConfigReader(); ~ConfigReader();
void load(std::string &path); bool load(const std::string &path);
MazeData getSymbols() const;
void setSymbols(MazeData &value);
private: private:
MazeSymbol symbols; // 存放迷宫符号 std::string trim(const std::string &s);
private:
MazeData symbols; // 存放迷宫符号
int difficulty = 0; // 怪物AI难度 int difficulty = 0; // 怪物AI难度
int mazeWidth = 21; int mazeWidth = 21;
int mazeHeight = 21; int mazeHeight = 21;
}; };
class ConfigData
{
public:
ConfigData();
~ConfigData();
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 setDiffculty(int level);
int getDiffculty();
private:
char m_wall, m_empty, m_player, m_monster, m_trap, m_exit;
int m_monsterAILevel;
};

View File

@ -8,4 +8,14 @@ Game::~Game()
{ {
} }
void Game::loadConfig(const std::string &filePath, MazeData &data)
{
m_config.setSymbols(data);
m_config.load(filePath);
}
void Game::initMaze()
{
}
void Game::run()
{
}

View File

@ -1,27 +1,23 @@
#pragma once #pragma once
#include "Config.h" #include "Config.h"
#include "MazeData.h"
#include <string> #include <string>
class Game class Game
{ {
private: private:
ConfigReader m_config;
MazeData m_mazeData;
ConfigReader m_config; bool m_isRunning = true;
ConfigData m_configData;
bool m_isRunning = true;
public: public:
Game(); Game();
~Game(); ~Game();
void loadConfig(const std::string& filePath,ConfigData& data);
void initMaze(ConfigData data);
void run();
void loadConfig(const std::string &filePath, MazeData &data);
void initMaze();
void run();
}; };

View File

@ -20,16 +20,16 @@ Maze::~Maze()
{ {
} }
void Maze::setMazeSymbols(char wall, char empty, char player, char monster, char trap, char exit) void Maze::setMazeData(MazeData &data)
{ {
} }
void Maze::generate(int w, int h, const MazeSymbols &sym) void Maze::generate(int w, int h, const MazeData &sym)
{ {
m_symbols = sym; m_symbols = sym;
m_width = (w % 2 == 0) ? w + 1 : w; m_width = (w % 2 == 0) ? w + 1 : w;
m_height = (h % 2 == 0) ? h + 1 : h; m_height = (h % 2 == 0) ? h + 1 : h;
m_grid.assign(m_height, std::string(m_width, m_symbols.wall)); m_grid.assign(m_height, std::string(m_width, m_symbols.getWall()));
std::vector<std::vector<Cell>> cells(m_height, std::vector<Cell>(m_width)); std::vector<std::vector<Cell>> cells(m_height, std::vector<Cell>(m_width));
for (int y = 0; y < m_height; ++y) for (int y = 0; y < m_height; ++y)
@ -51,7 +51,7 @@ void Maze::generate(int w, int h, const MazeSymbols &sym)
int sx = (startX(gen) / 2) * 2 + 1; int sx = (startX(gen) / 2) * 2 + 1;
int sy = (startY(gen) / 2) * 2 + 1; int sy = (startY(gen) / 2) * 2 + 1;
st.push({sx, sy, true}); st.push({sx, sy, true});
m_grid[sy][sx] = m_symbols.empty; m_grid[sy][sx] = m_symbols.getEmpty();
// DFS生成 // DFS生成
while (!st.empty()) while (!st.empty())
@ -67,8 +67,8 @@ void Maze::generate(int w, int h, const MazeSymbols &sym)
if (inside(nx, ny) && !cells[ny][nx].visited) if (inside(nx, ny) && !cells[ny][nx].visited)
{ {
cells[ny][nx].visited = true; cells[ny][nx].visited = true;
m_grid[ny][nx] = m_symbols.empty; m_grid[ny][nx] = m_symbols.getEmpty();
m_grid[c.y + dy / 2][c.x + dx / 2] = m_symbols.empty; m_grid[c.y + dy / 2][c.x + dx / 2] = m_symbols.getEmpty();
st.push({nx, ny, true}); st.push({nx, ny, true});
moved = true; moved = true;
break; break;
@ -80,16 +80,16 @@ void Maze::generate(int w, int h, const MazeSymbols &sym)
} }
// 放置出口与陷阱 // 放置出口与陷阱
m_grid[1][1] = m_symbols.empty; // 起点 m_grid[1][1] = m_symbols.getEmpty(); // 起点
m_grid[m_height - 2][m_width - 2] = m_symbols.exit; // 出口 m_grid[m_height - 2][m_width - 2] = m_symbols.getExit(); // 出口
// 随机放置陷阱 // 随机放置陷阱
std::uniform_int_distribution<> tx(1, m_width - 2), ty(1, m_height - 2); 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) for (int i = 0; i < (m_width * m_height) / 80; ++i)
{ {
int x = tx(gen), y = ty(gen); int x = tx(gen), y = ty(gen);
if (m_grid[y][x] == m_symbols.empty) if (m_grid[y][x] == m_symbols.getEmpty())
m_grid[y][x] = m_symbols.trap; m_grid[y][x] = m_symbols.getTrap();
} }
} }
@ -104,7 +104,7 @@ void Maze::draw(const Position &playerPos, const std::vector<Position> &monsterP
// 绘制玩家 // 绘制玩家
if (playerPos.x == x && playerPos.y == y) if (playerPos.x == x && playerPos.y == y)
{ {
std::cout << m_symbols.player; std::cout << m_symbols.getPlayer();
continue; continue;
} }
@ -113,7 +113,7 @@ void Maze::draw(const Position &playerPos, const std::vector<Position> &monsterP
{ {
if (m.x == x && m.y == y) if (m.x == x && m.y == y)
{ {
std::cout << m_symbols.monster; std::cout << m_symbols.getMonster();
drawn = true; drawn = true;
break; break;
} }
@ -132,15 +132,15 @@ bool Maze::isWalkable(const Position &p) const
if (p.x < 0 || p.x >= m_width || p.y < 0 || p.y >= m_height) if (p.x < 0 || p.x >= m_width || p.y < 0 || p.y >= m_height)
return false; return false;
char c = m_grid[p.y][p.x]; char c = m_grid[p.y][p.x];
return (c == m_symbols.empty || c == m_symbols.trap || c == m_symbols.exit); return (c == m_symbols.getEmpty() || c == m_symbols.getTrap() || c == m_symbols.getExit());
} }
bool Maze::isExit(const Position &p) const bool Maze::isExit(const Position &p) const
{ {
return m_grid[p.y][p.x] == m_symbols.exit; return m_grid[p.y][p.x] == m_symbols.getExit();
} }
bool Maze::checkTrap(const Position &p) const bool Maze::checkTrap(const Position &p) const
{ {
return m_grid[p.y][p.x] == m_symbols.trap; return m_grid[p.y][p.x] == m_symbols.getTrap();
} }

View File

@ -1,38 +1,36 @@
#pragma once #pragma once
#include "MazeData.h"
#include <string>
#include <vector> #include <vector>
#include<string>
struct Position
struct Position { {
int x, y; int x, y;
bool operator==(const Position& other) const { bool operator==(const Position &other) const
return x == other.x && y == other.y; {
} return x == other.x && y == other.y;
}; }
// 用于存储字符符号
struct MazeSymbols {
char wall, empty, player, monster, trap, exit;
}; };
class Maze class Maze
{ {
public: public:
Maze(); Maze();
~Maze(); ~Maze();
void setMazeSymbols(char wall, char empty, char player, char monster, char trap, char exit); void setMazeData(MazeData &data);
void generate(int w, int h, const MazeSymbols& sym); void generate(int w, int h, const MazeData &sym);
void draw(const Position& playerPos, const std::vector<Position>& monsterPos) const; void draw(const Position &playerPos, const std::vector<Position> &monsterPos) const;
bool isWalkable(const Position& p) const; bool isWalkable(const Position &p) const;
bool isExit(const Position& p) const; bool isExit(const Position &p) const;
bool checkTrap(const Position& p) const; bool checkTrap(const Position &p) const;
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; MazeData m_symbols;
}; };

View File

@ -0,0 +1,69 @@
#include "MazeData.h"
MazeData::MazeData()
{
}
MazeData::~MazeData()
{
}
char MazeData::getWall() const
{
return wall;
}
void MazeData::setWall(char value)
{
wall = value;
}
char MazeData::getEmpty() const
{
return empty;
}
void MazeData::setEmpty(char value)
{
empty = value;
}
char MazeData::getPlayer() const
{
return player;
}
void MazeData::setPlayer(char value)
{
player = value;
}
char MazeData::getMonster() const
{
return monster;
}
void MazeData::setMonster(char value)
{
monster = value;
}
char MazeData::getTrap() const
{
return trap;
}
void MazeData::setTrap(char value)
{
trap = value;
}
char MazeData::getExit() const
{
return exit;
}
void MazeData::setExit(char value)
{
exit = value;
}

View File

@ -0,0 +1,40 @@
#pragma once
class MazeData
{
public:
MazeData();
~MazeData();
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 getTrap() const;
void setTrap(char value);
char getExit() const;
void setExit(char value);
private:
char wall;
char empty;
char player;
char monster;
char trap;
char exit;
};

View File

@ -1,65 +0,0 @@
#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;
}

View File

@ -1,43 +0,0 @@
#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;
};

View File

@ -9,3 +9,7 @@ Empty =
[Difficulty] [Difficulty]
# 0: 随机移动1: BFS偏向2: A*精确追踪 # 0: 随机移动1: BFS偏向2: A*精确追踪
MonsterAI = 1 MonsterAI = 1
[Maze]
Width = 21
height = 21

View File

@ -2,11 +2,11 @@
int main() int main()
{ {
std::cout << "Hello CMake." << std::endl; std::cout << "Hello CMake." << std::endl;
Game game; Game game;
game.loadConfig("config.txt"); game.loadConfig("config.txt");
game.initMaze(); game.initMaze();
game.run(); game.run();
return 0; return 0;
} }