更新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,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include<string>
|
#include "MazeSymbol.h"
|
||||||
|
#include <string>
|
||||||
|
|
||||||
class ConfigReader
|
class ConfigReader
|
||||||
{
|
{
|
||||||
|
|
@ -8,10 +9,13 @@ 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
|
||||||
|
|
@ -20,18 +24,14 @@ 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