魔兽世界解题报告.docx
《魔兽世界解题报告.docx》由会员分享,可在线阅读,更多相关《魔兽世界解题报告.docx(26页珍藏版)》请在冰豆网上搜索。
魔兽世界解题报告
魔兽世界解题报告
一、解题思路
本题的思路十分清晰,主要是写一个怪物的基类,然后派生出五种怪物。
此外还需要时间函数、城市的结构体、总部的类等。
题目要求的事件全部于主函数内部发生,调用不同的函数完成任务。
二、类、结构体、函数列表
1classmonster:
怪物基类
变量:
char*name名字intnumbe编号inthealth生命值intattack攻击力
intposition所在城市编号,为红方大本营,numberofcity+1为蓝方大本营
intcolor所属阵营
函数:
virtualvoidmove()控制移动的函数,若为红色向右移,蓝色向左移,分别输出到达总部或者到达某个城市
virtualboolhurt(intattacking)处理受伤的函数,若死亡输出怪物死亡
virtualvoidfight(monster*x)攻击函数,x为攻击对象,调用对方的受伤函数,并输出。
若对方没死则要反击
virtualvoidfightback(monster*x)反击函数,x为反击对象,调用对方的受伤函数,并输出
2classdragon:
publicmonster:
从怪物基类派生出的龙类
新函数:
virtualvoidfight(monster*x)增加一个输出:
当主动攻击后没有死亡,则输出咆哮
3classninja:
publicmonster:
从怪物基类派生出的忍者类
新函数:
virtualvoidfightback(monster*x)从不反击,嗯,“忍”
4classiceman:
publicmonster:
从怪物基类派生出的冰人类
新变量:
intstep记录已经走过的步数的奇偶性,只可能为0或1,到达2则重置为0
新函数:
virtualvoidmove()每走两步,自减血量,并增加攻击力
5classlion:
publicmonster:
从怪物基类派生出的狮子类
新函数:
virtualboolhurt(intattacking)受伤若导致死亡,则战斗前生命值赋予攻击者
6classwolf:
publicmonster:
从怪物基类派生出的狼类
新变量:
intnumberkilled;记录主动杀敌数的奇偶性,只可能为0或1,到达2则重置为0
新函数:
virtualvoidfight(monster*x)若两次主动攻击杀死对手,补血提升攻击力
7structcity:
城市的结构体,-_-|||其实做成类也行,就算是搞特殊了吧
变量:
intlife城市储存的生命源
intwhowinbefore记录是谁在之前在这个城市取得的胜利,1为红,2为蓝
intflag记录现在的旗帜颜色,0为无,1为红,2为蓝
monster*warrior[3]存储城市中怪物的指针,warrior[1]为红方怪物,warrior[2]为蓝方怪物
8voidsetcity(city&mycity):
城市的初始化函数,-_-|||那个,嗯,这个就不说了
9classcenter:
总部类
变量:
intlife存储的生命源intnumber下一个产生的怪物的编号intenemy大本营中敌人数目
intcolor颜色monster*newmonster产生的新怪物的指针
函数:
boolendgame()查看总部中敌人的数目,如果达到两个则游戏结束
monster*create()生成新怪物的函数,未生成返回NULL
10inttimefly()处理时间的函数,每次拨过10分钟。
返回值为-1—5,表示现在处于哪个时间段,-1为达到预设时间
11intmain()主函数,每个时间段进行分别的操作
00分时产生新怪物,放入头尾两个多余的城市中city[0]和city[numberofcity]
10分时怪物前进一步
20分城市产生生命源
30分怪物可能一个人深处异乡,生命源就尽收囊中
40分怪物两两厮杀,生者为王,死者就delete了
50分总部报告生命源
三、程序分析,类的说明
本题在怪物基类上派生出五种怪物的类,其中龙和狼分别增加了攻击的虚函数,忍者增加了反击的虚函数,狮子增加了受伤的虚函数,冰人增加了移动的虚函数。
在设计基类函数时,最初没有受伤函数,但是后来考虑到狮子死后要加血和课堂上的例子,做了这个特殊处理,使得程序更加清晰。
(如果不写这个函数,也可以在每次攻击前都判断被攻击者是否为狮子,如果是,记录生命值,以待死后吸血)然后很明显的有构造函数、攻击函数、反击函数。
然后是各个基类的构造,关键就是抓住每种怪物的特点,分别构造特别的虚函数,(如忍者不会反击,那么就要有特别的反击函数)这样就可以在需要的时候,系统会根据指针所指的对象,调用每个派生类自己的函数,进行特殊的操作。
而对于没有特殊要求的函数,则都默认地调用基类的函数。
怪物基类和五种怪物的类为派生关系,而新怪物的指针是由总部的类产生的,产生的怪物的指针随后被存入城市的结构体中。
在这个解题过程中,关键就是在对于怪物的处理。
光是运用结构体是不足以达到简化程序的要求的,因为那样的话我们要多写很多相似函数来方便不同的怪物来调用。
运用面向对象的思想,将函数也包含进来,当操作时,每个函数是做什么的就很明显了,这起到了很好的整合的作用。
另外,多态和动态联编的运用更是大大简化了代码的负责度。
我们不需要为诸多有很多相似的事物分别处理,而是进行统一的规划。
对于相似的对象,我们将相同的部分提取出来,作为一个公用部分,然后通过继承和派生,再加入新的部分。
这样做还有利于增加新的一类对象,对象可以有更多的变化,程序更加灵活。
四、总结与反思
这道题是典型的利用面向对象解决的题目,使用类的方式来规整变量和函数,有效地降低程序的复杂度。
这道题的主要控制是利用主函数中的switch语句来完成的,这并不是很理想的做法,但是也是很易懂的方法。
之后其实只有两种东西要处理,一个是总部,一个是怪物,城市只是提供一个场所,并不需要什么处理,所以我就把它变成了结构体,而处理的思路前边已经说得很清晰了。
这道题其实还有不少可以改进的地方,比如为了操作简便,放弃了封装,这实际上是不符合要求的。
五、附录(源代码)
#include
#include
#definenone0
#definered1
#defineblue2
usingnamespacestd;
intoriginallife;//本部的生命源
intoriginalhealth[8];//dragon、ninja、iceman、lion、wolf的生命力
intoriginalattack[8];//dragon、ninja、iceman、lion、wolf的攻击力
intnumberofcity;//城市数目
intlionhealthbefore;//狮子战斗前的生命值
inthour;//小时
intminute;//分钟
intoriginaltime;//总时长
intpasttime;//已经经过的时长
charwhichside[10][10]={"","red","blue"};
classmonster
{public:
monster(char*inputname,intinputhealth,intinputattack,intinputnumber,intinputcolor,intinputposition):
health(inputhealth),attack(inputattack),number(inputnumber),color(inputcolor),position(inputposition)
{//怪物基类的构造函数,依次初始化名字,生命值,攻击力,序号,所属阵营,所处位置
name=newchar[10];
strcpy(name,inputname);
cout<'<(2)<printf("%s%s%dborn\n",whichside[color],name,number);
}
char*name;//名字
intnumber;//编号
inthealth;//生命值
intattack;//攻击力
intposition;//所在城市编号,为红方大本营,numberofcity+1为蓝方大本营
intcolor;//所属阵营
virtualvoidmove()//控制移动的函数
{
if(color==red)//红色右移
position++;
else//蓝色左移
position--;
cout<'<(2)<if(position==numberofcity+1||position==0)//到达总部
{
printf("%s%s%dreached%sheadquarterwith%delementsandforce%d\n",whichside[color],name,number,whichside[3-color],health,attack);
deletethis;
}
else//到达城市
printf("%s%s%dmarchedtocity%dwith%delementsandforce%d\n",whichside[color],name,number,position,health,attack);
}
virtualboolhurt(intattacking)
{//受伤的函数
health-=attacking;
if(health>0)//没死
returnfalse;
else
{//死了
cout<'<(2)<printf("%s%s%dwaskilledincity%d\n",whichside[color],name,number,position);
returntrue;
}
}
virtualvoidfight(monster*x)
{//攻击函数
cout<'<(2)<printf("%s%s%dattacked%s%s%dincity%dwith%delementsandforce%d\n",whichside[color],name,number,whichside[x->color],x->name,x->number,position,health,attack);
if(!
x->hurt(attack))//没死则反击
x->fightback(this);
else
{//死了,如果是Lion,吸血
if(!
strcmp(x->name,"lion"))
health+=lionhealthbefore;
}
}
virtualvoidfightback(monster*x)
{//反击函数
cout<'<(2)<printf("%s%s%dfoughtbackagainst%s%s%dincity%d\n",whichside[color],name,number,whichside[x->color],x->name,x->number,position,health,attack);
if(x->hurt(attack/2)&&!
strcmp(x->name,"lion"))//死了,如果是Lion,吸血
health+=lionhealthbefore;
}
};
classdragon:
publicmonster//龙
{public:
dragon(char*inputname,intinputhealth,intinputattack,intinputnumber,intinputcolor,intinputposition):
monster(inputname,inputhealth,inputattack,inputnumber,inputcolor,inputposition)
{}
virtualvoidfight(monster*x)
{
monster:
:
fight(x);
if(health>0)//咆哮
{
cout<'<(2)<printf("%s%s%dyelledincity%d\n",whichside[color],name,number,position);
}
}
};
classninja:
publicmonster//忍者
{
public:
ninja(char*inputname,intinputhealth,intinputattack,intinputnumber,intinputcolor,intinputposition):
monster(inputname,inputhealth,inputattack,inputnumber,inputcolor,inputposition)
{}
virtualvoidfightback(monster*x)//我忍了
{
}
};
classiceman:
publicmonster//冰人
{
public:
iceman(char*inputname,intinputhealth,intinputattack,intinputnumber,intinputcolor,intinputposition):
monster(inputname,inputhealth,inputattack,inputnumber,inputcolor,inputposition)
{step=0;}
intstep;
virtualvoidmove()//两步自残
{
step++;
if(step==2)
{
step=0;
attack+=20;
if(health>9)
health-=9;
else
health=1;
}
monster:
:
move();
}
};
classlion:
publicmonster//狮子
{
public:
lion(char*inputname,intinputhealth,intinputattack,intinputnumber,intinputcolor,intinputposition):
monster(inputname,inputhealth,inputattack,inputnumber,inputcolor,inputposition)
{}
virtualboolhurt(intattacking)//损己利人
{
lionhealthbefore=health;//记录生命值以备吸取
returnmonster:
:
hurt(attacking);
}
};
classwolf:
publicmonster//狼
{public:
wolf(char*inputname,intinputhealth,intinputattack,intinputnumber,intinputcolor,intinputposition):
monster(inputname,inputhealth,inputattack,inputnumber,inputcolor,inputposition)
{numberkilled=0;}
intnumberkilled;
virtualvoidfight(monster*x)
{
cout<'<(2)<printf("%s%s%dattacked%s%s%dincity%dwith%delementsandforce%d\n",whichside[color],name,number,whichside[x->color],x->name,x->number,position,health,attack);
if(!
x->hurt(attack))
x->fightback(this);
else
{
numberkilled++;
if(numberkilled==2)//杀人如麻
{
health*=2;
attack*=2;
numberkilled=0;
}
if(!
strcmp(x->name,"lion"))//吸狮子血
health+=lionhealthbefore;
//deletex;
}
}
};
structcity
{
intlife;//生命源
intwhowinbefore;//记录是谁在之前在这个城市取得的胜利,为红,为蓝
intflag;//记录现在的旗帜颜色,为无,为红,为蓝
monster*warrior[3];
};
voidsetcity(city&mycity)//初始化城市的函数,传入一个引用
{
mycity.life=0;
mycity.whowinbefore=none;
mycity.flag=none;
mycity.warrior[0]=NULL;
mycity.warrior[1]=NULL;
mycity.warrior[2]=NULL;
}
classcenter
{public:
intlife;//存储的生命源
intnumber;//下一个产生的怪物的编号
intenemy;//大本营中敌人数目
intcolor;//颜色
monster*newmonster;//产生怪物的指针
center(intinputlife,intinputcolor):
life(inputlife),color(inputcolor)
{
enemy=0;
number=1;
}
boolendgame()
{
if(enemy==2)
{
cout<'<(2)<printf("%sheadquarterwastaken\n",whichside[color]);
returntrue;
}
returnfalse;
}
monster*create()//生成怪物的函数,未生成返回NULL
{
if(color==red)
{
switch(number%5)
{
case1:
if(originalhealth[2]<=life)
{newmonster=newiceman("iceman",originalhealth[2],originalattack[2],number,red,0);life-=originalhealth[2];number++;
returnnewmonster;}
break;
case2:
if(originalhealth[3]<=life){newmonster=newlion("lion",originalhealth[3],originalattack[3],number,red,0);life-=originalhealth[3];number++;
returnnewmonster;}
break;
case3:
if(originalhealth[4]<=life){newmonster=newwolf("wolf",originalhealth[4],originalattack[4],number,red,0);life-=originalhealth[4];number++;
returnnewmonster;}
break;
case4:
if(originalhealth[1]<=life){newmonster=newninja("ninja",originalhealth[1],originalattack[1],number,red,0);life-=originalhealth[1];number++;
returnnewmonster;}
break;
case0:
if(originalhealth[0]<=life){newmonster=newdragon("dragon",originalhealth[0],originalattack[0],number,red,0);life-=originalhealth[0];number++;
returnnewmonster;}
break;
default:
returnNULL;
}
}
else
{
switch(number%5)
{
case1: