Thread: Code Review

  1. #1
    Registered User
    Join Date
    Jul 2019
    Posts
    34

    Code Review

    So I've been working on a small console game for about a week now, and I would like some feedback on it. I consider it finished, it does exactly what I want it to do. What could be improved? done better?

    Here is the code and here is a download for the entire VS 2019 project if you wish to look at that instead: Monster Fight

    main.cpp

    Code:
    // This is an independent project of an individual developer. Dear PVS-Studio, please check it.
    
    // PVS-Studio Static Code Analyzer for C, C++, C#, and Java: http://www.viva64.com
    
    
    #include <iostream>
    #include <string>
    #include <ostream>
    #include <vector>
    #include <random>
    #include <limits>
    
    
    #include "Character.h"
    #include "Player.h"
    #include "Enemy.h"
    #include "Attack.h"
    
    
    using std::cout;
    using std::endl;
    using std::string;
    using std::ostream;
    using std::vector;
    using std::default_random_engine;
    using std::uniform_int_distribution;
    using std::random_device;
    using std::cin;
    using std::numeric_limits;
    using std::streamsize;
    using std::getline;
    using std::mt19937;
    
    
    
    
    int main()
    {
        random_device rd;
        default_random_engine generator(rd());
    
    
        //AttackObjectName(Attack Name, Attack Power)
    
    
        Attack Punch("Punch", 3);
        Attack Kick("Kick", 1);
        Attack Slash("Slash", 2);
        Attack BodySlam("Body Slam", 4);
        Attack Missed("Missed Attack", 0);
    
    
        vector<Attack> playerAttacks;
        playerAttacks.reserve(4);
    
    
        playerAttacks.push_back(Punch);
        playerAttacks.push_back(Kick);
        playerAttacks.push_back(BodySlam);
        playerAttacks.push_back(Missed);
    
    
        uniform_int_distribution<int> randomPlayerAttacks(0, playerAttacks.size() - 1);
    
    
        vector<Attack> enemyAttacks;
        enemyAttacks.reserve(3);
    
    
        enemyAttacks.push_back(Slash);
        enemyAttacks.push_back(BodySlam);
        enemyAttacks.push_back(Missed);
    
    
        uniform_int_distribution<int> randomEnemyAttacks(0, enemyAttacks.size() - 1);
    
    
        Player Hero("Hero", 100, playerAttacks, 0, 0);
    
    
        uniform_int_distribution<int> randomMoneyReward(0, 80);
        uniform_int_distribution<int> randomXPReward(0, 40);
    
    
        //EnemyObjectName(Enemy Name, Health, AttackList, XP to Give, Money)
    
    
        Enemy Dragon("Dragon", 70, enemyAttacks, 40, 0);
        Enemy Skeleton("Skeleton", 10, enemyAttacks, 20, 0);
        Enemy Troll("Troll", 25, enemyAttacks, 30, 0);
        Enemy GiantRat("Giant Rat", 15, enemyAttacks, 25, 0);
        Enemy Raptor("Raptor", 35, enemyAttacks, 15, 0);
    
    
        vector<Enemy> enemyContainer;
        enemyContainer.reserve(5);
    
    
        enemyContainer.push_back(Dragon);
        enemyContainer.push_back(Skeleton);
        enemyContainer.push_back(Troll);
        enemyContainer.push_back(GiantRat);
        enemyContainer.push_back(Raptor);
    
    
        int choice{ 0 };
        int turn{ 1 };
    
    
        while (choice != -1)
        {
            choice = 0;
    
    
            //Choose a random enemy and set it inside vector, if we dont do this
            //A random enemy will be chosen for each call in the fight, we want 
            //the same eney for the duration of the fight.
            uniform_int_distribution<int> chooseRandomEnemy(0, enemyContainer.size() - 1);
            Enemy randomEnemy{ enemyContainer[chooseRandomEnemy(generator)] };
    
    
            //Randomly generate a reward and set it for this fight, then re-randomize it
            //for the next fight.
            randomEnemy.GiveMoney(randomMoneyReward(generator));
            randomEnemy.XpToGive(randomXPReward(generator));
    
    
            cout << "What would you like to do?\n" << endl;
    
    
            cout << "1) Fight" << endl;
            cout << "2) quit" << endl;
    
    
            cout << "\n> ";
            cin >> choice;
    
    
            switch (choice)
            {
            case 1:
                cin.ignore(numeric_limits<streamsize>::max(), '\n');
    
    
                //Initial encounter
                cout << "\n" << Hero.GetName() << " encountered a " << randomEnemy.GetName() << "!" << endl;
                cout << "It has " << randomEnemy.GetHealth() << " Health!\n" << endl;
    
    
                while (Hero.GetHealth() > 0)
                {
                    //Re-roll player and enemy attacks and power levels for random attacks and powers.
                    //Find better way to do this.
                    Attack randomPlayerAttack{ playerAttacks[randomPlayerAttacks(generator)] };
                    Attack randomEnemyAttack{ enemyAttacks[randomEnemyAttacks(generator)] };
    
    
                    cout << "\nACTION----------------------------------------------------------" << endl;
    
    
                    if (randomPlayerAttack.GetName() == "Missed Attack")
                    {
                        cout << Hero.GetName() << "'s attack Missed!" << endl;
                    }
                    else
                    {
                        cout << Hero.GetName() << " uses " << randomPlayerAttack.GetName();
                        cout << " against the " << randomEnemy.GetName() << ", and it does ";
                        cout << randomPlayerAttack.GetPower() << " damage!\n" << endl;
                    }
    
    
                    randomEnemy.TakeDamage(randomPlayerAttack.GetPower());
    
    
                    if (randomEnemy.GetHealth() <= 0)
                    {
                        cout << Hero.GetName() << " defeated " << randomEnemy.GetName();
                        cout << " and got " << randomEnemy.GetMoney() << " gold and ";
                        Hero.GiveExperience(randomEnemy.GetXpToGive());
                        cout << randomEnemy.GetXpToGive() <<  " experience.\n" << endl;
                        Hero.GiveMoney(randomEnemy.GetMoney());
                        cout << Hero.GetName() << "'s Health was fully restored." << endl;  
                        Hero.ResetHealth();
                        cout << "\n================================================================\n" << endl;
                        break;
                    }
    
    
                    if (randomEnemyAttack.GetName() == "Missed Attack")
                    {
                        cout << randomEnemy.GetName() << "'s attack missed!" << endl;
                    }
                    else
                    {
                        cout << randomEnemy.GetName() << " uses " << randomEnemyAttack.GetName();
                        cout << " against " << Hero.GetName() << ", and it does ";
                        cout << randomEnemyAttack.GetPower() << " damage!\n" << endl;
                    }
    
    
                    Hero.TakeDamage(randomEnemyAttack.GetPower());
    
    
                    if (Hero.GetHealth() <= 0)
                    {
                        cout << randomEnemy.GetName() << " defeated " << Hero.GetName() << endl;
                        cout << "\n================================================================\n" << endl;
    
    
                        cout << "\nGAME OVER\n" << endl;
    
    
                        return 0;
                        break;
                    }
    
    
                    cout << "\nSTATS=========================================================== Turn: " << turn++ << endl;
                    cout << Hero.GetName() << '\n' << endl;
    
    
                    cout << Hero.GetName() << "'s Health: " << Hero.GetHealth() << endl;
                    cout << Hero.GetName() << "'s Gold: " << Hero.GetMoney() << endl;
                    cout << Hero.GetName() << "'s Experience: " << Hero.GetExperience() << endl;
    
    
                    cout << '\n' << randomEnemy.GetName() << '\n' << endl;
    
    
                    cout << randomEnemy.GetName() << "'s Health: " << randomEnemy.GetHealth() << endl;
    
    
                    cout << "\n================================================================\n" << endl;
    
    
                    cout << "Press Enter to continue Fight\n" << endl;
    
    
                    cin.get();
                }
                    break;
    
    
                case 2:
                    return 0;
                    break;
    
    
                default:
                    cout << "\nInvalid Decision, please enter an integer or valid integer choice.\n" << endl;
                    cin.clear(); //Clear failure state
                    cin.ignore(numeric_limits<streamsize>::max(), '\n'); //discard bad characters
            }
        }
    
    
        return 0;
    }
    player.h

    Code:
    #pragma once// This is an independent project of an individual developer. Dear PVS-Studio, please check it.
    
    
    // PVS-Studio Static Code Analyzer for C, C++, C#, and Java: http://www.viva64.com
    
    
    #include <iostream>
    #include <string>
    #include <ostream>
    #include <vector>
    
    
    #include "Attack.h"
    #include "Enemy.h"
    
    
    using std::cout;
    using std::endl;
    using std::ostream;
    using std::string;
    using std::vector;
    
    
    class Player : public Character
    {
        public:
            Player
            (
                const string& name,
                int health, 
                vector<Attack> attackList,
                int money,
                int experience
            ) : Character{ name, health, attackList, money}, mExperience(experience)
            {}
    
    
            int GetExperience() const { return mExperience; }
    
    
            void GiveExperience(int amount);
    
    
            friend ostream& operator<<(ostream& os, const Player& player)
            {
                os << player.GetMoney() << endl;
                os << player.GetExperience() << endl;
    
    
                os << static_cast<const Character&>(player);
    
    
                return os;
            }
    
    
        private:
            int mExperience{ 0 };
    };
    player.cpp

    Code:
    // This is an independent project of an individual developer. Dear PVS-Studio, please check it.
    
    // PVS-Studio Static Code Analyzer for C, C++, C#, and Java: http://www.viva64.com
    #include "Player.h"
    
    
    void Player::GiveExperience(int amount)
    {
        mExperience += amount;
    }
    attack.h

    Code:
    #pragma once// This is an independent project of an individual developer. Dear PVS-Studio, please check it.
    
    
    // PVS-Studio Static Code Analyzer for C, C++, C#, and Java: http://www.viva64.com
    
    
    #include <iostream>
    #include <string>
    #include <ostream>
    
    
    using std::endl;
    using std::ostream;
    using std::string;
    
    
    class Attack
    {
        public:
            Attack(const string& name, double power) : mName(name), mPower(power)
            {}
            Attack() = default;
    
    
            string GetName() const { return mName; }
            double GetPower() const { return mPower; }
    
    
            friend ostream& operator<<(ostream& os, const Attack& attack)
            {
                os << attack.GetName() << endl;
                os << attack.GetPower() << endl;
    
    
                return os;
            }
    
    
        private:
            string mName{ "Attack Name" };
            double mPower{ 0 };
    };
    character.h

    Code:
    #pragma once// This is an independent project of an individual developer. Dear PVS-Studio, please check it.
    
    
    // PVS-Studio Static Code Analyzer for C, C++, C#, and Java: http://www.viva64.com
    
    
    #include <iostream>
    #include <string>
    #include <ostream>
    #include <vector>
    
    
    #include "Attack.h"
    //#include "Player.h"
    
    
    using std::endl;
    using std::ostream;
    using std::string;
    using std::vector;
    
    
    class Enemy;
    
    
    class Character
    {
        public:
            string GetName() const { return mName; }
            int GetHealth() const { return mHealth; }
            int GetMoney() const { return mMoney; }
    
    
            void TakeDamage(Attack& attack);
            void TakeDamage(int amount);
            void GiveMoney(int amount);
            void ResetHealth();
    
    
            friend ostream& operator<<(ostream& os, const Character& character)
            {
                os << character.GetName() << endl;
                os << character.GetHealth() << endl;
    
    
                return os;
            }
    
    
            //Protected because we dont want the user to create Characters, we want them to create players.
        protected:
            Character
            (
                const string& name, 
                int health, 
                vector<Attack> attackList,
                int money
            ) :     mName(name), 
                    mHealth(health), 
                    mAttackList(attackList),
                    mMoney(money)
            {}
            Character() = default;
    
    
        private:
            string mName{ "Character Name" };
            int mHealth{ 100 };
            vector<Attack> mAttackList;
            int mMoney{ 10 };
    };
    character.cpp


    Code:
    // This is an independent project of an individual developer. Dear PVS-Studio, please check it.
    
    // PVS-Studio Static Code Analyzer for C, C++, C#, and Java: http://www.viva64.com
    
    
    #include <iostream>
    #include <string>
    #include <ostream>
    
    
    #include "Character.h"
    #include "Attack.h"
    #include "Enemy.h"
    
    
    using std::cout;
    using std::endl;
    using std::ostream;
    using std::string;
    
    
    void Character::TakeDamage(Attack& attack)
    {
        mHealth -= attack.GetPower();
    }
    
    
    void Character::TakeDamage(int amount)
    {
        mHealth -= amount;
    }
    
    
    void Character::GiveMoney(int amount)
    {
        mMoney += amount;
    }
    
    
    //This will simply just set health to 100
    void Character::ResetHealth()
    {
        mHealth = 100;
    }
    enemy.h

    Code:
    #pragma once// This is an independent project of an individual developer. Dear PVS-Studio, please check it.
    
    
    // PVS-Studio Static Code Analyzer for C, C++, C#, and Java: http://www.viva64.com
    
    
    #include <iostream>
    #include <string>
    #include <ostream>
    #include <vector>
    
    
    #include "Attack.h"
    #include "Character.h"
    
    
    using std::endl;
    using std::ostream;
    using std::string;
    using std::vector;
    
    
    class Character;
    
    
    class Enemy : public Character
    {
        public:
            Enemy
            (
                const string& name,
                int health,
                vector<Attack> attackList,
                double xpToGive,
                int money
            ) : Character{ name, health, attackList, money}, mXpToGive(xpToGive)
            {}
    
    
            int GetXpToGive() const { return mXpToGive; }
            void XpToGive(int amount);
    
    
        private:
            int mXpToGive{ 0 }; //How much XP the player will recieve when this enemy is defeated
    };
    enemy.cpp

    Code:
    // This is an independent project of an individual developer. Dear PVS-Studio, please check it.
    
    // PVS-Studio Static Code Analyzer for C, C++, C#, and Java: http://www.viva64.com
    
    
    #include "Enemy.h"
    
    
    void Enemy::XpToGive(int amount)
    {
        mXpToGive += amount;
    }
    Last edited by ChayHawk; 02-26-2021 at 09:52 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Code review please
    By Richardcavell in forum C Programming
    Replies: 3
    Last Post: 05-13-2011, 11:01 AM
  2. How to get a code review
    By Richardcavell in forum C Programming
    Replies: 42
    Last Post: 03-19-2011, 10:36 PM
  3. code review
    By hamsteroid in forum C Programming
    Replies: 6
    Last Post: 04-04-2007, 12:23 PM
  4. Code review please
    By Brighteyes in forum C Programming
    Replies: 9
    Last Post: 03-29-2003, 06:28 PM
  5. review code
    By absenta in forum C++ Programming
    Replies: 3
    Last Post: 04-09-2002, 02:13 PM

Tags for this Thread