战斗游戏- c++,给定一个刷出职业,我如何每回合刷出更强的敌人

Combat Game - C++, Given a Spawner Class, How can I spawn stronger enemy every round

本文关键字:敌人 何每回 一个 c++ 游戏      更新时间:2023-10-16

我在OOP作业中有一个问题。我必须编码一场1v1的战斗。

这是一款生存游戏,玩家与敌人持续战斗,直到玩家死亡。玩家在前进过程中变得更强大。敌人也变得越来越强大。

我已经创建了两个类,单位和产卵。我们不能使用继承和多态性。我们只能使用类的简单定义。

我的问题是,我不能想到一个简单的方法,使类刷出一个更强大的敌人每一轮。

我想过重载单元的构造函数,但我在操作时遇到了麻烦。

有人能帮忙吗?

这是我的单元头文件(Unit.h):

#pragma once
#include <string>
#include <iostream>
#include <cstdlib>
#include <ctime>

using namespace std;
// Class Types
const string CLASS_WARRIOR  = "Warrior" ;
const string CLASS_ASSASSIN = "Assassin";
const string CLASS_MAGE     = "Mage"    ;
// Class Choices
const int CHOICE_WARRIOR    = 1;
const int CHOICE_ASSASSIN   = 2;
const int CHOICE_MAGE       = 3;
// Multipliers
const double MULTIPLIER_DAMAGE  = 0.50f;
const double MULTIPLER_HEAL     = 0.30f;
// Advantage
const bool ADVANTAGE = true;
// Win Bonus
const int BONUS_THREE   = 3;
const int BONUS_FIVE    = 5;
// Minimum and maximum values
const int HIT_RATE_MAX = 80;
const int HIT_RATE_MIN = 20;
const int DAMAGE_MIN = 1;
// Hit or miss
const bool ATTACK_HIT = true;
const bool ATTACK_MISS = false;
class Unit
{
public:
    // Constructors
    Unit(string name, int classChoice);
    // Getters and setters
    string getName();
    string getClass();
    int getHp();
    int getMaxHp();
    int getPower();
    int getVitality();
    int getAgility();
    int getDexterity();
    int getDamage();
    int getHeal();
    int getBonusDamage();
    bool getFirstToAttack();
    bool getHit();
    void setClassStats(const int classChoice);
    // Primary Actions
    void attack(Unit* target);
    // Secondary Actions
    void check(const Unit* target); // Inspects the enemy
    void lvlUp();               // Grants this Unit Bonus Stats on Victory

private:
    // Info
    string mName;
    string mClass;
    // Basic Stats
    int mHp;
    int mMaxHp;
    int mPower;
    int mVitality;
    int mAgility;
    int mDexterity;
    // Derived Stats
    int mDamage;
    int mHitrate;
    int  mHeal;
    int  mBonusDamage;
    // Miscellaneous 
    bool mAdvantage;    // If the player has the advantage
    string mTargetClass;// This Unit keeps in mind the class of this Unit's Opponent for reference
    int mChanceOfHit;   // The random chance if the attack will Hit/Miss
    bool mFirstToAttack;//if this unit will attack first
    bool mHit;          // if the attack is a hit or miss
};

这是我的Unit.cpp文件(Unit.cpp):

#include "Unit.h"

Unit::Unit(string name, int classChoice)
{
    mName = name;
    setClassStats(classChoice);
}
string Unit::getName()
{
    return mName;
}
string Unit::getClass()
{
    return mClass;
}
int Unit::getHp()
{
    return mHp;
}
int Unit::getMaxHp()
{
    return mMaxHp;
}
int Unit::getPower()
{
    return mPower;
}
int Unit::getVitality()
{
    return mVitality;
}
int Unit::getAgility()
{
    return mAgility;
}
int Unit::getDexterity()
{
    return mDexterity;
}
int Unit::getDamage()
{
    return mDamage;
}
int Unit::getHeal()
{
    return mHeal;
}
int Unit::getBonusDamage()
{
    return mBonusDamage;
}
bool Unit::getFirstToAttack()
{
    return mFirstToAttack;
}
bool Unit::getHit()
{
    return mHit;
}
void Unit::setClassStats(const int classChoice)
{
    if (classChoice == CHOICE_WARRIOR) {
        mClass      = CLASS_WARRIOR;
        mMaxHp = 20;
        mHp = mMaxHp;
        mPower      = 15;
        mVitality   = 10;
        mAgility    = 7;
        mDexterity  = 7;
        return;
    }
    else if (classChoice == CHOICE_ASSASSIN) {
        mClass      = CLASS_ASSASSIN;
        mMaxHp = 15;
        mHp         = mMaxHp;
        mPower      = 17;
        mVitality   = 8;
        mAgility    = 12;
        mDexterity  = 10;
        return;
    }
    else if (classChoice == CHOICE_MAGE) {
        mClass      = CLASS_MAGE;
        mMaxHp          = 30;
        mHp = mMaxHp;
        mPower      = 12;
        mVitality   = 12;
        mAgility    = 9;
        mDexterity  = 8;
        return;
    }
    throw exception("Error! Class not part of this game. ");
}
void Unit::attack(Unit * target)
{
    // Determine Whether the attack will Hit/Miss Based on the hit rate
    mChanceOfHit = rrand() % 100 + 1;
    if (mChanceOfHit > mHitrate) {
        mHit = ATTACK_MISS;
        return;
    }

    // Deducts the targets Hp by the Damage given by this Unit (if the attack didn't miss)
    target->mHp -= mDamage;
    mHit = ATTACK_HIT;
    // if target HP is negative, set it to zero
    if (target->mHp < 0) target->mHp = 0;
}
void Unit::check(const Unit * target)
{
    // The Unit Keeps in Mind his target's Class
    if (target->mClass == CLASS_WARRIOR)        mTargetClass = CLASS_WARRIOR;
    else if (target->mClass == CLASS_ASSASSIN)  mTargetClass = CLASS_ASSASSIN;
    else if (target->mClass == CLASS_MAGE)      mTargetClass = CLASS_MAGE;

    // Checks if the Unit is Advantageous Against his Target
    if (mClass == CLASS_WARRIOR) {
        if (target->mClass == CLASS_ASSASSIN) mAdvantage = ADVANTAGE;
        else mAdvantage = false;
    }
    else if (mClass == CLASS_ASSASSIN) {
        if (target->mClass == CLASS_MAGE) mAdvantage = ADVANTAGE;
        else mAdvantage = false;
    }
    else if (mClass == CLASS_MAGE) {
        if (target->mClass == CLASS_WARRIOR) mAdvantage = ADVANTAGE;
        else mAdvantage = false;
    }
    // Determine if this Unit Will Attack first
    if (mAgility >= target->mAgility) mFirstToAttack = true;
    else mFirstToAttack = false;
    // Determines Damage, Bonus Damage ( If Applicable ), and Hit Rate Based on targets stats
    mDamage = mPower - target->mVitality;
    if (mDamage < DAMAGE_MIN) mDamage = DAMAGE_MIN;
    mBonusDamage = mDamage * MULTIPLIER_DAMAGE;
    // Evaluates Damage Based on advantage
    if (mAdvantage) mDamage += mBonusDamage;
    mHitrate = ((float)mDexterity / (float)target->mAgility) * 100;
    //  Clamps the Hit Rate within the Hit Rate Range
    if (mHitrate > HIT_RATE_MAX) mHitrate = HIT_RATE_MAX;
    else if (mHitrate < HIT_RATE_MIN) mHitrate = HIT_RATE_MIN;
}
void Unit::lvlUp()
{
    // Determine Win Bonus Based on the target that he kept in mind
    if (mTargetClass == CLASS_WARRIOR) {
        mMaxHp += BONUS_THREE;
        mVitality += BONUS_THREE;
    }
    else if (mTargetClass == CLASS_ASSASSIN) {
        mAgility += BONUS_THREE;
        mDexterity += BONUS_THREE;
    }
    else if (mTargetClass == CLASS_MAGE) {
        mPower += BONUS_FIVE;
    }
    // Heals the player 30% of his Maximum HP
    mHeal = mMaxHp * MULTIPLER_HEAL;
    mHp += mHeal;
}

这是我的产卵头文件(产卵.h):

 #pragma once
 #include "Unit.h"
 class Spawner
 {
 public:
      Spawner();
      ~Spawner();
       void spawn(Unit*& unit);
  private:
      Unit* mUnit;
      int mRandomClass;
 };

这是我的spawn .cpp文件(spawn .cpp):

#include "Spawner.h"

Spawner::Spawner()
{
}
Spawner::~Spawner()
{
    delete mUnit;
    mUnit = NULL;
}
void Spawner::spawn(Unit *& unit)
{
    mRandomClass = rand() % 3 + 1;
    unit = new Unit("Enemy", mRandomClass);
    mUnit = unit;
}

最后是main。cpp:

#include "Unit.h"
#include "Spawner.h"
// Create player
Unit* createPlayer();
// Display Stats
void displayStats(Unit* unit);
// Play 1 round
void playRound(Unit*player, Unit* enemy);
// Simulate 1 attack (implement Higher agility gets to atttack first)
void combat(Unit* player, Unit* enemy);

void main()
{
    srand(time(NULL));
    Unit* player = createPlayer();
    Unit* enemy = NULL;
    Spawner *spawner = new Spawner();
    int round = 1;
    while (true) {
        cout << "Round " << round << endl;
        spawner->spawn(enemy);
        player->check(enemy);
        enemy->check(player);
        playRound(player, enemy);
        // if player is dead, end the game
        if (player->getHp() == 0) break;
        // else, add stats
        player->lvlUp();
        delete enemy;
        enemy = NULL;

        cout << "You defeted an enemy" << endl;
        system("pause>nul");
        system("cls");
        round++;
    }
    cout << "You were defeted! " << endl;
    cout << "You survived until Round " << round << endl;
    displayStats(player);
    delete player;
    player = NULL;
    delete spawner;
    spawner = NULL;
    system("pause>nul");
    system("cls");

}
Unit* createPlayer()
{
    Unit* unit = NULL;
    string name;
    int classChoice;
    cout << "Enter your Name: ";
    getline(cin, name);
    system("cls");
    cout << "Pick a class: " << endl
        << "t [ 1 ] Warrior" << endl
        << "t [ 2 ] Assassin" << endl
        << "t [ 3 ] Mage" << endl
        << endl;
    cin >> classChoice;
    while (classChoice > 3 || classChoice <= 0) {
        cout << "INVALID INPUT! Please try again" << endl;
        cout << "Pick a class: " << endl
            << "t [ 1 ] Warrior" << endl
            << "t [ 2 ] Assassin" << endl
            << "t [ 3 ] Mage" << endl
            << endl;
        cin >> classChoice;
    }
    unit = new Unit(name, classChoice);
    return unit;
}
void displayStats(Unit* unit)
{
    cout << "=========================================================================================" << endl
        << "Name: " << unit->getName() << " t t t HP: " << unit->getHp() << " / " << unit->getMaxHp() << endl
        << "Class: " << unit->getClass() << endl
        << "==========================================================================================" << endl
        << "POW: " << unit->getPower() << endl
        << "VIT: " << unit->getVitality() << endl
        << "AGI: " << unit->getAgility() << endl
        << "DEX: " << unit->getDexterity() << endl
        << endl;
}

void playRound(Unit*player, Unit* enemy)
{
    while (player->getHp() > 0 && enemy->getHp() > 0) {
        displayStats(player);
        displayStats(enemy);
        system("pause>nul");
        combat(player, enemy);
        system("cls");
    }
}
void combat(Unit* player, Unit* enemy)
{
    if (player->getFirstToAttack()) {
        player->attack(enemy);
        if (player->getHit() == ATTACK_MISS) cout << player->getName() << "'s Attack Missed! " << endl;
        else if (player->getHit() == ATTACK_HIT) cout << player->getName() << " dealt " << player->getDamage() << " Damage" << endl;
        system("pause>nul");
        if (enemy->getHp() == 0) return;
        enemy->attack(player);
        if (enemy->getHit() == ATTACK_MISS) cout << enemy->getName() << "'s Attack Missed! " << endl;
        else if (enemy->getHit() == ATTACK_HIT) cout << enemy->getName() << " dealt " << enemy->getDamage() << " Damage" << endl;
        system("pause>nul");
        return;
    }

    else if (enemy->getFirstToAttack()) {
        enemy->attack(player);
        if (enemy->getHit() == ATTACK_MISS) cout << enemy->getName() << "'s Attack Missed! " << endl;
        else if (enemy->getHit() == ATTACK_HIT) cout << enemy->getName() << " dealt " << enemy->getDamage() << " Damage" << endl;
        system("pause>nul");
        if (player->getHp() == 0) return;
        player->attack(enemy);
        if (player->getHit() == ATTACK_MISS) cout << player->getName() << "'s Attack Missed! " << endl;
        else if (player->getHit() == ATTACK_HIT) cout << player->getName() << " dealt " << player->getDamage() << " Damage" << endl;
        system("pause>nul");
        return;
    }
}

Unit类添加一个"等级",并使用该等级来增加单位的属性(例如,等级2可能意味着属性乘以1.5或诸如此类)。将level作为参数传递给构造函数,类似于units类。

你需要让你的刷出器知道它已经刷出了多少敌人:

// this belongs into your class definition, it should start at zero
int mCurrentSpawn;

因此在构造函数中将其设置为0:

Spawner::Spawner()
{
   mCurrentSpawn = 0;
}

然后当你刷出敌人时引用它:

void Spawner::spawn(Unit *& unit)
{
    mRandomClass = rand() % 3 + 1;
    unit = new Unit("Enemy", mRandomClass);
    mUnit = unit;
    mCurrentSpawn++;
    int levelUps = mCurrentSpawn - 1;
    while(levelUps > 0)
    {
       mUnit->lvlUp(); 
       levelUps--;
    }
}