一、题目分析
1、功能描述
几乎所有的RPG游戏(一种源自《龙与地下城》的游戏类型)在进入游戏时都会让用户自己来创建自己喜欢的角色。本次上机要求编写一个简化的创建游戏角色的程序。
示例:
2、游戏角色应有的属性
本题目要求的游戏角色应有以下属性:名字、性别、种族、职业、力量、敏捷、体力、智力、智慧、生命值和魔法值。
名字:不超过50个字符。
性别:可以选择男性和女性。
种族:一共可选五个种族,人类、精灵、兽人、矮人和元素。
职业:可选六种职业,狂战士、圣骑士、刺客、猎手、祭司和巫师。
其余属性均为整数。
本题目要求首先用户输入角色姓名,然后由用户选择角色性别,然后由用户选择种族,然后选择职业,然后自动分配力量、敏捷、体力、智力和智慧属性,并计算生命值和魔法值。
生命值=体力*20。
魔法值=(智力+智慧)*10。
3、职业限制
很多职业会限制某些种族选择,例如兽人不能就职圣骑士等等,种族和职业的限制表如下:
种族/职业 | 狂战士 | 圣骑士 | 刺客 | 猎手 | 祭司 | 巫师 |
---|---|---|---|---|---|---|
人类 | 允许 | 允许 | 允许 | 允许 | 允许 | 允许 |
精灵 | 不允许 | 不允许 | 允许 | 允许 | 允许 | 允许 |
兽人 | 允许 | 不允许 | 不允许 | 允许 | 允许 | 不允许 |
矮人 | 允许 | 允许 | 不允许 | 不允许 | 允许 | 不允许 |
元素 | 不允许 | 不允许 | 不允许 | 不允许 | 允许 | 允许 |
所以在要求用户选择职业时,输出信息里面只能有用户所选择种族可以就职的职业。
4、初始属性
本题目要求力量、敏捷、体力、智力和智慧要求是随机值(利用随机数函数来取得随机数),但是五项属性的总和应该是100,并且应该和职业相关。例如狂战士的体力和力量就要比较高,而巫师需要较高的智力,而祭司则需要较高的智慧。各职业初始属性的大致比例应遵从下表:
职业/属性 | 力量STR | 敏捷DEX | 体力CON | 智力INT | 智慧WIS |
---|---|---|---|---|---|
狂战士 | 40 | 20 | 30 | 5 | 5 |
圣骑士 | 25 | 15 | 30 | 20 | 10 |
刺客 | 20 | 35 | 20 | 15 | 10 |
猎手 | 15 | 40 | 15 | 10 | 20 |
祭司 | 15 | 20 | 15 | 35 | 15 |
巫师 | 10 | 20 | 10 | 20 | 40 |
例如,前面示意图中的祭司的初始属性,大致满足该比例,但是应该是随机的。
然后利用属性值计算生命值和魔法值。
5、显示信息
最后向用户显示该角色的所有信息,然后询问用户是否满意,如用户不满意则重新创建,若用户满意则程序结束,并将用户创建角色的相关信息写入文件保存。
二、类图设计
三、程序流程图
四、关键代码说明
对于生成随机数值的代码说明
1)首先在设置随机数值的成员函数中,产生一个长度为20的数组,数组内的数据均由随机数函数生成
void Player::setdata()
{
int rn[100];//随机数组
srand((unsigned int)time(NULL));
for(int i=0; i<20; i++)
{
rn[i] = rand()%5+1;
}
2)对于每个职业,由于各项的基础数值不同,可以用若干个随机数组中的数字相加作为每个数值的基础值
下以狂战士职业为例:
if(OCC == "狂战士")
{
for(int i=0; i<8; i++)
{
STR += rn[i];
}
for(int i=8; i<12; i++)
{
DEX += rn[i];
}
for(int i=12; i<18; i++)
{
CON += rn[i];
}
for(int i=18; i<19; i++)
{
INT += rn[i];
}
for(int i=19; i<20; i++)
{
WIS += rn[i];
}
}
3)对于5个数值先用一个长度为5的数值存储,然后产生5以内的随机数作为数组中的下标,以此取出随机的数组元素进行+1,直至总和为100
int data[5];//先使用数组存储5项基本数据
data[0] = STR;
data[1] = DEX;
data[2] = CON;
data[3] = INT;
data[4] = WIS;
while(data[0]+data[1]+data[2]+data[3]+data[4] != 100)
{
int i = rand()%5+1;
data[i] += 1;
}
STR = data[0];
DEX = data[1];
CON = data[2];
INT = data[3];
WIS = data[4];
HP = CON * 20;
MP = (INT + WIS) * 10;
}
全部代码
#include<iostream>
#include<cstdlib>
#include<ctime>
#include<fstream>
#include<windows.h>
using namespace std;
class Player{
public:
Player();
void setname();
void setsex();
void setrace();
void setOCC();
void setdata();
void showdata();
string get_name();
string get_sex();
string get_race();
string get_OCC();
int get_STR();
int get_DEX();
int get_CON();
int get_INT();
int get_WIS();
int get_HP();
int get_MP();
private:
string name;//姓名
string sex;//性别
string race;//种族
string OCC;//职业
int STR;//力量
int DEX;//敏捷
int CON;//体力
int INT;//智力
int WIS;//智慧
int HP;//生命值
int MP;//魔法值
};
Player::Player() //构造函数初始化成员变量
{
STR = 0;
DEX = 0;
CON = 0;
INT = 0;
WIS = 0;
HP = 0;
MP = 0;
}
void Player::setname()
{
cout<<"请输入姓名:";
cin>>name;
while(name.size() > 50)
{
cout<<"名字过长,请重新输入:";
cin>>name;
}
}
void Player::setsex()
{
cout<<"请选择性别(0:男性,1:女性):";
int choose;
cin>>choose;
while(choose<0||choose>1)
{
cout<<"输入有误,请重新输入:";
cin>>choose;
}
if(choose == 0)
{
sex = "男性";
}
else if(choose == 1)
{
sex = "女性";
}
else
{
cout<<"输入错误!!!";
}
}
void Player::setrace()
{
cout<<"请选择种族(0:人类,1:精灵,2:兽人,3:矮人,4:元素):";
int choose;
cin>>choose;
while(choose<0||choose>4)
{
cout<<"输入有误,请重新输入:";
cin>>choose;
}
if(choose == 0)
{
race = "人类";
}
else if(choose == 1)
{
race = "精灵";
}
else if(choose == 2)
{
race = "兽人";
}
else if(choose == 3)
{
race = "矮人";
}
else if(choose == 4)
{
race = "元素";
}
else
{
cout<<endl<<"输入错误!";
}
}
void Player::setOCC()
{
int choose;
if(race == "人类")
{
cout<<"请选择种族(0:狂战士,1:圣骑士,2:刺客,3:猎手,4:祭司,5:巫师):";
cin>>choose;
while(choose<0||choose>5)
{
cout<<"输入有误,请重新输入:";
cin>>choose;
}
if(choose == 0)
{
OCC = "狂战士";
}
else if(choose == 1)
{
OCC = "圣骑士";
}
else if(choose == 2)
{
OCC = "刺客";
}
else if(choose == 3)
{
OCC = "猎手";
}
else if(choose == 4)
{
OCC = "祭司";
}
else if(choose == 5)
{
OCC = "巫师";
}
}
if(race == "精灵")
{
cout<<"请选择种族(0:刺客,1:猎手,2:祭司,3:巫师):";
cin>>choose;
while(choose<0||choose>3)
{
cout<<"输入有误,请重新输入:";
cin>>choose;
}
if(choose == 0)
{
OCC = "刺客";
}
else if(choose == 1)
{
OCC = "猎手";
}
else if(choose == 2)
{
OCC = "祭司";
}
else if(choose == 3)
{
OCC = "巫师";
}
}
if(race == "兽人")
{
cout<<"请选择种族(0:狂战士,1:猎手,2:祭司):";
cin>>choose;
while(choose<0||choose>2)
{
cout<<"输入有误,请重新输入:";
cin>>choose;
}
if(choose == 0)
{
OCC = "狂战士";
}
else if(choose == 1)
{
OCC = "猎手";
}
else if(choose == 2)
{
OCC = "祭司";
}
}
if(race == "矮人")
{
cout<<"请选择种族(0:狂战士,1:圣骑士,2:祭司):";
cin>>choose;
while(choose<0||choose>2)
{
cout<<"输入有误,请重新输入:";
cin>>choose;
}
if(choose == 0)
{
OCC = "狂战士";
}
else if(choose == 1)
{
OCC = "圣骑士";
}
else if(choose == 2)
{
OCC = "祭司";
}
}
if(race == "元素")
{
cout<<"请选择种族(0:祭司,1:巫师):";
cin>>choose;
while(choose<0||choose>1)
{
cout<<"输入有误,请重新输入:";
cin>>choose;
}
if(choose == 0)
{
OCC = "祭司";
}
else if(choose == 1)
{
OCC = "巫师";
}
}
}
void Player::setdata()
{
int rn[100];//随机数组
srand((unsigned int)time(NULL));
for(int i=0; i<20; i++)
{
rn[i] = rand()%5+1;
}
if(OCC == "狂战士")
{
for(int i=0; i<8; i++)
{
STR += rn[i];
}
for(int i=8; i<12; i++)
{
DEX += rn[i];
}
for(int i=12; i<18; i++)
{
CON += rn[i];
}
for(int i=18; i<19; i++)
{
INT += rn[i];
}
for(int i=19; i<20; i++)
{
WIS += rn[i];
}
}
if(OCC == "圣骑士")
{
for(int i=0; i<5; i++)
{
STR += rn[i];
}
for(int i=5; i<8; i++)
{
DEX += rn[i];
}
for(int i=8; i<14; i++)
{
CON += rn[i];
}
for(int i=14; i<18; i++)
{
INT += rn[i];
}
for(int i=18; i<20; i++)
{
WIS += rn[i];
}
}
if(OCC == "刺客")
{
for(int i=0; i<4; i++)
{
STR += rn[i];
}
for(int i=4; i<11; i++)
{
DEX += rn[i];
}
for(int i=11; i<15; i++)
{
CON += rn[i];
}
for(int i=15; i<18; i++)
{
INT += rn[i];
}
for(int i=18; i<20; i++)
{
WIS += rn[i];
}
}
if(OCC == "猎手")
{
for(int i=0; i<3; i++)
{
STR += rn[i];
}
for(int i=3; i<11; i++)
{
DEX += rn[i];
}
for(int i=11; i<14; i++)
{
CON += rn[i];
}
for(int i=14; i<16; i++)
{
INT += rn[i];
}
for(int i=16; i<20; i++)
{
WIS += rn[i];
}
}
if(OCC == "祭司")
{
for(int i=0; i<3; i++)
{
STR += rn[i];
}
for(int i=3; i<7; i++)
{
DEX += rn[i];
}
for(int i=7; i<10; i++)
{
CON += rn[i];
}
for(int i=10; i<17; i++)
{
INT += rn[i];
}
for(int i=17; i<20; i++)
{
WIS += rn[i];
}
}
if(OCC == "巫师")
{
for(int i=0; i<2; i++)
{
STR += rn[i];
}
for(int i=2; i<6; i++)
{
DEX += rn[i];
}
for(int i=6; i<8; i++)
{
CON += rn[i];
}
for(int i=8; i<12; i++)
{
INT += rn[i];
}
for(int i=12; i<20; i++)
{
WIS += rn[i];
}
}
int data[5];//先使用数组存储5项基本数据
data[0] = STR;
data[1] = DEX;
data[2] = CON;
data[3] = INT;
data[4] = WIS;
/*for(int i=0;i<5;i++) //检测生成的随机数是否为随机
{
cout<<data[i]<<endl;
}*/
while(data[0]+data[1]+data[2]+data[3]+data[4] != 100)//对数组中的随机数值+1,直至总和为100
{
int i = rand()%5+1;
data[i] += 1;
}
STR = data[0];//将数组输出到属性中
DEX = data[1];
CON = data[2];
INT = data[3];
WIS = data[4];
HP = CON * 20;
MP = (INT + WIS) * 10;
}
void Player::showdata()
{
cout<<"姓名:"<<name<<endl;
cout<<"性别:"<<sex<<endl;
cout<<"种族:"<<race<<endl;
cout<<"职业:"<<OCC<<endl;
cout<<"力量:"<<STR<<endl;
cout<<"敏捷:"<<DEX<<endl;
cout<<"体力:"<<CON<<endl;
cout<<"智力:"<<INT<<endl;
cout<<"智慧:"<<WIS<<endl;
cout<<"生命值:"<<HP<<endl;
cout<<"魔法值:"<<MP<<endl;
}
string Player::get_name()
{
return name;
}
string Player::get_sex()
{
return sex;
}
string Player::get_race()
{
return race;
}
string Player::get_OCC()
{
return OCC;
}
int Player::get_STR()
{
return STR;
}
int Player::get_DEX()
{
return DEX;
}
int Player::get_CON()
{
return CON;
}
int Player::get_INT()
{
return INT;
}
int Player::get_WIS()
{
return WIS;
}
int Player::get_HP()
{
return HP;
}
int Player::get_MP()
{
return MP;
}
int main()
{
int flag = 1;
int choose;
while(flag)
{
Player player;
cout<<"========创建新角色:========"<<endl;
player.setname();
player.setsex();
player.setrace();
player.setOCC();
player.setdata();
cout<<""<<endl;
cout<<"========角色属性表========="<<endl;
player.showdata();
cout<<"==========================="<<endl;
cout<<"是否重新生成人物?(将保存人物)(0是,1否)";
cin>>choose;
if(choose == 0)
{
flag = 1;
}
else if(choose == 1)
{
ofstream outfile("player.dat");
if(!outfile)
{
cerr<<"open player.dat error!";
}
outfile<<"========角色属性表========="<<endl;
outfile<<"姓名:"<<player.get_name()<<endl;
outfile<<"性别:"<<player.get_sex()<<endl;
outfile<<"种族:"<<player.get_race()<<endl;
outfile<<"职业:"<<player.get_OCC()<<endl;
outfile<<"力量:"<<player.get_STR()<<endl;
outfile<<"敏捷:"<<player.get_DEX()<<endl;
outfile<<"体力:"<<player.get_CON()<<endl;
outfile<<"智力:"<<player.get_INT()<<endl;
outfile<<"智慧:"<<player.get_WIS()<<endl;
outfile<<"生命值:"<<player.get_HP()<<endl;
outfile<<"魔法值:"<<player.get_MP()<<endl;
flag = 0;
cout<<"保存中";//模拟存储过程
Sleep(1000);
cout<<".";
Sleep(1000);
cout<<".";
Sleep(1000);
cout<<"."<<endl;
Sleep(1000);
cout<<"保存成功!";
}
}
}
五、调试、测试及运行过程
1)调试过程
未输入数据前:
输入数据并生成随机数据后:
2)测试过程
1、名字输入过长
2、输入选项不正确
3)运行过程
1、程序运行界面
2、保存文件
六、经验总结
这是我第一次使用类的方法实现程序的功能,我对于使用面向对象的程序编程有了更加深刻的体会,并且在这次作业中对于类的定义、初始化和函数的运用有了一定的理解,而且复习了C++的文件操作和随机数生成的相关原理,更加进一步的了解了面向对象的程序编程的思想。