玩法规则:

这篇博客介绍一个控制台输出的以探险为主题的小游戏,是文字形式的回合制游戏。

游戏开始后,玩家控制随机的7名冒险者,他们分为由四种职业,每个职业有不同的炫酷技能:

C++练习实例———探险者联盟-LMLPHP

七名冒险者在20个关卡中前进,每个关卡都有可能遭遇怪兽,怪物的数量和种类是完全随机的,种类分为五种:

      C++练习实例———探险者联盟-LMLPHP

(其实这个游戏的自由发挥空间非常大,以上这些角色都是现编的,可以随便改)

当冒险家受到近距离攻击时,下个回合就只能用近距离攻击来反击,这是法师的软肋。每通过一个关卡,都会有随机奖励,比如增强血量上限的药水等。在没有怪物的关卡就什么都不会发生(其实可以加一些偶遇商店什么的,我没加),通过所有关卡就通关了,就这么简单。

 

代码:

该游戏主要是玩法逻辑比较麻烦,架构的思路很清晰,如下:

C++练习实例———探险者联盟-LMLPHP

下面上代码。

首先是Creature类,游戏中的所有游戏对象都会继承自它:

#include<iostream>
#include <vector>
using namespace std;

#ifndef CREATURE_H
#define CREATURE_H

class Creature
{
protected:
	int m_id;//编号
	int m_maxhp;//最大血量
	int m_curhp;//目前血量
	int m_armor;//护甲值
	int m_basedamage;//基础伤害
public:
	Creature(){}
	virtual ~Creature(){}

	void BeDamaged(const int damage)
	{
		int delta(damage);
		if (m_armor > 0)
		{
			if (damage < m_armor)
			{
				m_armor -= damage;
				return;
			}
			else
			{
				delta = damage - m_armor;
				m_armor = 0;
			}
		}

		if(m_curhp>0)
		m_curhp -= delta;
     }
	int ReturnRandom() const{return (rand() % 5);}
	void AddArmor(const int armor) {m_armor += armor;}
	int GetHp()const { return m_curhp; }
	int GetBaseDamage()const { m_basedamage; }
	int GetId() const{ return m_id; }
};
#endif

然后是冒险者基类和怪物基类,继承自生物类。

 Adventurer类:

#include <string.h>
#include "Creature.h"

#ifndef ADVENTURE_H
#define ADVENTURE_H

enum AdventureType
{
	Warriors,
	Rogues,
	OffensiveMages,
	DefensiveMages,
};

class Adventurer:public Creature
{
protected:
	AdventureType m_type;
	string m_name;
	int m_age;
	int m_money;
	bool m_isattackedbyclose;
public:
	Adventurer(int basedamage,string name,int age,AdventureType type,int id)
	:m_name(name),m_age(age),m_type(type)
	{
		m_basedamage = basedamage;
		m_id = id;
		m_maxhp = 100;
		m_curhp = m_maxhp;
		m_armor = 0;
		m_money = 0;
		m_isattackedbyclose = false;
	}
	virtual ~Adventurer(){}

	virtual void CloseAttack(Creature&one) = 0;
	virtual void DistanceAttackNoMp(Creature&a){}
	virtual bool DistanceMagic(Creature&a) { return false; }
	virtual bool DistanceMagic(Creature&a, Creature&b) { return false; }
	virtual bool DistanceMagic(Creature&a, Creature&b, Creature&c) { return false; }
	virtual void MpRestore(){}

	AdventureType ReturnType() const{ return m_type; }//返回该冒险者的类型
	void HpRestore() { m_curhp =m_maxhp; }
	void AddMaxHp(int delta)
	{
		m_maxhp += delta;
		m_curhp = m_maxhp;
	}
	string GetName()const { return m_name; }
	int GetAge()const { return m_age; }
	int GetMoney()const { return m_money; }
	void AddMoney(const int delta) { m_money += delta; }
	void AddBaseDamaged(const int delta) { m_basedamage += delta; }
	bool IsAttackedByClose() { return m_isattackedbyclose; }
	void SetAttackedByClose(bool attacked) { m_isattackedbyclose = attacked; }
	int GetArmor() { return m_armor; }
};
#endif

Monster类:

#include <string.h>
#include "Creature.h"

#ifndef MONSTER_H
#define MONSTER_H

enum MonsterType
{
	TIGER,
	EAGLE,
	WITCH,
	MUMMY,
	DRAGON,
};

class Monster :public Creature
{
protected:
	MonsterType m_type;

public:
	Monster(int basedamage, MonsterType type,int id):m_type(type)
	{
		m_id = id;
		m_basedamage = basedamage;
		m_maxhp = 100;
		m_curhp = m_maxhp;
		m_armor = 0;
	}
	virtual ~Monster() {}

	virtual void CloseAttack(Creature&one) = 0;
	virtual void DistanceAttackNoMp(Creature&a) {}
	virtual bool DistanceMagic(Creature&a) { return false; }
	virtual bool DistanceMagic(Creature&a, Creature&b) { return false; }
	virtual bool DistanceMagic(Creature&a, Creature&b, Creature&c) { return false; }
	virtual void KillSky(vector<Adventurer*>&all){}
	virtual bool IsUsedKS() const { return false; }

	MonsterType ReturnType() const { return m_type; }//返回该怪兽的类型
	void AddHp(int delta)
	{
	   m_curhp += delta;
	   if (m_curhp > m_maxhp)m_curhp = m_maxhp;
	}
};
#endif

在冒险者基类的基础上,创建四个不同职业的冒险者类:

#include "Adventurer.h"

#ifndef WARRIOR_H
#define WARRIOR_H

class Warrior:public Adventurer
{
public:
	Warrior( string name, int age,int id):
		Adventurer(23, name, age, Warriors,id)
	{}
	~Warrior() {}

	//近距离攻击
	void  CloseAttack(Creature&one)
	{
		one.BeDamaged(m_basedamage + ReturnRandom());
	}
};
#endif 
#include "Adventurer.h"

#ifndef ROGUE_H
#define ROGUE_H

class Rogue :public Adventurer
{
private:
	int m_distancedamage;

public:
	Rogue(string name, int age,int id):
		Adventurer(15, name, age, Rogues,id),m_distancedamage(17)
	{}
	~Rogue() {}

	//盗贼近距离攻击可吸血
	void  CloseAttack(Creature&one)
	{
		one.BeDamaged(m_basedamage + ReturnRandom());
		m_curhp += m_basedamage;
		cout << "吸取" << m_basedamage << "点血量!" << endl;
		if (m_curhp > m_maxhp)m_curhp = m_maxhp;
	}
	//远距离无蓝攻击
	void DistanceAttackNoMp(Creature&one)
	{
		one.BeDamaged(m_distancedamage + ReturnRandom());
	}
};
#endif 
#include "Adventurer.h"

#ifndef OFFENSIVEMAGE_H
#define OFFENSIVEMAGE_H

class OffensiveMage :public Adventurer
{
private:
	int m_distancedamage;
	int m_maxmp;
	int m_curmp;

public:
	OffensiveMage(string name, int age,int id) :
		Adventurer(7, name, age, OffensiveMages,id), m_distancedamage(27), m_maxmp(100), m_curmp(m_maxmp)
	{}
	~OffensiveMage() {}

	//近距离攻击
	void  CloseAttack(Creature&a)
	{
		a.BeDamaged(m_basedamage + ReturnRandom());
	}
	//远距离无蓝攻击
	void DistanceAttackNoMp(Creature&a)
	{
		a.BeDamaged(m_basedamage + ReturnRandom());
	}
	//魔法攻击
	bool DistanceMagic(Creature&a)
	{
		if (m_curmp >= 20)
		{
			a.BeDamaged(m_distancedamage + ReturnRandom());
			m_curmp -= 20;
			cout << "剩余mp值:" << m_curmp << endl;
			return true;
		}
		else return false;
	}
	bool DistanceMagic(Creature&a, Creature&b)
	{
		if (m_curmp >= 40)
		{
			a.BeDamaged(m_distancedamage + ReturnRandom());
			b.BeDamaged(m_distancedamage + ReturnRandom());
			m_curmp -= 40;
			cout << "剩余mp值:" << m_curmp << endl;
			return true;
		}
		else return false;
	}
	bool DistanceMagic(Creature&a, Creature&b, Creature&c)
	{
		if (m_curmp >= 60)
		{
			a.BeDamaged(m_distancedamage + ReturnRandom());
			b.BeDamaged(m_distancedamage + ReturnRandom());
			c.BeDamaged(m_distancedamage + ReturnRandom());
			m_curmp -= 60;
			cout << "剩余mp值:" << m_curmp << endl;
			return true;
		}
		else return false;
	}

	void MpRestore() { m_curmp = m_maxmp; }
};
#endif 
#include "Adventurer.h"

#ifndef	DEFENSIVEMAGE_H
#define DEFENSIVEMAGE_H

class DefensiveMage :public Adventurer
{
private:
	int m_gain;
	int m_maxmp;
	int m_curmp;
public:
	DefensiveMage(string name, int age,int id) :
		Adventurer(7, name, age, DefensiveMages,id), m_gain(24), m_maxmp(100), m_curmp(m_maxmp)
	{}
	~DefensiveMage(){}

	//近距离攻击
	void  CloseAttack(Creature&a)
	{
		a.BeDamaged(m_basedamage + ReturnRandom());
	}
	//远距离无蓝攻击
	void DistanceAttackNoMp(Creature&a)
	{
		a.BeDamaged(m_basedamage+ReturnRandom());
	}
	//魔法增益
	bool DistanceMagic(Creature&a)
	{
		if (m_curmp >= 20)
		{
			a.AddArmor(m_gain);
			m_curmp -= 20;
			cout << "剩余mp值:" << m_curmp << endl;
			return true;
		}
		else return false;
	}
	bool DistanceMagic(Creature&a, Creature&b)
	{
		if (m_curmp >= 40)
		{
			a.AddArmor(m_gain);
			b.AddArmor(m_gain);
			m_curmp -= 40;
			cout << "剩余mp值:" << m_curmp << endl;
			return true;
		}
		else return false;
	}
	bool DistanceMagic(Creature&a, Creature&b, Creature&c)
	{
		if (m_curmp >= 60)
		{
			a.AddArmor(m_gain);
			b.AddArmor(m_gain);
			c.AddArmor(m_gain);
			m_curmp -= 60;
			cout << "剩余mp值:" << m_curmp << endl;
			return true;
		}
		else return false;
	}

	void MpRestore() { m_curmp = m_maxmp; }
};
#endif

然后是五个具体的怪物类,继承自怪物基类:

#include "Monster.h"

#ifndef TIGER_H
#define TIGER_H

class Tiger :public Monster
{
public:
	Tiger(int id):Monster(20,TIGER,id){}
	~Tiger() {}

	void  CloseAttack(Creature&one) //近距离攻击
	{
		one.BeDamaged(m_basedamage + ReturnRandom());
	}
};
#endif 
#include "Monster.h"

#ifndef EAGLE_H
#define EAGLE_H

class Eagle :public Monster
{
private:
	int m_distancedamage;

public:
	Eagle(int id) :Monster(15,EAGLE,id), m_distancedamage(20){}
	~Eagle() {}

	//近距离攻击
	void  CloseAttack(Creature&one)
	{
		one.BeDamaged(m_basedamage + ReturnRandom());
	}
	//远距离无蓝攻击
	void DistanceAttackNoMp(Creature&a)
	{
		a.BeDamaged(m_distancedamage + ReturnRandom());
	}
};
#endif 
#include "Monster.h"

#ifndef WITCH_H
#define WITCH_H

class Witch :public Monster
{
private:
	int m_distancedamage;
	int m_maxmp;
	int m_curmp;

public:
	Witch(int id) :
		Monster(5, WITCH,id), m_distancedamage(27),m_maxmp(100),m_curmp(m_maxmp)
	{}
	~Witch() {}

	//近距离攻击
	void  CloseAttack(Creature&a)
	{
		a.BeDamaged(m_basedamage + ReturnRandom());
	}
	//远距离无蓝攻击
	void DistanceAttackNoMp(Creature&a)
	{
		a.BeDamaged(m_basedamage + ReturnRandom());
	}
	//魔法攻击(可吸血)
	bool DistanceMagic(Creature&a)
	{
		if (m_curmp >= 20)
		{
			a.BeDamaged(m_distancedamage + ReturnRandom());
			m_curmp -= 20;
			AddHp(10);
			cout << "吸取10点生命值!剩余mp值:" << m_curmp << endl;
			return true;
		}
		else return false;
	}
	bool DistanceMagic(Creature&a, Creature&b)
	{
		if (m_curmp >= 40)
		{
			a.BeDamaged(m_distancedamage + ReturnRandom());
			b.BeDamaged(m_distancedamage + ReturnRandom());
			m_curmp -= 40;
			AddHp(15);
			cout << "吸取15点生命值!剩余mp值:" << m_curmp << endl;
			return true;
		}
		else return false;
	}
	bool DistanceMagic(Creature&a, Creature&b, Creature&c)
	{
		if (m_curmp >= 60)
		{
			a.BeDamaged(m_distancedamage + ReturnRandom());
			b.BeDamaged(m_distancedamage + ReturnRandom());
			c.BeDamaged(m_distancedamage + ReturnRandom());
			m_curmp -= 60;
			AddHp(20);
			cout << "吸取20点生命值!剩余mp值:" << m_curmp << endl;
			return true;
		}
		else return false;
	}
};
#endif 
#include "Monster.h"

#ifndef MUMMY_H
#define MUMMY_H

class Mummy :public Monster
{
public:
	Mummy(int id) :Monster(25, MUMMY,id){}
	~Mummy() {}

	//近距离攻击(吸血)
	void  CloseAttack(Creature&one)
	{
		one.BeDamaged(m_basedamage + ReturnRandom());
		AddHp(m_basedamage);
		cout << "吸取" << m_basedamage << "点生命值!" << endl;
	}
};
#endif 
#include "Monster.h"

#ifndef DRAGON_H
#define DRAGON_H

class Dragon :public Monster
{
private:
	int m_distancedamage;
	bool usedKS;
public:
	Dragon(int id) :
		Monster(18,DRAGON,id), m_distancedamage(22),usedKS(false)
	{}
	~Dragon() {}

	//近距离攻击
	void  CloseAttack(Creature&a)
	{
		a.BeDamaged(m_basedamage + ReturnRandom());
	}
	//远距离攻击
	void DistanceAttackNoMp(Creature&a)
	{
		a.BeDamaged(m_distancedamage + ReturnRandom());
	}
	//毁天灭地
	void KillSky(vector<Adventurer*>&all)
	{
		for (auto val : all)
		{
			val->BeDamaged(40);
		}
		usedKS = true;
	}
	bool IsUsedKS() const{ return usedKS; }

};
#endif 

最后是GameManager类,核心的玩法逻辑都集中在这里,比较繁琐:

头文件:

#include "Mummy.h"
#include "OffensiveMage.h"
#include "Rogue.h"
#include "Tiger.h"
#include "Warrior.h"
#include "Witch.h"
#include <vector>
#include <fstream>
#include<string>

#ifndef GAMEMANAGER_H
#define GameManager_H

class GameManager
{
private:
	int m_totallevel;
	int m_curlevel;
	int m_encounterprob;

	vector<Adventurer*>m_adventurers;
	vector<Monster*> m_monsters;
	vector<string> m_names;

	//构造函数,主要用来初始化冒险家容器(单例模式,构造为私有)
	GameManager()
	{
		m_names = { "Herbert","Baron","Theodore","Darren","Marshall","Maxwell","Jason","William","Alan" };

		m_curlevel = 1;
		m_totallevel = 20;
		m_encounterprob = 30;//百分之30的几率遭遇怪兽
		m_adventurers.push_back(new Warrior(ReturnName(), ReturnAge(), 1));
		m_adventurers.push_back(new Rogue(ReturnName(), ReturnAge(), 2));
		m_adventurers.push_back(new OffensiveMage(ReturnName(), ReturnAge(), 3));
		m_adventurers.push_back(new DefensiveMage(ReturnName(), ReturnAge(), 4));

		for (int i = 0; i < 3; i++)
		{
			int choice = ReturnRandom(4);
			if (choice == 1)m_adventurers.push_back(new Warrior(ReturnName(), ReturnAge(), 5 + i));
			if (choice == 2)m_adventurers.push_back(new Rogue(ReturnName(), ReturnAge(), 5 + i));
			if (choice == 3)m_adventurers.push_back(new OffensiveMage(ReturnName(), ReturnAge(), 5 + i));
			if (choice == 4)m_adventurers.push_back(new DefensiveMage(ReturnName(), ReturnAge(), 5 + i));
		}
	}

public:

	static GameManager* GetInstance();//单例模式

	~GameManager()
	{
		m_adventurers.clear();
		m_monsters.clear();
	}

	//随机获取1到max的一个数
	int ReturnRandom(const int max)const
	{
		return (rand() % max) + 1;
	}
	//获得一个随机年龄
	int ReturnAge()const
	{
		return 18 + ReturnRandom(10);
	}
	//获得一个随机名字
	string ReturnName()
	{
		int i = ReturnRandom(m_names.size()) - 1;
		string name = m_names[i];
		m_names.erase(m_names.begin() + i);
		return name;
	}
	//判断是否遭遇了怪兽
	bool IsEncounter()
	{
		int n = ReturnRandom(100);
		if (n <= m_encounterprob)return true;
		else return false;
	}
	//从文件中读取怪兽的描述
	void OutPutInstructionFromFile();
	//刷新存储怪物的容器
	void GenerateMonster();
	//令冒险者依次攻击
	void EveryAdventureAttack();
	//令怪兽依次攻击
	void EveryMonsterAttack();
	//由id获得在容器中的索引
	int FindIndexForMonster(const int id)const
	{
		for (int i = 0; i < m_monsters.size(); i++)
		{
			if (m_monsters[i]->GetId() == id)
				return i;
		}
		return -1;
	}
	int FindIndexForAd(const int id)const
	{
		for (int i = 0; i < m_adventurers.size(); i++)
		{
			if (m_adventurers[i]->GetId() == id)
				return i;
		}
		return -1;
	}
	//伤害结算
	void DeadSettleForAd(const int index)
	{
		if (m_adventurers[index]->GetHp() <= 0)//冒险者死亡,从容器中直接删除
		{
			cout << m_adventurers[index]->GetId() << "号冒险家" << m_adventurers[index]->GetName() << "死亡!" << endl;
			m_adventurers.erase(m_adventurers.begin() + index);
		}
		else cout << m_adventurers[index]->GetId() << "号冒险家的血量还剩:" << m_adventurers[index]->GetHp() << endl;
	}
	void DeadSettleForMonster(const int index)
	{
		if (m_monsters[index]->GetHp() <= 0)//怪物死亡,从容器中直接删除
		{
			cout << m_monsters[index]->GetId() << "号怪兽死亡!" << endl;
			m_monsters.erase(m_monsters.begin() + index);
		}
		else cout << m_monsters[index]->GetId()<< "号怪物的血量还剩:" << m_monsters[index]->GetHp() << endl;
	}
	//过关奖励
	void PassReward();
	void Start();
};

#endif // !GAMEMANAGER_H

cpp文件:

#include "GameManager.h"
 GameManager * GameManager::GetInstance()
 {
	 static GameManager instance;
	 return &instance;
 }

 void GameManager::OutPutInstructionFromFile()
{
	char line[1024] = { 0 };
	ifstream fin("data.txt");
	if (!fin)
	{
		cout << "no data.txt!" << endl;
		return;
	}
	if (fin.fail())//如果文件为空
	{
		cout << "file is empty!" << endl;
		return;
	}
	do {
		fin.getline(line, sizeof(line));
		cout << line << endl;
	} while (!fin.eof());

	fin.close();
	return;
}

void GameManager::GenerateMonster()
{
	m_monsters.clear();

	int n = ReturnRandom(4) - 1;
	for (int i = 0; i < n; i++)
		m_monsters.push_back(new Tiger(m_monsters.size() + 1));

	n = ReturnRandom(4) - 1;
	for (int i = 0; i < n; i++)
		m_monsters.push_back(new Eagle(m_monsters.size() + 1));

	n = ReturnRandom(3) - 1;
	for (int i = 0; i < n; i++)
		m_monsters.push_back(new Witch(m_monsters.size() + 1));

	n = ReturnRandom(3) - 1;
	for (int i = 0; i < n; i++)
		m_monsters.push_back(new Mummy(m_monsters.size() + 1));

	n = ReturnRandom(2) - 1;
	for (int i = 0; i < n; i++)
		m_monsters.push_back(new Dragon(m_monsters.size() + 1));
}

void GameManager::EveryAdventureAttack()
{
	for (auto var : m_adventurers)
	{
		if (var->ReturnType() == Warriors)
		{
			while (1)
			{
				cout << var->GetId() << "号冒险者" << var->GetName() << "是一个warrior,他的技能有:1.近身攻击" << endl;
				int skill(1);
				cout << "输入你想让他使用的技能序号:";
				cin >> skill;//这里从c1实际没用到,因为warrior只有一个技能
				cout << "对几号怪物使用:" << endl;
				int  m(0);
				cin >> m;

				int i = FindIndexForMonster( m);
				if (i != -1)//找到了该号怪兽
				{
					var->CloseAttack(*m_monsters[i]);

					cout << "出击!!!" << endl;

					DeadSettleForMonster( i);
					break;
				}
				else cout << "不存在该号怪物,出击失败,请重新选择" << endl;
			}
			if (m_monsters.size() == 0)break;
		}
		if (var->ReturnType() == Rogues)
		{
			while (1)
			{
				cout << var->GetId() << "号冒险者" << var->GetName() << "是一个Rogue,他的技能有:1.近身攻击 2.远程攻击" << endl;
				int skill(1);
				if (var->IsAttackedByClose())
				{
					cout << "但他此刻被近身攻击了,只能用近身攻击反击!" << endl;
				}
				else
				{
					cout << "输入你想让他使用的技能序号:";
					cin >> skill;
				}
				cout << "对几号怪物使用:" << endl;
				int m(0);
				cin >> m;

				int i = FindIndexForMonster( m);
				if (i != -1)//找到了该号怪兽
				{
					if (skill == 1)
						var->CloseAttack(*m_monsters[i]);
					if (skill == 2)
						var->DistanceAttackNoMp(*m_monsters[i]);

					cout << "出击!!!" << endl;
					var->SetAttackedByClose(false);

					DeadSettleForMonster(i);
					break;
				}
				else cout << "不存在该号怪物,出击失败,请重新选择" << endl;
			}
			if (m_monsters.size() == 0)break;
		}
		if (var->ReturnType() == OffensiveMages)
		{
			while (1)
			{
				cout << var->GetId() << "号冒险者" << var->GetName() << "是一个OffensiveMage,他的技能有:1.近身攻击 2.远程攻击 3.魔法:火焰冲击 4.魔法:火焰双枪 5.魔法:火焰三重奏" << endl;
				int skill(1);
				if (var->IsAttackedByClose())
				{
					cout << "但他此刻被近身攻击了,只能用近身攻击反击!" << endl;
					var->SetAttackedByClose(false);
				}
				else
				{
					cout << "输入你想让他使用的技能序号:";
					cin >> skill;
				}
				if (skill == 1 || skill == 2 || skill == 3)//选择单体目标
				{
					cout << "对几号怪物使用:" << endl;
					int m(0);
					cin >> m;

					int i = FindIndexForMonster( m);
					if (i != -1)//找到了该号怪兽
					{
						if (skill == 1)var->CloseAttack(*m_monsters[i]);
						if (skill == 2)var->DistanceAttackNoMp(*m_monsters[i]);
						if (skill == 3)
						{
							if (!var->DistanceMagic(*m_monsters[i]))//攻击失败
							{
								cout << "魔法值不够!请重新选择" << endl;
								continue;
							}
						}
						cout << "出击!!!" << endl;
						var->SetAttackedByClose(false);

						DeadSettleForMonster(i);
						break;
					}
					else cout << "不存在该号怪物,请重新选择" << endl;
				}
				if (skill == 4)
				{
					cout << "选择两个怪物的序号(从小到大):" << endl;
					int m1(0), m2(0);
					cin >> m1 >> m2;

					int i = FindIndexForMonster( m1);
					int i2 = FindIndexForMonster( m2);
					if (i != -1 && i2 != -1)//找到了这两个怪兽
					{
						if (!var->DistanceMagic(*m_monsters[i], *m_monsters[i2]))//若攻击失败
						{
							cout << "魔法值不够!请重新选择" << endl;
							continue;
						}

						cout << "出击!!!" << endl;
						var->SetAttackedByClose(false);

						DeadSettleForMonster( i2);
						DeadSettleForMonster( i);

						break;
					}
					else cout << "有怪物不存在,请重新选择" << endl;
				}
				if (skill == 5)
				{
					cout << "选择三个怪物的序号(从小到大):" << endl;
					int m1(0), m2(0), m3(0);
					cin >> m1 >> m2 >> m3;

					int i = FindIndexForMonster(m1);
					int i2 = FindIndexForMonster( m2);
					int i3 = FindIndexForMonster(m3);
					if (i != -1 && i2 != -1 && i3 != -1)//找到了这三个怪兽
					{
						if (!var->DistanceMagic(*m_monsters[i], *m_monsters[i2], *m_monsters[i3]))//攻击失败
						{
							cout << "魔法值不够!请重新选择" << endl;
							continue;
						}

						cout << "出击!!!" << endl;
						var->SetAttackedByClose(false);

						DeadSettleForMonster(i3);
						DeadSettleForMonster(i2);
						DeadSettleForMonster(i);//注意,这里i3 i2和i的顺序不能变,一定要倒着

						break;
					}
					else cout << "有怪物不存在,请重新选择" << endl;
				}
			}
			if (m_monsters.size() == 0)break;
		}
		if (var->ReturnType() == DefensiveMages)
		{
			while (1)
			{
				cout << var->GetId() << "号冒险者" << var->GetName() << "是一个DefensiveMage,他的技能有:1.近身攻击 2.远程攻击 3.魔法:精准保护 4.魔攻:双人联护 5.魔攻:铜墙铁壁" << endl;
				int skill(1);
				if (var->IsAttackedByClose())
				{
					cout << "但他此刻被近身攻击了,只能用近身攻击反击!" << endl;
					var->SetAttackedByClose(false);
				}
				else
				{
					cout << "输入你想让他使用的技能序号:";
					cin >> skill;
				}
				if (skill == 1 || skill == 2)//选择单体目标
				{
					cout << "对几号怪物使用:" << endl;
					int m(0);
					cin >> m;

					int i = FindIndexForMonster( m);
					if (i != -1)//找到了该号怪兽
					{
						if (skill == 1)var->CloseAttack(*m_monsters[i]);
						if (skill == 2)var->DistanceAttackNoMp(*m_monsters[i]);

						cout << "出击!!!" << endl;
						var->SetAttackedByClose(false);

						DeadSettleForMonster(i);
						break;
					}
					else if (i == -1)cout << "不存在该号怪物,请重新选择" << endl;
				}
				if (skill == 3)
				{
					cout << "对几号冒险者使用:" << endl;
					int m(0);
					cin >> m;

					int i = FindIndexForAd( m);
					if (i != -1)//找到了该号冒险者
					{
						if (!var->DistanceMagic(*m_adventurers[i]))//增益失败
						{
							cout << "魔法值不够!请重新选择" << endl;
							continue;
						}
						cout << "加强防御!!!" << endl;
						var->SetAttackedByClose(false);

						break;
					}
					else cout << "不存在该号冒险者,请重新选择" << endl;
				}
				if (skill == 4)
				{
					cout << "选择两个冒险者的序号(从小到大):" << endl;
					int m1(0), m2(0);
					cin >> m1 >> m2;

					int i = FindIndexForAd(m1);
					int i2 = FindIndexForAd( m2);
					if (i != -1 && i2 != -1)//找到了这两个冒险者
					{
						if (!var->DistanceMagic(*m_adventurers[i], *m_adventurers[i2]))//若增益失败
						{
							cout << "魔法值不够!请重新选择" << endl;
							continue;
						}
						cout << "加强防御!!!" << endl;
						var->SetAttackedByClose(false);

						break;
					}
					else cout << "有冒险者不存在,请重新选择" << endl;
				}
				if (skill == 5)
				{
					cout << "选择三个冒险者的序号(从小到大):" << endl;
					int m1(0), m2(0), m3(0);
					cin >> m1 >> m2 >> m3;

					int i = FindIndexForAd(m1);
					int i2 = FindIndexForAd( m2);
					int i3 = FindIndexForAd( m3);
					if (i != -1 && i2 != -1 && i3 != -1)//找到了这三个冒险者
					{
						if (!var->DistanceMagic(*m_adventurers[i], *m_adventurers[i2], *m_adventurers[i3]))//增益失败
						{
							cout << "魔法值不够!请重新选择" << endl;
							continue;
						}
						cout << "加强防御!!!" << endl;
						var->SetAttackedByClose(false);

						break;
					}
					else cout << "有冒险者不存在,请重新选择" << endl;
				}
			}
			if (m_monsters.size() == 0)break;
		}
	}
}

void GameManager::EveryMonsterAttack()
{
	for (auto var :m_monsters)
	{
		cout << var->GetId() << "号怪兽出动!" << endl;
		int i = ReturnRandom(m_adventurers.size()) - 1; //随机选一个冒险者攻击

		if (var->ReturnType() == TIGER|| var->ReturnType() == MUMMY)
		{
				var->CloseAttack(*m_adventurers[i]);
				m_adventurers[i]->SetAttackedByClose(true);//给冒险者标记为被近身攻击
                cout <<var->GetId()<< "号怪兽对" << m_adventurers[i]->GetId()<<"号冒险者发动了近身撕咬!"<< endl;

				DeadSettleForAd(i);
		}
		if (var->ReturnType() == EAGLE)
		{
			var->DistanceAttackNoMp(*m_adventurers[i]);
			cout << var->GetId() << "号怪兽对" << m_adventurers[i]->GetId() << "号冒险者发动了羽落攻击!" << endl;

			DeadSettleForAd(i);
		}
		if (var->ReturnType() == WITCH)
		{
			int i2 = ReturnRandom(m_adventurers.size()-i) - 1+i; //保证i2大于等于i且小于size()
			int i3= ReturnRandom(m_adventurers.size()-i2) - 1+i2;//同上
			if (!var->DistanceMagic(*m_adventurers[i], *m_adventurers[i2], *m_adventurers[i3]))
			{
				if (!var->DistanceMagic(*m_adventurers[i], *m_adventurers[i2]))
				{
					if (!var->DistanceMagic(*m_adventurers[i]))
					{
						//mp不够发动任何魔法攻击
						var->DistanceAttackNoMp(*m_adventurers[i]);
						cout << var->GetId() << "号怪兽对" << m_adventurers[i]->GetId() << "号冒险者发动了远程石块攻击!" << endl;
						DeadSettleForAd(i);
					}
					else//mp够发动单人魔法攻击
					{
						cout << var->GetId() << "号怪兽对" << m_adventurers[i]->GetId() << "号冒险者发动了暗鸦攻击!" << endl;
						DeadSettleForAd( i);
					}
				}
				else//mp够发动双人魔法攻击
				{
					cout << var->GetId() << "号怪兽对" << m_adventurers[i]->GetId() << "号冒险者和"<< m_adventurers[i2]->GetId() <<"号冒险者连续发动了两次暗鸦攻击!" << endl;
					DeadSettleForAd( i2);
					if (i != i2)
					DeadSettleForAd( i);
				}
			}
			else//mp够发动三人魔法攻击
			{
				cout << var->GetId() << "号怪兽对"
					<< m_adventurers[i]->GetId() << "号冒险者和"
					<< m_adventurers[i2]->GetId() << "号冒险者和"
					<< m_adventurers[i3]->GetId() << "号冒险者连续发动了三次暗鸦攻击!" << endl;
				DeadSettleForAd(i3);
				if(i2!=i3)
				DeadSettleForAd(i2);
				if(i!=i2&&i!=i3)
				DeadSettleForAd( i);
			}
		}
		if (var->ReturnType() == DRAGON)
		{
			if (!var->IsUsedKS())//如果龙没用过绝招,使用
			{
				var->KillSky(m_adventurers);
				cout << var->GetId() << "号怪兽是巨龙!它发动了毁天灭地!!!"<<endl;

				for (int j = m_adventurers.size()-1; j >= 0; j--)
					DeadSettleForAd(j);
			}
			else
			{
				var->DistanceAttackNoMp(*m_adventurers[i]);
				cout << var->GetId() << "号怪兽对" << m_adventurers[i]->GetId() << "号冒险者发动了羽落攻击!" << endl;

				DeadSettleForAd( i);
			}
		}

		if (m_adventurers.size() == 0)break;
	}
}

void GameManager::PassReward()
{
	int coins = ReturnRandom(300) / m_adventurers.size();//每个人分到的钱
	for (auto var : m_adventurers)//每个人分到钱并恢复所有血量蓝量
	{
		var->AddMoney(coins);
		var->HpRestore();
		var->MpRestore();
	}
	cout << "恭喜你打败了这一关的所有怪物!在这一关每个冒险家分到了" << coins << "个金币!" << endl;

	int dice = ReturnRandom(3);
	if (dice == 1)//获得加血量上限药水
	{
		int choice = ReturnRandom(m_adventurers.size()) - 1;
		m_adventurers[choice]->AddMaxHp(20);
		cout << m_adventurers[choice]->GetId() << "号冒险者获得了活力药水,血量上限增加20!" << endl;
	}
	if (dice == 2)//获得加伤害药水
	{
		int choice = ReturnRandom(m_adventurers.size()) - 1;
		m_adventurers[choice]->AddBaseDamaged(8);
		cout << m_adventurers[choice]->GetId() << "号冒险者获得了能量药水,伤害增加8!" << endl;
	}
	if (dice == 3)cout << "没有获得任何药水" << endl;
}

void GameManager::Start()
{
	string adventurertype[4] = { "Warriors","Rogues","OffensiveMages","DefensiveMages" };
	string monstertype[5] = { "Tiger","Eagle","Witch","Mummy","Dragon" };

	OutPutInstructionFromFile();//从输出冒险者和怪物的说明

	cout << endl << "你的初始阵容为:" << endl;
	for (auto val :m_adventurers)
	{
		cout << val->GetId() << "号冒险者" << val->GetName() << endl;
		cout << "年龄:" << val->GetAge() << "  职业:" << adventurertype[val->ReturnType()] << endl;
	}

	cout << "冒险开始!" << endl;

	while (m_curlevel <=m_totallevel)
	{
		if (IsEncounter())
		{
			GenerateMonster();
			cout << "你在第" << m_curlevel << "hour遭遇了怪物!它们是:" << endl;
			for (auto var : m_monsters)
			{
				cout << var->GetId() << "号怪物:" << monstertype[var->ReturnType()] << endl;
			}
			cout << "现在,是你的回合" << endl;
			while (1)
			{
				cout << "轮到你了!" << endl;
				EveryAdventureAttack();
				if (m_monsters.size() == 0)break;

				cout<<endl << "轮到怪物攻击了!" << endl;
				cout<< endl; cin.get(); cin.get();
				EveryMonsterAttack();
				if (m_adventurers.size() == 0)break;

				cout <<endl<< "下一回合开始" << endl;

				cout << endl << "目前怪物情况:" << endl;
				for (auto var : m_monsters)
				{
					cout << var->GetId() << "号怪物血量:" << var->GetHp() << endl;
				}
				cout << endl << "目前冒险家情况:" << endl;
				for (auto var : m_adventurers)
				{
					cout << var->GetId() << "号冒险家血量:" << var->GetHp() << " 护甲:" << var->GetArmor() << endl;
				}
				cout << endl;
				cin.get();
			}
			if (m_monsters.size() == 0)//过关,分配宝物
			{
				PassReward();
			}
			if (m_adventurers.size() == 0)
			{
				cout << "游戏失败,您止步于第" << m_curlevel << "关" << endl;
				cin.get();
				return;
			}
		}
		else cout << "在第" << m_curlevel << "hour没有发生任何事" << endl;
		m_curlevel++;
	}
	cout << endl << "恭喜您通关!" << endl;
	cout << "存活的冒险家的最终情况为:" << endl;
	for (auto var : m_adventurers)
	{
		cout << var->GetId() << "号冒险家:" << var->GetName()<<"剩余血量:"<<var->GetHp()<<"  获得金币"<<var->GetMoney() << endl;
	}
	return;
}

main函数:

#include "GameManager.h"
#include <time.h>
#define MANAGER GameManager::GetInstance()

int main(int  argc, char*  argv[])
{
	srand((unsigned)time(0));

	char c(0);

	while (c != 'e')
	{
		MANAGER->Start();
		cout << endl << "输入e退出,输入其他键重新游戏" << endl;
		cin >> c;
	}

	return 0;
}

自己玩了玩还挺有意思的,感谢观看:)

10-08 04:30