这是王虎应书中一个案例,本图截取自哔哩哔哩up主[牛正六爻]的一个免费教学视频。

主卦卦身为申,没有上卦,为卦主问卦之时处于无婚姻状态之象【卦主自离婚后至求测没有再娶】。
虢婶代码辅助理解记忆。
cpp
#include <iostream>
#include <vector>
#include <string>
#include <ctime>
#include <cstdlib>
#include <cmath>
#include <cctype>
// 游戏常量定义
const int MAP_WIDTH = 18; // 地图宽度
const int MAP_HEIGHT = 12; // 地图高度
const int INIT_PLAYER_HP = 120; // 玩家初始生命值
const int INIT_PLAYER_ATK = 25; // 玩家初始攻击力
const int INIT_MONSTER_HP = 60; // 怪物初始生命值
const int INIT_MONSTER_ATK = 12; // 怪物初始攻击力
const int ATTACK_RANGE = 2; // 攻击范围(曼哈顿距离)
const int MONSTER_COUNT = 4; // 初始怪物数量
// 角色类(玩家)
class Role {
private:
std::string name; // 角色名称
int level; // 等级
int hp; // 当前生命值
int maxHp; // 最大生命值
int atk; // 攻击力
int x, y; // 坐标(x:横向,y:纵向)
public:
// 构造函数:初始化角色
Role(const std::string& name, int x, int y)
: name(name), level(1), hp(INIT_PLAYER_HP), maxHp(INIT_PLAYER_HP),
atk(INIT_PLAYER_ATK), x(x), y(y) {}
// 移动:dx=横向偏移(-1左/1右),dy=纵向偏移(-1上/1下)
bool move(int dx, int dy, const class Map& map);
// 攻击怪物
void attack(class Monster& monster);
// 受伤害
void takeDamage(int damage);
// 显示角色状态
void showStatus() const;
// 获取坐标
int getX() const { return x; }
int getY() const { return y; }
// 检查是否存活
bool isAlive() const { return hp > 0; }
// 获取攻击力
int getAtk() const { return atk; }
std::string getName() const { return name; }
};
// 怪物类
class Monster {
private:
std::string name; // 怪物名称
int hp; // 当前生命值
int maxHp; // 最大生命值
int atk; // 攻击力
int x, y; // 坐标
bool alive; // 是否存活
public:
// 构造函数:初始化怪物
Monster(const std::string& name, int x, int y)
: name(name), hp(INIT_MONSTER_HP), maxHp(INIT_MONSTER_HP),
atk(INIT_MONSTER_ATK), x(x), y(y), alive(true) {}
// 攻击玩家
void attack(Role& role);
// 受伤害
void takeDamage(int damage);
// 随机移动(避开障碍物和玩家)
void randomMove(const class Map& map);
// 显示怪物状态
void showStatus() const;
// 获取坐标
int getX() const { return x; }
int getY() const { return y; }
// 检查是否存活
bool isAlive() const { return alive; }
std::string getName() const { return name; }
int getAtk() const { return atk; }
};
// 地图类
class Map {
private:
std::vector<std::vector<char>> grid; // 地图网格
std::vector<Monster> monsters; // 地图上的怪物
int playerX, playerY; // 玩家当前位置
public:
// 构造函数:初始化地图地形
Map() {
// 初始化网格为平地(.)
grid.resize(MAP_HEIGHT, std::vector<char>(MAP_WIDTH, '.'));
// 设置边界障碍物(#)
for (int i = 0; i < MAP_HEIGHT; ++i) {
grid[i][0] = '#';
grid[i][MAP_WIDTH - 1] = '#';
}
for (int j = 0; j < MAP_WIDTH; ++j) {
grid[0][j] = '#';
grid[MAP_HEIGHT - 1][j] = '#';
}
// 设置中间障碍物(迷宫效果)
grid[3][4] = grid[3][5] = grid[3][6] = '#';
grid[6][10] = grid[7][10] = grid[8][10] = '#';
grid[5][2] = grid[6][2] = grid[7][2] = '#';
}
// 初始化玩家位置(避开障碍物)
void initPlayerPos(Role& player) {
// 地图中心附近生成玩家
playerX = MAP_WIDTH / 2;
playerY = MAP_HEIGHT / 2;
// 确保初始位置是平地且无障碍物
while (grid[playerY][playerX] != '.') {
playerX = rand() % (MAP_WIDTH - 2) + 1;
playerY = rand() % (MAP_HEIGHT - 2) + 1;
}
player = Role("传奇勇士", playerX, playerY);
}
// 生成怪物(随机位置,避开障碍物、玩家)
void spawnMonsters(int count) {
for (int i = 0; i < count; ++i) {
int x, y;
// 循环生成合法位置(平地+无占用)
do {
x = rand() % (MAP_WIDTH - 2) + 1;
y = rand() % (MAP_HEIGHT - 2) + 1;
} while (grid[y][x] != '.' || isPosOccupied(x, y));
monsters.emplace_back("黑野猪" + std::to_string(i + 1), x, y);
}
}
// 检查坐标是否被占用(玩家或存活怪物)
bool isPosOccupied(int x, int y) const {
if (x == playerX && y == playerY) return true;
for (const auto& monster : monsters) {
if (monster.isAlive() && monster.getX() == x && monster.getY() == y) {
return true;
}
}
return false;
}
// 检查坐标是否合法(在地图内+非障碍物)
bool isPosValid(int x, int y) const {
return x >= 0 && x < MAP_WIDTH && y >= 0 && y < MAP_HEIGHT && grid[y][x] == '.';
}
// 更新玩家位置到地图
void updatePlayerPos(const Role& player) {
playerX = player.getX();
playerY = player.getY();
}
// 怪物随机移动更新
void updateMonsters() {
for (auto& monster : monsters) {
if (monster.isAlive()) {
monster.randomMove(*this);
}
}
}
// 查找玩家附近可攻击的怪物(最近优先)
Monster* findAttackableMonster(const Role& player) {
int px = player.getX();
int py = player.getY();
Monster* target = nullptr;
int minDist = ATTACK_RANGE + 1; // 初始距离超过攻击范围
for (auto& monster : monsters) {
if (!monster.isAlive()) continue;
// 计算曼哈顿距离:|x1-x2| + |y1-y2|
int dist = abs(monster.getX() - px) + abs(monster.getY() - py);
if (dist <= ATTACK_RANGE && dist < minDist) {
minDist = dist;
target = &monster;
}
}
return target;
}
// 渲染地图(显示玩家、怪物、地形)
void display(const Role& player) const {
system("cls"); // Windows清屏(Linux/macOS替换为 "clear")
std::cout << "===== 传奇游戏地图 =====" << std::endl;
for (int y = 0; y < MAP_HEIGHT; ++y) {
for (int x = 0; x < MAP_WIDTH; ++x) {
// 显示玩家(P)
if (x == player.getX() && y == player.getY()) {
std::cout << "P ";
}
// 显示存活怪物(M)
else {
bool isMonster = false;
for (const auto& monster : monsters) {
if (monster.isAlive() && monster.getX() == x && monster.getY() == y) {
std::cout << "M ";
isMonster = true;
break;
}
}
// 显示地形(障碍物# / 平地.)
if (!isMonster) {
std::cout << grid[y][x] << " ";
}
}
}
std::cout << std::endl;
}
std::cout << "========================" << std::endl;
}
// 获取所有怪物(供主循环判断是否通关)
const std::vector<Monster>& getMonsters() const { return monsters; }
};
// ------------------------------ 角色类方法实现 ------------------------------
bool Role::move(int dx, int dy, const Map& map) {
int newX = x + dx;
int newY = y + dy;
// 检查位置是否合法(非障碍物+无占用)
if (map.isPosValid(newX, newY) && !map.isPosOccupied(newX, newY)) {
x = newX;
y = newY;
return true;
}
std::cout << "❌ 无法移动!前方有障碍物或其他单位" << std::endl;
return false;
}
void Role::attack(Monster& monster) {
if (!monster.isAlive()) {
std::cout << "❌ 攻击无效!目标已死亡" << std::endl;
return;
}
// 玩家攻击怪物
std::cout << "\n⚔️ " << name << " 攻击了 " << monster.getName() << ",造成 " << atk << " 点伤害!" << std::endl;
monster.takeDamage(atk);
// 怪物存活则反击
if (monster.isAlive()) {
monster.attack(*this);
} else {
std::cout << "✅ " << monster.getName() << " 被击败!" << std::endl;
}
}
void Role::takeDamage(int damage) {
hp -= damage;
if (hp < 0) hp = 0;
std::cout << "💥 " << name << " 受到 " << damage << " 点伤害,剩余生命值:" << hp << std::endl;
if (!isAlive()) {
std::cout << "💀 " << name << " 生命值耗尽,游戏结束!" << std::endl;
}
}
void Role::showStatus() const {
std::cout << "\n【角色状态】" << std::endl;
std::cout << "姓名:" << name << " | 等级:" << level << std::endl;
std::cout << "生命值:" << hp << "/" << maxHp << " | 攻击力:" << atk << std::endl;
std::cout << "当前位置:(" << x << "," << y << ")" << std::endl;
}
// ------------------------------ 怪物类方法实现 ------------------------------
void Monster::attack(Role& role) {
std::cout << "🐗 " << name << " 发起反击,对 " << role.getName() << " 造成 " << atk << " 点伤害!" << std::endl;
role.takeDamage(atk);
}
void Monster::takeDamage(int damage) {
hp -= damage;
if (hp <= 0) {
hp = 0;
alive = false;
}
}
void Monster::randomMove(const Map& map) {
// 四个移动方向(上、下、左、右)
int dirs[4][2] = {{0, -1}, {0, 1}, {-1, 0}, {1, 0}};
int randDir = rand() % 4; // 随机选择方向
int newX = x + dirs[randDir][0];
int newY = y + dirs[randDir][1];
// 位置合法则移动
if (map.isPosValid(newX, newY) && !map.isPosOccupied(newX, newY)) {
x = newX;
y = newY;
}
}
void Monster::showStatus() const {
std::cout << "\n【怪物状态】" << std::endl;
std::cout << "名称:" << name << " | 状态:" << (alive ? "存活" : "死亡") << std::endl;
std::cout << "生命值:" << hp << "/" << maxHp << " | 攻击力:" << atk << std::endl;
std::cout << "当前位置:(" << x << "," << y << ")" << std::endl;
}
// ------------------------------ 主函数(游戏流程) ------------------------------
int main() {
// 初始化随机数种子(确保怪物位置/移动随机)
srand(static_cast<unsigned int>(time(NULL)));
// 游戏欢迎界面
std::cout << "===== 🔥 传奇游戏 C++ 简化版 🔥 =====" << std::endl;
std::cout << "📜 操作说明:" << std::endl;
std::cout << "W - 向上 | S - 向下 | A - 向左 | D - 向右(移动)" << std::endl;
std::cout << "空格 - 攻击(附近怪物) | T - 显示详细状态 | Q - 退出游戏" << std::endl;
std::cout << "=====================================" << std::endl;
system("pause"); // 暂停等待用户开始
// 初始化游戏资源
Map gameMap; // 创建地图
Role player("", 0, 0); // 创建玩家(后续初始化位置)
gameMap.initPlayerPos(player); // 初始化玩家位置
gameMap.spawnMonsters(MONSTER_COUNT); // 生成怪物
// 游戏主循环
char input;
bool gameOver = false;
while (!gameOver) {
// 1. 渲染地图和角色状态
gameMap.display(player);
player.showStatus();
// 2. 检查是否通关(所有怪物死亡)
bool allMonstersDead = true;
for (const auto& monster : gameMap.getMonsters()) {
if (monster.isAlive()) {
allMonstersDead = false;
break;
}
}
if (allMonstersDead) {
std::cout << "\n🎉 恭喜!所有怪物已被击败,你通关了!" << std::endl;
gameOver = true;
break;
}
// 3. 接收用户输入
std::cout << "\n请输入操作:";
std::cin >> input;
input = toupper(input); // 转为大写,兼容小写输入
// 4. 处理用户输入
switch (input) {
case 'W': // 上移(y-1)
player.move(0, -1, gameMap);
gameMap.updatePlayerPos(player);
break;
case 'S': // 下移(y+1)
player.move(0, 1, gameMap);
gameMap.updatePlayerPos(player);
break;
case 'A': // 左移(x-1)
player.move(-1, 0, gameMap);
gameMap.updatePlayerPos(player);
break;
case 'D': // 右移(x+1)
player.move(1, 0, gameMap);
gameMap.updatePlayerPos(player);
break;
case ' ': // 攻击(空格)
{
Monster* target = gameMap.findAttackableMonster(player);
if (target) {
player.attack(*target);
} else {
std::cout << "❌ 附近没有可攻击的怪物!" << std::endl;
}
system("pause"); // 暂停查看战斗结果
break;
}
case 'T': // 显示详细状态(角色+所有怪物)
player.showStatus();
for (const auto& monster : gameMap.getMonsters()) {
monster.showStatus();
}
system("pause");
break;
case 'Q': // 退出游戏
std::cout << "👋 感谢游玩,再见!" << std::endl;
gameOver = true;
break;
default: // 无效输入
std::cout << "❌ 无效操作,请重新输入!" << std::endl;
system("pause");
break;
}
// 5. 检查玩家是否死亡
if (!player.isAlive()) {
gameOver = true;
break;
}
// 6. 怪物随机移动(每回合更新)
gameMap.updateMonsters();
}
system("pause");
return 0;
}