设计一个回合制战斗系统Combat(C++)

C++设计一个回合制战斗系统Combat

题目

设计和实现回合制战斗系统Combat
1. Soldier战士类

  1. Soldier的属性(protected作用域)
    最大生命 maxHP 当前生命 HP 最大体力maxSP 当前体力SP
    攻击力 damage 经验 exp 等级 level 姓名 name
    药瓶数量 drugNum

  2. Soldier的动作(public作用域)
    决策 makeDecision 攻击 attack 休息 rest 吃药 takingDrug

  3. Soldier被创建后,maxHP和HP为100,maxSP和SP为100,damage为20,exp为0, level为1,drugNum为5;

  4. 每回合Soldier通过决策(makeDecision)来决定需要发出哪一个动作(攻击attack、休息rest或吃药takingDrug,注意每回合只能做其中一个动作)。请自行设计和调整每种动作发出的必要条件,例如:生命值若低于最大值的30%该回合就吃药,体力低于最大值的50%该回合就休息,生命力和体力都充足该回合就发起攻击,等等;

  5. 攻击(attack)敌人一次,体力(SP)减少10,经验(exp)增加5。敌人的生命值(HP)减去攻击方攻击力值(damage)的大小。敌人生命值(HP)减少到0时死去,如果敌人被自己打死,获得敌人身上的所有药瓶;

  6. 经验(exp)每增加20,等级(level)就提高1级,maxHP、maxSP、damage分别增加20;Soldier, Wizard, Master升级后,当前HP,SP,MP和NP的值皆按比例(xx:MaxXX)增长,注意:不是升级后上述当前属性值就自动全满。例如:Wizard的 HP/MaxHP 50/100,升级后,HP/MaxHP调整为60/120。升级前HP:MaxHP比例为0.5,升级后MaxHP变成120,若要保持0.5的比例,HP自动调整为60。这种设定类似于魔兽争霸III。

  7. 休息(rest)一次,生命值(HP)、体力(SP)增加最大值的50%,但不要超过最大值。(例如,当前生命值是30,最大生命值是100,则吃药后的当前生命值为30+100*50%=80。)

  8. 吃药(takingDrug),如果药瓶数量为0,不能吃药。吃药一次,药瓶数量减少1,生命值(HP)增加最大值的80%,但不能超过maxHP。
    2. Wizard巫师类,从Soldier类公有继承

  9. Wizard的属性(protected作用域)
    新增的属性: 最大魔法值 maxMP 当前魔法值 MP

  10. Wizard的动作(public作用域)
    决策 makeDecision 攻击 attack 休息 rest 吃药 takingDrug
    魔法攻击wizard_attack

  11. Wizard被创建后,maxMP和MP为100 ,maxHP和HP为100,maxSP和SP为100,maxMP和MP为100,damage为20,exp为0,level为1;

  12. 每回合Wizard通过决策(makeDecision)来决定需要发出哪一个动作(攻击attack、魔法攻击wizard_attack、休息rest或吃药takingDrug,注意每回合只能做一个动作);

  13. 魔法攻击(wizard_attack):如果魔法值小于25、或体力小于10无法使用该技能。一次魔法攻击能同时攻击几个敌人,但每对付一个敌人,自己的体力(SP)减少10、魔法值减少25、经验(exp)增加5、敌人的生命值(HP)减去自己攻击力值(damage)。敌人生命值(HP)减少到0时死去,同时自己获得敌人身上的所有药瓶;

  14. 经验(exp)每增加20,等级(level)提高1级,maxHP、maxSP、maxMP、damage分别增加20;(如果觉得升级太快了,或者升级增加的HP和damage不太协调,可以调整这些参数)

  15. 休息(rest)一次,生命值(HP)、体力(SP)恢复效果同Soldier的休息(rest)动作。魔法值增加最大魔法值的30%,但不要超过最大魔法值,例如:_mp=_mp+_maxMp*30%。

  16. 吃药(takingDrug)一次,效果等同于Soldier吃药。

  17. 攻击(attack),攻击效果同Soldier。
    3. Master巫师类,从Wizard类公有继承

  18. Master的属性(protected作用域)
    新增的属性: 最大内力 maxNp 当前内力 NP

  19. Master的动作(public作用域)
    决策 makeDecision 攻击 attack 休息 rest 吃药 takingDrug
    魔法攻击wizard_attack 绝杀攻击master_attack

  20. Master被创建后,maxMP和MP为100 ,maxHP和HP为100,maxSP和SP为100,maxNP和NP为100,damage为30,exp为0,level为1;

  21. 每回合Wizard通过决策(makeDecision)来决定需要发出哪一个动作(攻击attack、魔法攻击wizard_attack、绝杀攻击master_attack、休息rest或吃药takingDrug,注意每回合只能做一个动作);

  22. 大师攻击(master_attack),如果内力(NP)大于50时,可以使用大师(master_attack)攻击。一次大师攻击能让被攻击的敌人的生命值(HP)减少其最大生命值的(maxHP)50%(可能有点太强了,破坏平衡性!容易导致游戏在短短几个回合就结束,可以考虑适当减小。),例如敌人HP为100,maxHP为160,被大师攻击后,生命值变为HP-maxHP50%=100-16050%=20。一次大师攻击会内力(NP)损耗50、体力(SP)损耗30,经验增加5。

  23. 魔法攻击(wizard_attack),攻击效果等同于Wizard的攻击(attack)动作

  24. 攻击(attack),攻击效果等同于Soldier的攻击(attack)动作。

  25. 使用大师攻击后,经验(exp)每增加20,等级(level)就提高1级,maxHP、maxSP、maxMP、maxNP分别增加20,damage增加20;

  26. 休息(rest)一次,内力增加最大内力的30%,但不要超过最大内力值。其余如HP、SP、MP的恢复等同于Wizard的休息(rest)动作。

  27. 吃药(takingDrug)一次,效果等同于Soldier的吃药(takingDrug)动作。

4. WarSystem战斗系统类

  1. WarSystem类的属性
    军团A Soldier ** _pGroupA; 军团B Soldier ** _pGroupB;

  2. WarSystem类的动作
    战斗开始startWar 回合开始startRound

  3. 每次战斗,双方派出一个军团,军团由数名战士、巫师和大师组成。战斗按回合制进行,即每回合中,一方军团的每个成员做完各自的一次动作(由makeDecision决定)后,另一方军团每个成员接着完成自己的一次动作。战斗开始,由哪个军团先发起攻击,系统随机决定。回合的生成和结束由WarSystem类控制;

  4. WarSystem类拥有两个数据成员(指向指针变量的指针,即二级指针):
    Soldier ** _pGroupA;
    Soldier ** _pGroupB;
    分别对应战斗的双方军团。(提示,军团可以由Soldier *数组的形式生成,在WarSystem的pGroupA和pGroupB分别指向两个军团,注意OOP的多态实现。)

  5. WarSystem类可以发出战斗开始即startWar()动作。在startWar()中,随机决定由哪一方率先发起攻击(恐怕是每个回合都随机决定谁先出手会比较公平,如果每回合先出手都是固定一方,那么战斗结果完全是确定性的。而且由于两支队伍的成员一样,交换先出手权后的结果也是对称的。),然后调用WarSystem的另一动作:回合开始,即startRound()。

  6. startRound()动作的描述:在startRound()中,按军团顺序调用每个战士的makeDecision()动作(也可以考虑两个军团轮流一次一人行动,比较公平)。

重要提醒

本博客是博主花几个小时弄的,尚未完全满足题目要求,例如未进行随机开启军团战斗(用随机函数判断即可,较简单),本博客意在为广大初学者提供类的设计思路,故不提供主函数代码,请自行设计,由于时间仓促代码多有不足,请读者朋友仔细甄别其中优劣之处,再次提醒,代码仅提供给大家作为思路参考!!!!

Soldier类

#ifndef A1
#define A1
#include<iostream>
#include<string>

using namespace std;
class Soldier//战士类
{
protected:
	double maxHP=100,HP=100,maxSP=100,SP=100,damage=20,drugNum=5,level=1;
	int exp=0;
    string name;
public:
	Soldier()
	{
	}
	int enemynum = 3;//设置一个默认敌人数量
	void setHP()//重置生命值为0
	{
		HP = 0;
	}
	void underattack(double x);
	virtual void setname();//设置名字
	virtual ~Soldier(){}
	virtual void makeDecision(Soldier **t);
	void attack(Soldier **t);
	virtual void rest();
	void takingDrug();
	string getname()//获取名字
	{
		return name;
	}
	double getmaxHP()//获取最大生命值
	{
		return maxHP;
	}
	double getHP()//获取生命值
	{
		return HP;
	}
	double getdrugnum()//获取药瓶数量
	{
		return drugNum;
	}
};
void Soldier::makeDecision(Soldier **t)//决策
{
	if (HP < (maxHP * 0.3))//生命值若低于最大值的30%该回合就吃药
		takingDrug();
	else if (SP < (maxSP * 0.5))//体力低于最大值的50%该回合就休息
		rest();
	else//生命力和体力都充足该回合就发起攻击t
		attack(t);
}
void Soldier::underattack(double hurt)
{
	HP -= hurt;
}
void Soldier::attack(Soldier **enemy)//攻击函数(平A)
{
	for (int i = 0; i < enemynum; i++)
	{
		if (HP > 0 && enemy[i]->getHP()> 0 && SP > 0)
		{
			cout << name << "攻击了" << enemy[i]->getname()<< endl;
			enemy[i]->underattack(damage);
			SP -= 10;
			exp += 5;
			cout << name << "的体力值下降至" << SP << '\t' << "经验+5(" << exp << ")" << endl;
			if (exp % 20 == 0)
			{
				double BHP = HP / maxHP;
				double BSP = SP / maxSP;
				level++;
				damage *= 1.2;
				maxHP *= 1.2;
				maxSP *= 1.2;
				HP = maxHP * BHP;
				SP = maxSP * BSP;
				cout << name << "升级至等级" << level << endl;
			}
			if (enemy[i]->getHP()<= 0)
			{
				enemy[i]->setHP();
				drugNum += enemy[i]->getdrugnum();
				cout << enemy[i]->getname()<< "死亡,生命值为" <<HP<< "\t" << name << "获得药瓶数量" << enemy[i]->getdrugnum()<< endl;
			}
			cout << enemy[i]->getname() << "受到" << damage << "伤害 当前生命值为" << enemy[i]->getHP() << endl << endl;
			return;
		}
	}
}
void Soldier::takingDrug()//吃药
{
	cout << name << "***开始吃药***" << endl;
	if (drugNum == 0)
	{
		cout << "很遗憾," << name << "没有药瓶了" << endl;
		return;
	}
	else {
		drugNum--;
		HP += maxHP * 0.8;
		if (HP > maxHP)
			HP = maxHP;
	}
	cout << "***结束吃药***" << endl << "当前生命值:" << HP << '\t' << "体力" << SP << endl;
}
//coding by wangxiao/wansixinxin/wangboxin/liuyang
void Soldier::rest()//休息
{
	cout << name << "***开始休息***" << endl;
	HP += maxHP * 0.5;
	if (HP > maxHP)
		HP = maxHP;
	SP += maxSP * 0.5;
	if (SP > maxSP)
		SP = maxSP;
	cout << "***休息结束***" << endl << "当前生命值:" << HP << '\t' << "体力" << SP << endl;
}

void Soldier::setname()//命名
{
	cout << "请为战士命名:";
	cin >> name;
}
#endif // !A1

Wizard类

#ifndef A2
#define A2
#include"Soldier.h"
#include<iostream>
using namespace std;
class Wizard :public Soldier//巫师类
{
protected:
	double MP=100;
	double maxMP = 100;
public:
	Wizard() {}
	~Wizard() {}
	virtual void setname();
	virtual void rest();
	virtual void makeDecision(Soldier **enemy);
	void wizard_attack(Soldier **enemy);//法术攻击
};
void Wizard::rest()//巫师休息
{

	cout << name << "***开始休息***" << endl;
	HP += maxHP * 0.5;
	if (HP > maxHP)
		HP = maxHP;
	SP += maxSP * 0.5;
	if (SP > maxSP)
		SP = maxSP;
	MP+= maxMP * 0.5;
	if (MP > maxMP)
		MP = maxMP;
	cout << "***休息结束***" << endl << "当前生命值:" << HP << '\t' << "体力" << SP <<"魔法值"<<MP<<endl;
}
void Wizard::makeDecision(Soldier** enemy)
{
	if (MP <= 25 && SP <= 10)
		rest();
	else if (MP <= 25 && SP>=10)
		attack(enemy);
	else if (HP <= 20)
		takingDrug();
	else
		wizard_attack(enemy);
}
void Wizard::wizard_attack(Soldier** enemy)
{
	if (HP>0)
	{

		for (int i = 0; i < enemynum; i++)
		{
			if (enemy[i]->getHP()>0)
			{
				if (MP > 25 && SP > 10)
				{
					MP -= 25;
					SP -= 10;
					cout << endl<< name << "对" << enemy[i]->getname() << "发动魔法攻击"<< endl;
					enemy[i]->underattack(damage * 0.2);
					cout << enemy[i]->getname() << "的生命值下降至" << enemy[i]->getHP() << endl;
					exp += 5;
					cout << name << "的体力值/魔法值下降为:" << SP << "/" << MP << "经验+5(" << exp << ")" << endl;
					if (enemy[i]->getHP() <= 0)
					{
						enemy[i]->setHP();
						drugNum += enemy[i]->getdrugnum();
						cout << enemy[i]->getname()<< "死亡" << "\t" << name << "获得药瓶数量" << enemy[i]->getdrugnum()<< endl;
					}
					if (exp % 20 == 0)
					{
						double BHP = HP / maxHP;
						double BSP = SP / maxSP;
						double BMP = MP / maxMP;
						level++;
						damage *= 1.2;
						maxHP *= 1.2;
						maxSP *= 1.2;
						maxMP *= 1.2;
						HP = maxHP * BHP;
						SP = maxSP * BSP;
						MP = maxMP * BMP;
						cout << name << "升级至等级" << level << endl;
					}
				}
				else
				{
					cout << "魔法值或者体力值不足无法继续魔法攻击" << endl;
					return;
				}
			}
		}
	}
}
void Wizard::setname()
{
	cout << "请为法师命名:";
	cin >> name;
}
#endif // !A2

Master类

#ifndef A3
#define A3
#include"Wizard.h"
class Master :public Wizard
{protected:
	double NP = 100;
	double maxNP = 100;
public:
	Master() {};
	~Master() {};
	void setname();
	void master_attack(Soldier **enemy);
	void makeDecision(Soldier** enemy);
	void rest();
};
void Master::master_attack(Soldier** enemy)//大师攻击(终结技)
{
	if (HP > 0)
	{
		for (int i = 0; i < enemynum; i++)
		{
			if (enemy[i]->getHP() > 0 && NP >= 50 && SP >= 30)
			{
				NP -= 50;
				SP -= 30;
				enemy[i]->setHP();
				cout << enemy[i]->getname() << "被" << name << "终结" << endl;
				cout << enemy[i]->getname() << "的生命值当前为" << enemy[i]->getHP()<<endl;
				exp += 5;
				if (exp % 20 == 0)
				{
					double BHP = HP / maxHP;
					double BSP = SP / maxSP;
					double BMP = MP / maxMP;
					double BNP = NP / maxNP;
					level++;
					damage *= 1.2;
					maxHP *= 1.2;
					maxSP *= 1.2;
					maxMP *= 1.2;
					HP = maxHP * BHP;
					if (HP > maxHP)
						HP = maxHP;
					SP = maxSP * BSP;
					if (SP > maxSP)
						SP = maxSP;
					MP = maxMP * BMP;
					if (MP > maxMP)
						MP = maxMP;
					NP = maxNP * BNP;
					if (NP > maxNP)
						NP = maxNP;
					cout << name << "升级至等级" << level << endl;
					cout << name<<"各项属性提升至:生命" << HP << "体力" << SP << "魔法值" << MP << "内力" << NP << endl << endl;
				}
			}
			else if (NP < 50 && SP < 30)
			{
				cout <<name<< "内力或体力不足无法继续发动终结技" << endl;
				return;
			}
		}
	}
}
void Master::rest()
{
	cout << name << "***开始休息***" << endl;
	HP += maxHP * 0.5;
	if (HP > maxHP)
		HP = maxHP;
	SP += maxSP * 0.5;
	if (SP > maxSP)
		SP = maxSP;
	MP += maxMP * 0.5;
	if (MP > maxMP)
		MP = maxMP;
	NP += maxNP * 0.5;
	if (NP > maxNP)
		NP = maxNP;
	cout << "***休息结束***" << endl << "当前生命值:" << HP << '\t' << "体力" << SP << "魔法值" << MP << "内力" << NP << endl;
}
void Master::makeDecision(Soldier** enemy)
{
	for (int i = 0; i < enemynum; i++)
	{
		if (enemy[i]->getHP() <= enemy[i]->getmaxHP() * 0.4)
		{
			master_attack(enemy);
			return;
		}
	}
	if (MP <= 25 && SP <= 10)
		rest();
	else if (MP <= 25 && SP >= 10)
		attack(enemy);
	else if (HP <= 20)
		takingDrug();
	else
		wizard_attack(enemy);
}
void Master::setname()
{
	cout << "请为此大师命名:";
	cin >> name;
}
#endif // !A3

Warsystem类

#ifndef  A5
#define A5
#include"Master.h"
#include<windows.h>
#include<cstdlib>
class Warsystem
{
private:
	Soldier** _pgroupA;
	Soldier** _pgroupB;
	void startround(Soldier **A,Soldier **B);
public:
	bool isgrouplose(Soldier** A);
	Warsystem(Soldier** A, Soldier** B)
	{
		_pgroupA = A;
		_pgroupB = B;
	}
	void startwar();
};
void Warsystem::startwar()
{
	int round = 1;
	do
	{
		cout << endl<<endl<<endl<<"第" << round << "回合:" << endl << endl;
		if (round++ & 1)
			startround(_pgroupA, _pgroupB);
		else
			startround(_pgroupB, _pgroupA);
		Sleep(3000);
	} while (!isgrouplose(_pgroupA) && !isgrouplose(_pgroupB));
	if (isgrouplose(_pgroupA))
		cout << "B军团胜利";
	else
		cout << "A军团胜利";
}
void Warsystem::startround(Soldier** A, Soldier** B)
{
	for (int i = 0; i < A[0]->enemynum; i++)
	{
		if(A[i]->getHP()>0)
			A[i]->makeDecision(B);
	}
}
bool Warsystem::isgrouplose(Soldier** A)
{
	for (int i = 0; i < A[0]->enemynum; i++)
	{
		if (A[i]->getHP()>0)
			return false;
	}
	return true;
}
#endif // ! A4


  • 30
    点赞
  • 121
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值