CSP-201609-3-炉石传说
解题思路
1.类和结构定义
-
Servant
:定义了随从的结构,包含攻击力(attack
)和生命值(health
)。 -
MyPlayer
:定义了玩家的类,包含玩家英雄的生命值(heroHealth
)、玩家战场上存活的随从数量(ServantsNum
)和玩家控制的随从列表(Servants
)。此类包含方法用于召唤随从(callServant
)和进行攻击(ServantAttack
)。
在MyPlayer
类中,主要包含两个函数:callServant
和ServantAttack
。这两个函数分别处理游戏中召唤随从和随从攻击的行为。
(1)callServant函数
- 创建一个新的
Servant
对象t
,其攻击力和生命值由函数参数指定。 - 检查要召唤的位置(
position - 1
,因为数组索引从0开始)。如果该位置目前没有随从(即生命值为0),则直接在该位置放置新召唤的随从。 - 如果该位置已有随从,则需要为新随从腾出空间。这通过从右向左(从战场的最后一个位置开始,即索引6)遍历
Servants
数组并将随从向右移动一位来实现,直至达到召唤位置。这样,原来的随从和右侧的随从都会顺次向右移动一位,为新随从留出空间。 - 在召唤位置插入新的随从后,更新战场上随从的数量(
ServantsNum
)。
(2)ServantAttack()函数
- 首先,根据
attacker
和defender
参数获取攻击方随从和防御方角色(可能是随从或英雄)的信息。 - 如果
defender
为0,表示攻击的是敌方英雄。此时,直接减少敌方英雄的生命值,减少的数值等于攻击方随从的攻击力。 - 如果
defender
非0,表示攻击的是敌方随从。这时,双方随从都会对彼此造成伤害:
- 减少敌方随从的生命值,减少的数值等于攻击方随从的攻击力。
- 减少攻击方随从的生命值,减少的数值等于防御方随从的攻击力。 - 检查攻击后双方随从的生命值,如果某随从的生命值小于等于0,则该随从死亡,需要从战场上移除。移除随从后,要更新存活随从的数量,并对剩余随从的位置进行调整(类似召唤随从时的逻辑)。
2.游戏逻辑
-
初始化游戏环境:创建两个玩家对象,分别代表先手玩家(
firstPlayer
)和后手玩家(secondPlayer
)。游戏开始时,每个玩家的英雄生命值均为30,且没有随从在战场上。 -
执行游戏操作:读取输入的操作数(
n
)和随后的操作列表。根据当前回合的玩家(使用布尔值currentPlayer
标记),执行对应的操作。操作包括:summon
:在指定位置召唤一个具有特定攻击力和生命值的随从。attack
:使用一个随从攻击对手的随从或英雄。end
:结束当前玩家的回合并切换到对手玩家。
-
执行攻击和召唤逻辑:
- 在召唤(
callServant
)时,将新的随从插入到指定位置,并调整其它随从的位置。 - 在攻击(
ServantAttack
)时,根据攻击和防御方的攻击力调整双方生命值,并处理随从的死亡(生命值小于等于0)。
- 在召唤(
-
输出游戏结果
完整代码
#include <iostream>
#include <vector>
using namespace std;
struct Servant
{
int attack;
int health;
Servant(int a, int h) : attack(a), health(h) {}
};
class MyPlayer
{
public:
int heroHealth, ServantsNum;
vector<Servant>Servants;
MyPlayer() {
heroHealth = 30;
ServantsNum = 0;
Servants = vector<Servant>(7, { 0,0 });
}
void callServant(int position, int attack, int health) {
Servant t{ attack,health };
if (Servants[position - 1].health == 0) Servants[position - 1] = t;
else
{
for (int i = 6; i >= position; i--) {
Servants[i] = Servants[i - 1];
}
Servants[position - 1] = t;
}
ServantsNum++;
}
void ServantAttack(MyPlayer& enemy, int attacker, int defender) {
if (defender == 0) enemy.heroHealth -= Servants[attacker - 1].attack; // 敌方英雄
else // 敌方随从
{
int myAttack = Servants[attacker - 1].attack, enemyAttack = enemy.Servants[defender - 1].attack;
enemy.Servants[defender - 1].health -= myAttack;
if (enemy.Servants[defender - 1].health <= 0) { // 死亡检测
for (int i = defender - 1; i < 6; i++)
{
enemy.Servants[i] = enemy.Servants[i + 1];
}
Servants[6].attack = 0, Servants[6].health = 0;
enemy.ServantsNum--;
}
Servants[attacker - 1].health -= enemyAttack;
if (Servants[attacker - 1].health <= 0)
{
for (int i = attacker - 1; i < 6; i++)
{
Servants[i] = Servants[i + 1];
}
Servants[6].attack = 0, Servants[6].health = 0;
ServantsNum--;
}
}
}
};
int n, pos, att, hea, atter, def;
string action;
MyPlayer firstPlayer, secondPlayer;
int main()
{
cin >> n;
MyPlayer& t = firstPlayer, & t_enemy = secondPlayer;
bool currentPlayer = 0; // 0-firstPlayer 1-secondPlayer
for (int i = 0; i < n; i++)
{
cin >> action;
if (!currentPlayer) // firstPlayer
{
if (action == "summon")
{
cin >> pos >> att >> hea;
firstPlayer.callServant(pos, att, hea);
}
else if (action == "attack")
{
cin >> atter >> def;
firstPlayer.ServantAttack(secondPlayer, atter, def);
}
else if (action == "end") currentPlayer = 1;
}
else
{
if (action == "summon")
{
cin >> pos >> att >> hea;
secondPlayer.callServant(pos, att, hea);
}
else if (action == "attack")
{
cin >> atter >> def;
secondPlayer.ServantAttack(firstPlayer, atter, def);
}
else if (action == "end") currentPlayer = 0;
}
}
// 1.游戏的胜负结果
if (firstPlayer.heroHealth > 0 && secondPlayer.heroHealth <= 0) cout << 1 << endl; // 先手玩家获胜
else if (firstPlayer.heroHealth <= 0 && secondPlayer.heroHealth > 0) cout << -1 << endl; // 后手玩家获胜
else cout << 0 << endl;
// 2.先手玩家的英雄的生命值
cout << firstPlayer.heroHealth << endl;
// 3.先手玩家在战场上存活的随从个数以及生命值
cout << firstPlayer.ServantsNum << " ";
for (auto& it : firstPlayer.Servants) {
if (it.health != 0) {
cout << it.health << " ";
}
}
cout << endl;
// 4-5.后手(同理)
cout << secondPlayer.heroHealth << endl;
cout << secondPlayer.ServantsNum << " ";
for (auto& it : secondPlayer.Servants) {
if (it.health != 0) {
cout << it.health << " ";
}
}
return 0;
}