task2
题目要求
源码
main.cpp
#include <iostream>
#include <fstream>
#include <vector>
#include "Person.hpp"
int main()
{
using namespace std;
vector<Person> phone_book;
Person p;
while(cin>>p)
phone_book.push_back(p);
for(auto &i: phone_book)
cout << i << endl;
cout << boolalpha << (phone_book.at(0) == phone_book.at(1)) << endl;
phone_book.at(0).changeEmail();
phone_book.at(0).changeTel();
for(auto &i: phone_book)
cout << i << endl;
ofstream fout;
fout.open("phone_book.txt");
if(!fout.is_open())
{
cerr << "fail to open file phone_book.txt\n";
return 1;
}
for(auto &i: phone_book)
fout << i << endl;
fout.close();
}
Person.hpp
#include <iostream>
#include <string>
#include <istream>
#include <ostream>
using namespace std;
class Person{
private:
string name, telephone, email;
public:
Person(){}
Person(string name, string telephone, string email=""){
this->name = name;
this->telephone = telephone;
this->email = email;
}
void changeEmail(){
cin.clear();
cout << "请输入修改后的邮箱号码:";
cin >> email;
}
void changeTel(){
cin.clear();
cout << "请输入修改后的电话号码:";
cin >> telephone;
}
friend ostream& operator<<(ostream& os, const Person &p){
os << p.name << "\t" << p.telephone << "\t" << p.email;
return os;
}
friend istream& operator>>(istream& os, Person &p){
os >> p.name >> p.telephone >> p.email;
return os;
}
friend bool operator==(const Person &p1, const Person &p2){
return (p1.name == p2.name && p1.telephone == p2.telephone);
}
};
运行截图
总结
- 测试了两个修改接口
task3
题目要求
说明
- 进行填补和进一步的改进的基础建立在需要从宏观上了解整个项目的构成和逻辑关系,基本思路是通过
.h
头文件中类提供的接口来判断有哪些功能和互相调用的逻辑关系。 - 本来想进行汉化工作,但由于我的测试平台是在macOS,等宽字体的问题和win不能很好地适配
- 在基本的代码填补后的测试中发现,游戏存在部分平衡性问题和bug。在此基础上进行了如下平衡性修改:
- 增加了单次特殊攻击魔力值消耗设定的接口
- 增加每次玩家和enemy操作后魔力值自动回复的功能(enemy恢复能力为玩家的一半)
- 删除了AI生命小于百分之五十情况下无法发动特殊攻击的情况
- 修复了enemy发动特殊攻击条件中的概率错误的bug,并调整为60%
- 改善了enemy的AI,能在等待一回合的自动恢复法力和使用法力药水之间平衡
- 调整玩家每次升级后的生命、法力上限提升和速度提升幅度
- 增加了每次玩家升级后血量和法力值部分恢复的功能
- 调整AI使用物品的逻辑,防止击败enemy后大概率无法获得奖励物品
源码
由于代码过长,仅展示部分,其余请右击下列文件保存
main.cpp |player.h |player.cpp |container.h |container.cpp |swordsman.h |swordsman.cpp
main.cpp
//=======================
// main.cpp
//=======================
// main function for the RPG style game
#include <iostream>
#include <string>
using namespace std;
#include "swordsman.h"
int specialatt_consume = 40; // 单次发动特殊攻击消耗的魔法值
int MP_autoResume = 10; // 每回合法力值自动回复点数
int main()
{
string tempName;
bool success=0; //flag for storing whether operation is successful
cout <<"Please input player's name: ";
************
************
player.h
//=======================
// player.h
//=======================
// The base class of player
// including the general properties and methods related to a character
#ifndef _PLAYER
#define _PLAYER
#include <iomanip> // use for setting field width
#include <time.h> // use for generating random factor
#include "container.h"
#include <string>
#include <iostream>
using namespace std;
enum job {sw, ar, mg}; /* define 3 jobs by enumerate type
sword man, archer, mage */
class player
************
************
player.cpp
//=======================
// player.cpp
//=======================
extern int MP_autoResume;
// character's HP and MP resume
#include "player.h"
#include <iostream>
using namespace std;
void player::MPResume()
{
MP += MP_autoResume;
}
void player::reFill()
{
HP=HPmax; // HP and MP fully recovered
MP=MPmax;
}
************
************
container.h
//=======================
// container.h
//=======================
// The so-called inventory of a player in RPG games
// contains two items, heal and magic water
#ifndef _CONTAINER // Conditional compilation
#define _CONTAINER
class container // Inventory
{
protected:
int numOfHeal; // number of heal
int numOfMW; // number of magic water
public:
container(); // constuctor
void set(int heal_n, int mw_n); // set the items numbers
int nOfHeal(); // get the number of heal
int nOfMW(); // get the number of magic water
************
************
container.cpp
//=======================
// player.cpp
//=======================
extern int MP_autoResume;
// character's HP and MP resume
#include "player.h"
#include <iostream>
using namespace std;
void player::MPResume()
{
MP += MP_autoResume;
}
void player::reFill()
{
HP=HPmax; // HP and MP fully recovered
MP=MPmax;
}
************
************
swordsman.h
//=======================
// swordsman.h
//=======================
// Derived from base class player
// For the job Swordsman
#include "player.h"
#include <iostream>
using namespace std;
class swordsman : public player // subclass swordsman publicly inherited from base player
{
public:
swordsman(int lv_in=1, string name_in="Not Given");
// constructor with default level of 1 and name of "Not given"
void isLevelUp();
bool attack (player &p);
bool specialatt(player &p);
/* These three are derived from the pure virtual functions of base class
The definition of them will be given in this subclass. */
void AI(player &p); // Computer opponent
};
swordsman.cpp
//=======================
// swordsman.cpp
//=======================
// constructor. default values don't need to be repeated here
extern int specialatt_consume;
extern int MP_autoResume;
#include "swordsman.h"
#include <iostream>
using namespace std;
swordsman::swordsman(int lv_in, string name_in)
{
role=sw; // enumerate type of job
LV=lv_in;
name=name_in;
// Initialising the character's properties, based on his level
HPmax=150+8*(LV-1); // HP increases 8 point2 per level
************
************
运行结果
-
请自行build测试或直接下载打包文件
macOS环境需将main.cpp中所有cls替换为clear
总结
- 依旧是对于基类与派生类的逻辑关系需要厘清