C++基础教程面向对象(学习笔记(52))

综合测验

Summary

继承允许我们模拟两个对象之间的is-a关系。从中继承的对象称为父类,基类。执行继承的对象称为子类,派生类或子类。

当派生类继承自基类时,派生类将获取基类的所有成员。

构造派生类时,首先构造类的基类部分,然后构造派生部分。更详细为:

#预留派生类的内存(对于基本部分和派生部分都足够)。
#调用适当的派生类构造函数。
#首先使用适当的基类构造函数构造基类对象。如果未指定基类构造函数,则将使用默认构造函数。
#派生类的初始化列表初始化派生类的成员。
#派生类构造函数的主体执行。
#控制权返回给调用者。
#破坏以相反的顺序发生,从大多数派生到最基础的阶级。

C ++有3个访问说明符:public,private和protected。受保护的访问说明符允许成员所属的类,友元函数和派生类访问受保护的成员,而不是公共成员。

类可以公开,私有或受保护地从另一个类继承。类几乎总是公开继承。

这是一个包含所有访问说明符和继承类型组合的表:

基类中的访问说明符公开继承时的访问说明符私有继承时的访问说明符受保护地继承时的访问说明符
public公开私有的受保护的
private无法访问无法访问无法访问
protected受保护私有的受保护

派生类可以添加新函数,更改派生类中基类工作中存在的函数的方式,更改继承成员的访问级别或隐藏功能。

多重继承使派生类可以从多个父级继承成员。您应该尽可能避免多重继承。

Quiz Time

1)对于以下每个程序,确定它们输出的内容,或者它们是否不能编译,指出原因。这个练习是通过检查来完成的,所以不要编译这些(答案是微不足道的)。
1A)

#include <iostream>
 
class Base
{
public:
	Base()
	{
		std::cout << "Base()\n";
	}
	~Base()
	{
		std::cout << "~Base()\n";
	}
};
 
class Derived: public Base
{
public:
	Derived()
	{
		std::cout << "Derived()\n";
	}
	~Derived()
	{
		std::cout << "~Derived()\n";
	}
};
 
int main()
{
	Derived d;
}

解决方案

构造按照从大多数父类到大多数子类的顺序进行。销毁以相反的顺序发生。
Base()
Derived()
~Derived()
~Base()
1b)

#include <iostream>
 
class Base
{
public:
	Base()
	{
		std::cout << "Base()\n";
	}
	~Base()
	{
		std::cout << "~Base()\n";
	}
};
 
class Derived: public Base
{
public:
	Derived()
	{
		std::cout << "Derived()\n";
	}
	~Derived()
	{
		std::cout << "~Derived()\n";
	}
};
 
int main()
{
	Derived d;
	Base b;
}

提示:局部变量以与定义相反的顺序销毁。

解决方案
首先我们构造d,打印:
Base()
Derived()
然后我们构造b,打印:

Base()
然后我们破坏b,打印:

〜Base()
然后我们破坏d,打印:

~Derived()
〜Base()
1C)

#include <iostream>
 
class Base
{
private:
	int m_x;
public:
	Base(int x): m_x(x)
	{
		std::cout << "Base()\n";
	}
	~Base()
	{
		std::cout << "~Base()\n";
	}
 
	void print() { std::cout << "Base: " << m_x << '\n';  }
};
 
class Derived: public Base
{
public:
	Derived(int y):  Base(y)
	{
		std::cout << "Derived()\n";
	}
	~Derived()
	{
		std::cout << "~Derived()\n";
	}
 
	void print() { std::cout << "Derived: " << m_x << '\n'; }
};
 
int main()
{
	Derived d(5);
	d.print();
}

解决方案

不编译,Derived :: print()无法访问私有成员m_x

1D)

#include <iostream>
 
class Base
{
protected:
	int m_x;
public:
	Base(int x): m_x(x)
	{
		std::cout << "Base()\n";
	}
	~Base()
	{
		std::cout << "~Base()\n";
	}
 
	void print() { std::cout << "Base: " << m_x << '\n';  }
};
 
class Derived: public Base
{
public:
	Derived(int y):  Base(y)
	{
		std::cout << "Derived()\n";
	}
	~Derived()
	{
		std::cout << "~Derived()\n";
	}
 
	void print() { std::cout << "Derived: " << m_x << '\n'; }
};
 
int main()
{
	Derived d(5);
	d.print();
}

解决方案

Base()
Derived()
Derived:5
~Derived()
~Base()

1E)

#include <iostream>
 
class Base
{
protected:
	int m_x;
public:
	Base(int x): m_x(x)
	{
		std::cout << "Base()\n";
	}
	~Base()
	{
		std::cout << "~Base()\n";
	}
 
	void print() { std::cout << "Base: " << m_x << '\n';  }
};
 
class Derived: public Base
{
public:
	Derived(int y):  Base(y)
	{
		std::cout << "Derived()\n";
	}
	~Derived()
	{
		std::cout << "~Derived()\n";
	}
 
	void print() { std::cout << "Derived: " << m_x << '\n'; }
};
 
class D2 : public Derived
{
public:
	D2(int z): Derived(z)
	{
		std::cout << "D2()\n";
	}
	~D2()
	{
		std::cout << "~D2()\n";
	}
 
        // 注意:这里没有print()函数
};
 
int main()
{
	D2 d(5);
	d.print();
}

隐藏解决方案

Base()
Derived()
D2()
Derived:5
~D2()
〜Derived()
~Base()
2a)编写一个源自常见Fruit类的Apple类和Banana类。Fruit应该有两个成员:名称和颜色。

应运行以下程序:

int main()
{
	Apple a("red");
	Banana b;
 
	std::cout << "My " << a.getName() << " is " << a.getColor() << ".\n";
	std::cout << "My " << b.getName() << " is " << b.getColor() << ".\n";
	
	return 0;
}

并产生结果:

My apple is red.
My banana is yellow.

解决方案

#include <iostream>
#include <string>
 
class Fruit
{
private:
	std::string m_name;
	std::string m_color;
 
public:
	Fruit(std::string name, std::string color)
		: m_name(name), m_color(color)
	{
 
	}
 
	std::string getName() { return m_name; }
	std::string getColor() { return m_color; }
};
 
class Apple: public Fruit
{
public:
	Apple(std::string color="red")
		: Fruit("apple", color)
	{
	}
};
 
class Banana : public Fruit
{
public:
	Banana()
		: Fruit("banana", "yellow")
	{
 
	}
};
 
int main()
{
	Apple a("red");
	Banana b;
 
	std::cout << "My " << a.getName() << " is " << a.getColor() << ".\n";
	std::cout << "My " << b.getName() << " is " << b.getColor() << ".\n";
	
	return 0;
}

2b)在以前的程序中添加一个新类,该程序名为GrannySmith,继承自Apple。

应运行以下程序:

int main()
{
	Apple a("red");
	Banana b;
	GrannySmith c;
 
	std::cout << "My " << a.getName() << " is " << a.getColor() << ".\n";
	std::cout << "My " << b.getName() << " is " << b.getColor() << ".\n";
	std::cout << "My " << c.getName() << " is " << c.getColor() << ".\n";
	
	return 0;
}

并产生结果:

My apple is red.
My banana is yellow.
My granny smith apple is green.
解决方案

#include <iostream>
#include <string>
 
class Fruit
{
private:
	std::string m_name;
	std::string m_color;
 
public:
	Fruit(std::string name, std::string color)
		: m_name(name), m_color(color)
	{
 
	}
 
	std::string getName() { return m_name; }
	std::string getColor() { return m_color; }
};
 
class Apple: public Fruit
{
// 我们用于Apple的前一个构造函数有一个固定的名称(“apple”)。
// 我们需要一个新的GrannySmith构造函数来设置水果的名称
protected: // 受保护,因此只有派生类可以访问
	Apple(std::string name, std::string color)
		: Fruit(name, color)
	{
	}
 
public:
	Apple(std::string color="red")
		: Fruit("apple", color)
	{
	}
};
 
class Banana : public Fruit
{
public:
	Banana()
		: Fruit("banana", "yellow")
	{
 
	}
};
 
class GrannySmith : public Apple
{
public:
	GrannySmith()
		: Apple("granny smith apple", "green")
	{
 
	}
};
 
int main()
{
	Apple a("red");
	Banana b;
	GrannySmith c;
 
	std::cout << "My " << a.getName() << " is " << a.getColor() << ".\n";
	std::cout << "My " << b.getName() << " is " << b.getColor() << ".\n";
	std::cout << "My " << c.getName() << " is " << c.getColor() << ".\n";
 
	return 0;
}

3)挑战时间!以下测验问题更加困难和冗长。我们打算写一个简单的游戏来对抗怪物。游戏的目标是在你死之前收集尽可能多的金币或者达到20级。

我们的程序将包含3个类:一个Creature类,一个Player类和一个Monster类。玩家和怪物都继承自生物。

3a)首先创建Creature类。生物有5个属性:一个名字(std :: string),一个符号(一个char),一个生命值(int),它们每次攻击所造成的伤害量(int),以及它们携带的金币( INT)。将它们作为类成员实现。编写一整套getter(每个成员的get函数)。添加其他三个函数:void reduceHealth(int)将生物的生命值降低整数。当Creature的生命值为0或更低时,bool isDead()返回true。void addGold(int)为生物添加金币。

应运行以下程序:

#include <iostream>
#include <string>
 
int main()
{
	Creature o("orc", 'o', 4, 2, 10);
	o.addGold(5);
	o.reduceHealth(1);
	std::cout << "The " << o.getName() << " has " << o.getHealth() << " health and is carrying " << o.getGold() << " gold.\n.";
 
	return 0;
}

并产生结果:

The has 3 health and is carrying 15 gold.
解决方案

#include <iostream>
#include <string>
 
class Creature
{
protected:
	std::string m_name;
	char m_symbol;
	int m_health;
	int m_damage;
	int m_gold;
 
public:
	Creature(std::string name, char symbol, int health, int damage, int gold) :
		m_name(name), m_symbol(symbol), m_health(health), m_damage(damage), m_gold(gold)
	{
	}
 
	const std::string& getName() { return m_name; }
	char getSymbol() { return m_symbol; }
	int getHealth() { return m_health; }
	int getDamage() { return m_damage; }
	int getGold() { return m_gold; }
 
	void reduceHealth(int health) { m_health -= health; }
	bool isDead() { return m_health <= 0; }
	void addGold(int gold) { m_gold += gold; }
};
 
int main()
{
	Creature o("orc", 'o', 4, 2, 10);
	o.addGold(5);
	o.reduceHealth(1);
	std::cout << "The " << o.getName() << " has " << o.getHealth() << " health and is carrying " << o.getGold() << " gold.\n.";
 
	return 0;
}

3b)现在我们要创建Player类。Player类继承自Creature。玩家有一个额外的成员,玩家的等级,从1开始。玩家有一个自定义名称(由用户输入),使用符号’@’,有10个生命值,1个伤害开始,并且没有金币。编写一个名为levelUp()的函数,将玩家的等级和伤害提高1.还为级别成员编写一个getter。最后,编写一个名为hasWon()的函数,如果玩家达到20级则返回true。

编写一个新的main()函数,询问用户的名称并生成输出,如下所示:

Enter your name: Alex
Welcome, Alex.
You have 10 health and are carrying 0 gold.
解决方案

#include <iostream>
#include <string>
 
class Creature
{
protected:
	std::string m_name;
	char m_symbol;
	int m_health;
	int m_damage;
	int m_gold;
 
public:
	Creature(std::string name, char symbol, int health, int damage, int gold) :
		m_name(name), m_symbol(symbol), m_health(health), m_damage(damage), m_gold(gold)
	{
	}
 
	const std::string& getName() { return m_name; }
	char getSymbol() { return m_symbol; }
	int getHealth() { return m_health; }
	int getDamage() { return m_damage; }
	int getGold() { return m_gold; }
 
	void reduceHealth(int health) { m_health -= health; }
	bool isDead() { return m_health <= 0; }
	void addGold(int gold) { m_gold += gold; }
};
 
class Player : public Creature
{
	int m_level = 1;
 
public:
	Player(std::string name)
		: Creature(name, '@', 10, 1, 0)
	{
	}
 
	void levelUp()
	{
		++m_level;
		++m_damage;
	}
 
	int getLevel() { return m_level; }
	bool hasWon() { return m_level >= 20; }
};
 
int main()
{
	std::cout << "Enter your name: ";
	std::string playerName;
	std::cin >> playerName;
 
	Player p(playerName);
	std::cout << "Welcome, " << p.getName() << ".\n";
 
	std::cout << "You have " << p.getHealth() << " health and are carrying " << p.getGold() << " gold.\n.";
 
	return 0;
}

3c)接下来是怪物类。怪物也继承了生物。怪物没有非继承的成员变量。

首先,编写一个继承自Creature的空Monster类,然后在名为Type的Monster类中添加一个枚举,其中包含我们将在此游戏中拥有的3个怪物的枚举器:DRAGON,ORC和SLIME(您还需要一个MAX_TYPES枚举器,因为它会派上用场。)

解决方案

class Monster : public Creature
{
public:
	enum Type
	{
		DRAGON,
		ORC,
		SLIME,
		MAX_TYPES
	};
};

3d)每个怪物类型将具有不同的名称,符号,开始健康,黄金和伤害。这是每个怪物类型的统计表:

TypeNameSymbolHealthDamageGold
DRAGONdragonD204100
ORCorco4225
SLIMEslimes1110

下一步是编写一个Monster构造函数,这样我们就可以创建怪物了。Monster构造函数应该使用Type枚举作为参数,然后创建一个具有该类怪物的相应统计数据的Monster。

有许多不同的方法可以实现这一点(一些更好,一些更糟)。但是在这种情况下,因为我们所有的怪物属性都是预定义的(不是随机的),我们将使用查找表。查找表是包含所有预定义属性的数组。我们可以根据需要使用查找表来查找给定怪物的属性。

那么我们如何实现这个查找表呢?这并不难。我们只需要两件事。首先,我们需要一个包含每个怪物Type的元素的数组。每个数组元素都将包含一个结构,其中包含该类型的Monster的所有预定义属性值。

第1步:在名为MonsterData的Monster中创建一个结构类型。此结构应具有每个属性的成员(名称,符号,运行状况,损坏和黄金)。
步骤2:将该结构的数组声明为名为monsterData的类的静态成员(将其声明为普通数组成员,然后在其之前添加单词static)。
第3步:在类之外添加以下代码。这是我们的查找表的定义:

Monster::MonsterData Monster::monsterData[Monster::MAX_TYPES]
{
	{ "dragon", 'D', 20, 4, 100 },
	{ "orc", 'o', 4, 2, 25 },
	{ "slime", 's', 1, 1, 10 }
};

现在我们可以索引这个数组来查找我们需要的任何值!例如,要获得Dragon的金币,我们可以访问monsterData [DRAGON] .gold。

使用此查找表来实现构造函数:

Monster(Type type): Creature(monsterData[type].name, ...)

以下程序应编译:

#include <iostream>
#include <string>
 
int main()
{
	Monster m(Monster::ORC);
	std::cout << "A " << m.getName() << " (" << m.getSymbol() << ") was created.\n";
}

并打印:

创建了一个orc(o)。
解决方案

#include <iostream>
#include <string>
 
class Creature
{
protected:
	std::string m_name;
	char m_symbol;
	int m_health;
	int m_damage;
	int m_gold;
 
public:
	Creature(std::string name, char symbol, int health, int damage, int gold) :
		m_name(name), m_symbol(symbol), m_health(health), m_damage(damage), m_gold(gold)
	{
	}
 
	const std::string& getName() { return m_name; }
	char getSymbol() { return m_symbol; }
	int getHealth() { return m_health; }
	int getDamage() { return m_damage; }
	int getGold() { return m_gold; }
 
	void reduceHealth(int health) { m_health -= health; }
	bool isDead() { return m_health <= 0; }
	void addGold(int gold) { m_gold += gold; }
};
 
class Player : public Creature
{
	int m_level = 1;
 
public:
	Player(std::string name)
		: Creature(name, '@', 10, 1, 0)
	{
	}
 
	void levelUp()
	{
		++m_level;
		++m_damage;
	}
 
	int getLevel() { return m_level; }
};
 
class Monster : public Creature
{
public:
	enum Type
	{
		DRAGON,
		ORC,
		SLIME,
		MAX_TYPES
	};
 
	struct MonsterData
	{
		const char* name;
		char symbol;
		int health;
		int damage;
		int gold;
	};
 
	static MonsterData monsterData[MAX_TYPES];
 
	Monster(Type type)
		: Creature(monsterData[type].name, monsterData[type].symbol, monsterData[type].health, monsterData[type].damage, monsterData[type].gold)
	{
	}
};
 
Monster::MonsterData Monster::monsterData[Monster::MAX_TYPES]
{
	{ "dragon", 'D', 20, 4, 100 },
	{ "orc", 'o', 4, 2, 25 },
	{ "slime", 's', 1, 1, 10 }
};
 
int main()
{
	Monster m(Monster::ORC);
	std::cout << "A " << m.getName() << " (" << m.getSymbol() << ") was created.\n";
 
	return 0;
}

3e)最后,向名为getRandomMonster()的Monster添加一个静态函数。此函数应选择0和MAX_TYPES-1之间的随机数,并返回一个具有该类型的怪物(按值)(您需要将int static_cast到一个Type以将其传递给Monster构造函数)。

您可以使用以下代码选择一个随机数:

#include <cstdlib> //rand() 和srand()
#include <ctime> // time()
 
// 生成最小和最大(包括)之间的随机数
// 假设已经调用了srand()
int getRandomNumber(int min, int max)
{
	static const double fraction = 1.0 / (static_cast<double>(RAND_MAX) + 1.0);  //static用于效率,所以我们只计算一次这个值
	// 在我们的范围内均匀分布随机数
	return static_cast<int>(rand() * fraction * (max - min + 1) + min);
}

应运行以下主要功能:

#include <iostream>
#include <string>
#include <cstdlib> // rand() 和srand()
#include <ctime> //  time()
 
int main()
{
	srand(static_cast<unsigned int>(time(0))); // 将初始值设置为系统时钟
	rand(); // get rid of first result
 
	for (int i = 0; i < 10; ++i)
	{
		Monster m = Monster::getRandomMonster();
		std::cout << "A " << m.getName() << " (" << m.getSymbol() << ") was created.\n";
	}
 
	return 0;
}

该计划的结果应该是随机的。

解决方案

#include <iostream>
#include <string>
#include <cstdlib> //  rand() 和srand()
#include <ctime> //  time()
 
// 生成最小和最大(包括)之间的随机数
// 假设已经调用了srand()
int getRandomNumber(int min, int max)
{
	static const double fraction = 1.0 / (static_cast<double>(RAND_MAX) + 1.0);  //static用于效率,所以我们只计算一次这个值
	// 在我们的范围内均匀分布随机数
	return static_cast<int>(rand() * fraction * (max - min + 1) + min);
}
 
class Creature
{
protected:
	std::string m_name;
	char m_symbol;
	int m_health;
	int m_damage;
	int m_gold;
 
public:
	Creature(std::string name, char symbol, int health, int damage, int gold) :
		m_name(name), m_symbol(symbol), m_health(health), m_damage(damage), m_gold(gold)
	{
	}
 
	char getSymbol() { return m_symbol; }
	const std::string& getName() { return m_name; }
	bool isDead() { return m_health <= 0; }
	int getGold() { return m_gold; }
	void addGold(int gold) { m_gold += gold;  }
	void reduceHealth(int health) { m_health -= health;  }
	int getHealth() { return m_health; }
	int getDamage() { return m_damage;  }
};
 
class Player : public Creature
{
	int m_level = 1;
 
public:
	Player(std::string name)
		: Creature(name, '@', 10, 1, 0)
	{
	}
 
	void levelUp()
	{
		++m_level;
		++m_damage;
	}
 
	int getLevel() { return m_level; }
	bool hasWon() { return m_level >= 20; }
};
 
class Monster : public Creature
{
public:
	enum Type
	{
		DRAGON,
		ORC,
		SLIME,
		MAX_TYPES
	};
 
	struct MonsterData
	{
		const char* name;
		char symbol;
		int health;
		int damage;
		int gold;
	};
 
	static MonsterData monsterData[MAX_TYPES];
 
	Monster(Type type)
		: Creature(monsterData[type].name, monsterData[type].symbol, monsterData[type].health, monsterData[type].damage, monsterData[type].gold)
	{
	}
 
	static Monster getRandomMonster()
	{
		int num = getRandomNumber(0, MAX_TYPES - 1);
		return Monster(static_cast<Type>(num));
	}
};
 
Monster::MonsterData Monster::monsterData[Monster::MAX_TYPES]
{
	{ "dragon", 'D', 20, 4, 100 },
	{ "orc", 'o', 4, 2, 25 },
	{ "slime", 's', 1, 1, 10 }
};
 
int main()
{
	srand(static_cast<unsigned int>(time(0))); // 将初始值设置为系统时钟
	rand(); // get rid of first result
 
	for (int i = 0; i < 10; ++i)
	{
		Monster m = Monster::getRandomMonster();
		std::cout << "A " << m.getName() << " (" << m.getSymbol() << ") was created.\n";
	}
 
	return 0;
}

3f)我们终于开始编写我们的游戏逻辑了!

以下是游戏规则:

玩家一次遇到一个随机生成的怪物。
对于每个怪物,玩家有两种选择:(R)un或(F)ight。
如果玩家决定参加比赛,他们有50%的机会逃跑。
如果玩家逃脱,他们移动到下一次遭遇将不会产生不良影响。
如果玩家没有逃脱,则怪物获得自由攻击,并且玩家选择他们的下一个动作。
如果玩家选择战斗,则玩家首先攻击。玩家的伤害会降低怪物的健康。
如果怪物死亡,玩家将获取怪物携带的任何金币。玩家也升级,将等级和伤害提高1点。
如果怪物没有死亡,怪物就会攻击玩家。怪物的伤害会降低玩家的健康。
当玩家死亡(失去)或达到20级(胜利)时游戏结束
如果玩家死亡,游戏应告诉玩家他们的等级以及他们有多少金币。
如果玩家获胜,游戏应告诉玩家他们赢了,以及他们有多少金币
这是一个示例游戏会话:

Enter your name: MW
Welcome, MW
You have encountered a orc (o).
®un or (F)ight: R
You successfully fled.
You have encountered a orc (o).
®un or (F)ight: R
You successfully fled.
You have encountered a slime (s).
®un or (F)ight: F
You hit the slime for 1 damage.
You killed the slime.
You are now level 2.
You found 5 gold.
You have encountered a slime (s).
®un or (F)ight: F
You hit the slime for 2 damage.
You killed the slime.
You are now level 3.
You found 5 gold.
You have encountered a slime (s).
®un or (F)ight: F
You hit the slime for 3 damage.
You killed the slime.
You are now level 4.
You found 5 gold.
You have encountered a dragon (D).
®un or (F)ight: R
You failed to flee.
The dragon hit you for 4 damage.
®un or (F)ight: R
You successfully fled.
You have encountered a slime (s).
®un or (F)ight: F
You hit the slime for 4 damage.
You killed the slime.
You are now level 5.
You found 5 gold.
You have encountered a slime (s).
®un or (F)ight: F
You hit the slime for 5 damage.
You killed the slime.
You are now level 6.
You found 5 gold.
You have encountered a dragon (D).
®un or (F)ight: R
You failed to flee.
The dragon hit you for 4 damage.
®un or (F)ight: R
You failed to flee.
The dragon hit you for 4 damage.
You died at level 6 and with 25 gold.
Too bad you can’t take it with you!
请按任意键继续. . .
提示:创建4个功能:

main()函数应该处理游戏设置(创建播放器)和主游戏循环。
fightMonster()处理玩家与单个怪物之间的战斗,包括询问玩家他们想做什么,处理跑步或打击案件。
attackMonster()处理攻击怪物的玩家,包括升级。
attackPlayer()处理攻击玩家的怪物。

解决方案

#include <iostream>
#include <string>
#include <cstdlib> // rand()和srand()
#include <ctime> // time()
 
// 生成最小和最大(包括)之间的随机数
// 假设已经调用了srand()
int getRandomNumber(int min, int max)
{
	static const double fraction = 1.0 / (static_cast<double>(RAND_MAX) + 1.0);  //static用于效率,所以我们只计算一次这个值
	// 在我们的范围内均匀分布随机数
	return static_cast<int>(rand() * fraction * (max - min + 1) + min);
}
 
class Creature
{
protected:
	std::string m_name;
	char m_symbol;
	int m_health;
	int m_damage;
	int m_gold;
 
public:
	Creature(std::string name, char symbol, int health, int damage, int gold) :
		m_name(name), m_symbol(symbol), m_health(health), m_damage(damage), m_gold(gold)
	{
	}
 
	char getSymbol() { return m_symbol; }
	const std::string& getName() { return m_name; }
	bool isDead() { return m_health <= 0; }
	int getGold() { return m_gold; }
	void addGold(int gold) { m_gold += gold;  }
	void reduceHealth(int health) { m_health -= health;  }
	int getHealth() { return m_health; }
	int getDamage() { return m_damage;  }
};
 
class Player : public Creature
{
	int m_level = 1;
 
public:
	Player(std::string name)
		: Creature(name, '@', 10, 1, 0)
	{
	}
 
	void levelUp()
	{
		++m_level;
		++m_damage;
	}
 
	int getLevel() { return m_level; }
	bool hasWon() { return m_level >= 20; }
};
 
 
 
class Monster : public Creature
{
public:
	enum Type
	{
		DRAGON,
		ORC,
		SLIME,
		MAX_TYPES
	};
 
	struct MonsterData
	{
		const char* name;
		char symbol;
		int health;
		int damage;
		int gold;
	};
 
	static MonsterData monsterData[MAX_TYPES];
	Type m_type;
 
	Monster(Type type)
		: Creature(monsterData[type].name, monsterData[type].symbol, monsterData[type].health, monsterData[type].damage, monsterData[type].gold), m_type(type)
	{
	}
 
	static Monster getRandomMonster()
	{
		int num = getRandomNumber(0, MAX_TYPES - 1);
		return Monster(static_cast<Type>(num));
	}
};
 
Monster::MonsterData Monster::monsterData[Monster::MAX_TYPES]
{
	{ "dragon", 'D', 20, 4, 100 },
	{ "orc", 'o', 6, 2, 25 },
	{ "slime", 's', 1, 1, 5 }
};
 
// 此函数处理玩家攻击怪物
void attackMonster(Player &p, Monster &m)
{
	// 如果玩家死了,我们就无法攻击怪物
	if (p.isDead())
		return;
 
	std::cout << "You hit the " << m.getName() << " for " << p.getDamage() << " damage.\n";
 
	// 由玩家的伤害减少怪物的健康
	m.reduceHealth(p.getDamage());
 
	// 如果怪物现在已经死了,请将玩家升级
	if (m.isDead())
	{
		std::cout << "You killed the " << m.getName() << ".\n";
		p.levelUp();
		std::cout << "You are now level " << p.getLevel() << ".\n";
		std::cout << "You found " << m.getGold() << " gold.\n";
		p.addGold(m.getGold());
	}
}
 
// 此函数处理攻击玩家的怪物
void attackPlayer(Monster &m, Player &p)
{
	// 如果怪物死了,它就无法攻击玩家
	if (m.isDead())
		return;
 
	// 怪物的伤害会降低玩家的健康
	p.reduceHealth(m.getDamage());
	std::cout << "The " << m.getName() << " hit you for " << m.getDamage() << " damage.\n";
}
 
// 此函数处理玩家和随机生成的怪物之间的整个战斗
void fightMonster(Player &p)
{
	// First randomly generate a monster
	Monster m = Monster::getRandomMonster();
	std::cout << "You have encountered a " << m.getName() << " (" << m.getSymbol() << ").\n";
	
	// 只要怪物没有死,玩家没有死,那么战斗继续
	while (!m.isDead() && !p.isDead())
	{
		std::cout << "(R)un or (F)ight: ";
		char input;
		std::cin >> input;
		if (input == 'R' || input == 'r')
		{
			// 成功逃离的几率为50%
			if (getRandomNumber(1, 2) == 1)
			{
				std::cout << "You successfully fled.\n";
				return; // success ends the encounter
			}
			else
			{
				// 没有逃跑会让怪物免受攻击并且你会受到伤害
				std::cout << "You failed to flee.\n";
				attackPlayer(m, p);
				continue;
			}
		}
 
		if (input == 'F' || input == 'f')
		{
			// 玩家首先攻击,怪物再攻击
			attackMonster(p, m);
			attackPlayer(m, p);
		}
	}
}
 
int main()
{
	srand(static_cast<unsigned int>(time(0))); // 将初始值设置为系统时钟
	rand(); // 摆脱第一个结果
 
	std::cout << "Enter your name: ";
	std::string playerName;
	std::cin >> playerName;
 
	Player p(playerName);
	std::cout << "Welcome, " << p.getName() << '\n';
 
	// 如果玩家没有死并且尚未获胜,则游戏继续进行
	while (!p.isDead() && !p.hasWon())
		fightMonster(p);
 
	// 此时,玩家已经死亡或已经获胜
	if (p.isDead())
	{
		std::cout << "You died at level " << p.getLevel() << " and with " << p.getGold() << " gold.\n";
		std::cout << "Too bad you can't take it with you!\n";
	}
	else
	{
		std::cout << "You won the game with " << p.getGold() << " gold!\n";
	}
 
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值