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,maxMP和MP为100,damage为20,exp为0, level为1,drugNum为5;
4) 每回合Soldier通过决策(makeDecision)来决定需要发出哪一个动作(攻击attack、休息rest或吃药takingDrug,注意每回合只能做其中一个动作)。请自行设计和调整每种动作发出的必要条件,例如:生命值若低于最大值的50%该回合就吃药,体力低于最大值的30%该回合就休息,生命力和体力都充足该回合就发起攻击,等等;
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。
7) 休息(rest)一次,生命值(HP)、体力(SP)增加最大值的50%,但不要超过最大值。(例如,当前生命值是30,最大生命值是100,则吃药后的当前生命值为30+100*50%=80。)
8) 吃药(takingDrug),如果药瓶数量为0,不能吃药。吃药一次,药瓶数量减少1,生命值(HP)增加最大值的80%,但不能超过maxHP。
设计和实现回合制战斗系统Combat的要求(二)
2. Wizard巫师类,从Soldier类公有继承
1) Wizard的属性(protected作用域)
新增的属性:
最大魔法值 maxMp
当前魔法值 HP
2) Wizard的动作(public作用域)
决策 makeDecision
攻击 attack
休息 rest
吃药 takingDrug
魔法攻击wizard_attack
3) Wizard被创建后,maxMP和MP为100 ,maxHP和HP为100,maxSP和SP为100,maxMP和MP为100,damage为20,exp为0,level为1;
4) 每回合Wizard通过决策(makeDecision)来决定需要发出哪一个动作(攻击attack、魔法攻击wizard_attack、休息rest或吃药takingDrug,注意每回合只能做一个动作);
5) 魔法攻击(wizard_attack):如果魔法值小于25、或体力小于10无法使用该技能。一次魔法攻击能同时攻击几个敌人,但每对付一个敌人,自己的体力(SP)减少10、魔法值减少25、经验(exp)增加5、敌人的生命值(HP)减去自己攻击力值(damage)。敌人生命值(HP)减少到0时死去,同时自己获得敌人身上的所有药瓶;
6) 经验(exp)每增加20,等级(level)提高1级,maxHP、maxSP、maxMP、damage分别增加20;
7) 休息(rest)一次,生命值(HP)、体力(SP)恢复效果同Soldier的休息(rest)动作。魔法值增加最大魔法值的30%,但不要超过最大魔法值,例如:_mp=_mp+_maxMp*30%。
8) 吃药(takingDrug)一次,效果等同于Soldier吃药。
9) 攻击(attack),攻击效果同Soldier。
设计和实现回合制战斗系统Combat的要求(三)
2. Master巫师类,从Wizard类公有继承
1) Master的属性(protected作用域)
新增的属性:
最大内力 maxNp
当前内力 NP
2) Master的动作(public作用域)
决策 makeDecision
攻击 attack
休息 rest
吃药 takingDrug
魔法攻击wizard_attack
绝杀攻击master_attack
3) Master被创建后,maxMP和MP为100 ,maxHP和HP为100,maxSP和SP为100,maxMP和MP为100,damage为30,exp为0,level为1;
4) 每回合Wizard通过决策(makeDecision)来决定需要发出哪一个动作(攻击attack、魔法攻击wizard_attack、绝杀攻击master_attack、休息rest或吃药takingDrug,注意每回合只能做一个动作);
5) 大师攻击(master_attack),如果内力(NP)大于50时,可以使用大师(master_attack)攻击。一次大师攻击能让被攻击的敌人的生命值(HP)减少其最大生命值的(maxHP)50%,例如敌人HP为100,maxHP为160,被大师攻击后,生命值变为HP-maxHP*50%=100-160*50%=20。一次大师攻击会内力(NP)损耗50、体力(SP)损耗30,经验增加5。
6) 魔法攻击(wizard_attack),攻击效果等同于Wizard的攻击(attack)动作
7) 攻击(attack),攻击效果等同于Soldier的攻击(attack)动作。
8) 使用大师攻击后,经验(exp)每增加20,等级(level)就提高1级,maxHP、maxSP、maxMP、maxNP分别增加20,damage增加20;
9) 休息(rest)一次,内力增加最大内力的30%,但不要超过最大内力值。其余如HP、SP、MP的恢复等同于Wizard的休息(rest)动作。
10) 吃药(takingDrug)一次,效果等同于Soldier的吃药(takingDrug)动作。
设计和实现回合制战斗系统Combat的要求(四)
2. 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()动作。
5.将整个战斗过程的每一步保存入日志文件。
设计和实现回合制战斗系统Combat程序代码(一)
由于时间……只编了master类
Master1.h类
#ifndef _WARRIOR_H
#define _WARRIOR_H
#include "regulations.h"//规则常数
#include "MyRandom.h" //随机数类
#include "Log.h" //日志类
#include
using namespace std;
//抽象基类
class Warrior
{
public:
//构造函数
Warrior(){};
//虚析构函数
virtual ~Warrior(void){};
//纯虚函数,在子类中实现
//纯虚函数,大师攻击
virtual void wizard_attack(Warrior **)=0;
//纯虚函数,攻击
virtual void attack(Warrior *)=0;
//纯虚函数,休息
virtual void rest(void)=0;
//纯虚函数,继续休息
virtual void restAgain(void)=0;
//纯虚函数,吃药
virtual void haveDrug(void)=0;
//纯虚函数,死亡
virtual bool die(void)=0;
//纯虚函数,决策,从一组对手中进行决策
virtual void makeDecision(Warrior **)=0;
//获取姓名
virtual string getName()=0;
//被杀伤生命点数
virtual void setHP(int)=0;
virtual int getDrug()=0;
//友元函数,Log类能访问Warrior对象
friend void Log::print(Warrior *) const;
friend void Log::print(string message) const;
protected:
int maxHP; //最大生命 health
int HP; //当前生命
int maxSP; //最大体力 strength
int SP; //当前体力
int maxMP; //最大魔法值
int MP; //当前魔法值
int damage; //攻击力
int EXP; //经验
int level; //等级
string name; //姓名
int drugNum; //药品数
MyRandom random; //随机数对象
Log log; //日志对象
};
#endif //_WARRIOR_H
设计和实现回合制战斗系统Combat程序代码(二)
Master.h类
#ifndef _Master_H
#define _Master_H
#include "Master1.h"
#include
using namespace std;
//组员战士
class Master:public Warrior
{
public:
//构造函数
Master(string);
//析构函数
virtual ~Master(void);
//绝杀
void wizard_attack(Warrior **);
//攻击
void attack(Warrior *);
//休息
void rest();
//休战
void restAgain();
//吃药
void haveDrug();
//死亡
bool die();
//决策,从一组对手中进行决策
void makeDecision(Warrior **);
//判断是否已经击败对方全组
bool enemyGroupDefeated(Warrior **);
//魔法攻击一个对手
virtual void masterStroke(Warrior *);
//获取姓名
virtual string getName();
//被杀伤生命点数
virtual void setHP(int);
int getDrug();
bool restComplete; //是否休息结束
};
#endif //_Master_H
设计和实现回合制战斗系统Combat程序代码(三)
Regulations.h类
#ifndef _REGULATIONS_H
#define _REGULATIONS_H
//编译选项
#define _DISPLAY
//全局常量值
const int EXP_INCREMENT = 5; //经验增加值
const int SP_INCREMENT = 50; //体力增加值
const int SP_DECREMENT = 20; //攻击后体力减少值
const int DAMAGE_INCREMENT = 20; //攻击力增加值
const int MAXHP_INCREMENT = 100; //最大生命增加值
const int MAXSP_INCREMENT = 100; //最大体力增加值
const int MAXMP_INCREMENT = 100; //最大内力增加值
const int GROUP_SIZE = 3; //组队成员数
const int ROUND_INTERVAL = 1000; //回合时间间隔
const int ATTACK_INTERVAL = 500; //队员攻击时间间隔
const int MASTER_STROKE_RATE = 3; //绝杀使用频率1/5
const int LOSE_TARGET_RATE = 4; //没打中对方频率
const int ATTACK_SIZE = 3; //魔法攻击的人数范围 3人
const double MP_ROUND_RECOVER = 0.2; //每一回合内力恢复%
const double MP_ALLOW_MASTERSTROKE = 0.3; //内力恢复至百分比后允许绝杀
const double SP_ALLOW_MASTERSTROKE = 0.3; //体力恢复至百分比后允许绝杀
const double REST_CONDITION = 0.3; //休息指标
const double HAVE_DRUG_CONDITION = 0.5; //吃药底线指标
const int LUCKY_NUMBER = 7; //随机数的幸运数字
#endif //_REGULATIONS_H
设计和实现回合制战斗系统Combat程序代码(四)
Log.h类
#ifndef _LOG_H
#define _LOG_H
#include
#include
#include
using namespace std;
//日志类
class Warrior; //提前声明Warrior类,在cpp中再包含Warrior.h避免交叉包含
class Log
{
public:
//构造函数
Log(void);
//析构函数
~Log(void);
// 输出字符串
void print(Warrior *) const;
void print(string message) const;
void print(int);
};
#endif //_LOG_H
MyRandom.h类
#ifndef _MYRANDOM_H
#define _MYRANDOM_H
//标准c的函数库,需要在extern "C"块内说明
extern "C"
{
#include
#include
#include
}
#include "Log.h"
//随机数类
class MyRandom
{
public:
//构造函数
MyRandom(void);
//析构函数
virtual ~MyRandom(void);
//随机数函数,产生指定范围内的随机数
unsigned int number(unsigned int,unsigned int);
};
#endif //_MYRANDOM_H
设计和实现回合制战斗系统Combat程序代码(五)
WarSystem.h类
#ifndef _WARSYSTEM_H
#define _WARSYSTEM_H
#include "Master1.h"
#include "regulations.h"
#include "MyRandom.h"
#include "Log.h"
#include
using namespace std;
class WarSystem
{
public:
//构造函数
WarSystem(Warrior *[],Warrior *[]);
//析构函数
~WarSystem(void);
//战斗开始函数
void startWar(void);
private:
//基类指针数组
Warrior **_pWarriorA;
Warrior **_pWarriorB;
//回合开始函数
void startRound(Warrior **,Warrior **);
//判断Warrior组是否被击败函数
bool groupDefeated(Warrior **);
//日志对象
Log log;
};
#endif //_WARSYSTEM_H
Log.cpp
#include "Log.h"
#include "Soldier.h"
Log::Log(void)
{
}
Log::~Log(void)
{
}
// 输出字符串
void Log::print(string message) const
{
cout << message;
}
//输出对象
void Log::print(Warrior *warrior) const
{
if (!warrior->die())
{
cout << warrior->getName()
<< "生命(" << warrior->HP << "/" << warrior->maxHP << ")"
<< "体力(" << warrior->SP << "/" << warrior->maxSP << ")"
<< "内力(" << warrior->MP << "/" << warrior->maxMP << ")"
<< "药品(" << warrior->drugNum << ")"
<< "经验(" << warrior->EXP << ")"
<< "等级(" << warrior->level << ")"
<< "攻击(" << warrior->damage << ")" << endl;
}
else
{
cout << warrior->getName()
<< "被打死" < } } //输出数字 void Log::print(int n) { cout << n; } Master.cpp #include "Master.h" //构造函数 Master::Master(string _name) {name = _name; //姓名 drugNum = 5; //药品数 maxHP = 100;//最大生命 HP = 100; //生命 maxSP = 100;//最大体力 SP = 100; //体力 maxMP = 100; //最大魔法值 MP = 100; //魔法值 damage = 20; //攻击力 level = 1; //等级 EXP = 0; //经验 restComplete = true;//刚开战不是休息状态} //析构函数 Master::~Master(void) { } //魔法攻击函数 void Master::wizard_attack(Warrior **enemyGroup) { //攻击人数 for(int i=0;i { int target = random.number(1,GROUP_SIZE)-1; if (!enemyGroup[target]->die()) { this->masterStroke(enemyGroup[target]);//攻击 } }} void Master::masterStroke(Warrior *enemy) {log.print("\t实施魔法攻击" + enemy->getName() + " 受到攻击"); //对手--------------------------------------------------------- //对手减少生命值 enemy->setHP(this->damage); //判断对手是否已死 if (enemy->die()) { log.print(", " + enemy->getName() + " 被打死,提前退出战斗\n"); int num=enemy->getDrug(); this->drugNum += num; log.print(this->getName() +" 获得" ); log.print(num); log.print(" 瓶药水!"); } log.print("\n"); //自己--------------------------------------------------------- //体力减少双倍 if ((this->SP)-2*SP_DECREMENT>0) this->SP-=(2*SP_DECREMENT); else this->SP = 0; //EXP增加 this->EXP+=EXP_INCREMENT; //当EXP累计增加了,指数提升 if ((this->EXP)/20+1>level) { //level提升 this->level += 1; //HP,SP,MP增加 this->maxHP+=MAXHP_INCREMENT; this->maxSP+=MAXSP_INCREMENT; this->maxMP+=MAXMP_INCREMENT; //damage增加 this->damage+=DAMAGE_INCREMENT; } //内力全部消耗殆尽 this->MP -= 50; if(this->MP<0) this->MP=0;} //攻击函数 void Master::attack(Warrior *enemy) { log.print(" 攻击" + enemy->getName()); if (random.number(1, LOSE_TARGET_RATE)==3) { log.print(" 打偏\n"); } else { log.print(" 命中"); enemy->setHP(this->damage); if (enemy->die()) { log.print(", " + enemy->getName() + " 被打死,提前退出战斗"); log.print("\n"); int num=enemy->getDrug(); this->drugNum += num; log.print(this->getName() +" 获得" ); log.print(num); log.print(" 瓶药水!");} log.print("\n"); if (this->SP-SP_DECREMENT>0) this->SP-=SP_DECREMENT; else this->SP = 0; this->EXP+=EXP_INCREMENT; if ((this->EXP)/20+1>level) { this->level += 1; this->maxHP+=MAXHP_INCREMENT; this->maxSP+=MAXSP_INCREMENT; this->maxMP+=MAXMP_INCREMENT; this->damage+=DAMAGE_INCREMENT; }//休息}}} void Master::rest() { log.print(" 休息\n"); //开始休息 restComplete = false; //恢复生命 this->HP = maxHP; //恢复体力 this->SP = maxSP; //恢复内力 this->MP = maxMP; } //继续休息 void Master::restAgain() { log.print(" 继续休息\n"); //结束休息 restComplete = true; } //吃药 void Master::haveDrug() { log.print(" 吃药\n"); this->drugNum-=1; //恢复体力 if (this->SP+SP_INCREMENT this->SP+=SP_INCREMENT; else this->SP=maxSP; } //死亡 bool Master::die() { if (this->HP<=0) { //生命清零 this->HP = 0; return true; } else return false; } //决策 void Master::makeDecision(Warrior **enemyGroup) { if (!this->die() && !this->enemyGroupDefeated(enemyGroup))//若自己没有死且对方全组没死光,本回合继续参战 { log.print(this->getName()); this->MP += MP_ROUND_RECOVER * (this->maxMP); if ((this->MP)>(this->maxMP)) this->MP = this->maxMP; if (!restComplete)//若上回合rest,本回合继续休息 {this->restAgain();} else { if (1.0*(this->SP)/(this->maxSP) < HAVE_DRUG_CONDITION && this->drugNum>0) { this->haveDrug();} else if (1.0*(this->HP)/(this->maxHP) < REST_CONDITION) //生命低于最大值的/3,休息 { this->rest(); } else { if (random.number(1,MASTER_STROKE_RATE)==2 /*随机绝杀*/ &&(this->MP) > MP_ALLOW_MASTERSTROKE * (this->maxMP) /*内力>30%*/ && (this->SP) > SP_ALLOW_MASTERSTROKE * (this->maxSP))/*体力>30%*/ this->wizard_attack(enemyGroup);//魔法攻击 } else while(1) { int target = random.number(1,GROUP_SIZE)-1; if (!enemyGroup[target]->die()) { this->attack(enemyGroup[target]);//攻击 break;}}}}}} //Warrior组是否已经被击败 bool Master::enemyGroupDefeated(Warrior **group) { bool defeated=true; for (int i=0;i { if (group[i]->die()==false) { defeated=false; break; } } return defeated;} //获取姓名 string Master::getName() { return "[" + this->name + "]";} void Master::setHP(int losePoints) { log.print(", 伤害点数:"); log.print(losePoints); this->HP -= losePoints;} int Master::getDrug() { return this->drugNum;} MayRandom.cpp #include "MyRandom.h" //构造函数 MyRandom::MyRandom() { srand( (unsigned)time( NULL ) ); } //析构函数 MyRandom::~MyRandom(void) { } //随机数函数,产生从range_min到range_max之间的整数随机数 unsigned MyRandom::number(unsigned RANGE_MIN,unsigned RANGE_MAX) { int num; num=(((double)rand()/(double)RAND_MAX)*RANGE_MAX+RANGE_MIN); return num; } WarSystem.cpp #include "WarSystem.h" #include "MyRandom.h" //构造函数 WarSystem::WarSystem(Warrior *groupA[],Warrior *groupB[]) { //Warrior **_pWarriorA; //Warrior **_pWarriorB; _pWarriorA = groupA; _pWarriorB = groupB; } //析构函数 WarSystem::~WarSystem(void) { } //战斗开始函数 void WarSystem::startWar(void) { int round=1; do { log.print("==第"); log.print(round++); log.print("回合===\n"); if (round%2==0) startRound(_pWarriorA,_pWarriorB); else startRound(_pWarriorB,_pWarriorA); Sleep(ROUND_INTERVAL); } while(!groupDefeated(_pWarriorA) && !groupDefeated(_pWarriorB));//当一方被击败退出战斗 } //回合开始函数 void WarSystem::startRound(Warrior **groupAttack,Warrior **groupDefend) { int i; for (i=0;i { Sleep(ATTACK_INTERVAL); groupAttack[i]->makeDecision(groupDefend); } #ifdef _DISPLAY log.print("\t▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉\n"); //输出防守方统计值 for (i=0;i { log.print("\t"); log.print(groupDefend[i]); } log.print("\t‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥\n"); //输出攻击方统计值 for (i=0;i { log.print("\t"); log.print(groupAttack[i]); } log.print("\t▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉\n"); #endif //_DISPLAY } //判断Warrior组是否被击败函数 bool WarSystem::groupDefeated(Warrior **group) { bool defeated=true; //假设已经被击败 for (int i=0;i { if (group[i]->die()==false) { defeated=false; //第i个Warrior没有死 break; } } //全部被消灭 if (defeated) { for (int i=0;i { log.print(group[i]->getName() + ","); } log.print("\b已经全部被消灭,游戏结束.\n"); } return defeated; }设计和实现回合制战斗系统Combat程序代码(六)
设计和实现回合制战斗系统Combat程序代码(七)
设计和实现回合制战斗系统Combat程序代码(八)
设计和实现回合制战斗系统Combat程序代码(九)
设计和实现回合制战斗系统Combat程序代码(十)