CSCI-541 Programming Skills: Efficient Design in Modern C++
Project 1 - Broken Heroes of the Feral Vale

Due Date: End of day, Friday March 8, 2019

Revision History:

Table of Contents:

Introduction

Goals

The goal of this project is for students to gain experience with fundamental C++ concepts such as:

Overview

You have been tasked by your company to develop the next big fantasy role playing game (RPG), Broken Heroes of the Fearl Vale.

The game deals with the ongoing skirmish in the realm of The Feral Vales, between three ancient and opposing teams:

Each team has a party of three members, the heroes, each with their own unique characteristics and abilities:

Gameplay

The way the game is played is the three opposing teams of heroes are organized into a separate queues. Game play follows these steps until only one team remains standing.

  1. The three opposing heroes at the front of their respective queues engage in one on one combat in what we call a single battle. Each battle number determines the order the combatants will fight each other.
    Battle Number Team Order
    1 Dragon, Lion, Shark
    2 Lion, Shark, Dragon
    3 Shark, Dragon, Lion
    4 Shark, Lion, Dragon
    5 Lion, Dragon, Shark
    6 Dragon, Shark, Lion
  2. The first hero attacks the second hero using their attacking characteristics, e.g. in battle 1 Dragon attacks Lion.
  3. The second hero takes the damage based on their defensive characteristics.
  4. If the second hero has not fallen, they attack the third hero based on their attacking characteristics, e.g. in battle 1 Lion attacks Shark.
  5. The third hero takes the damage based on their defensive characteristics.
  6. If the third hero has not fallen, they attack the first hero based on their attacking characteristics, e.g. in battle 1 Shark attacks Dragon.
  7. The first hero takes the damage based on their defensive characteristics.
  8. If a hero does not fall, they re-enter the back of their team queue, otherwise they have fallen from the battle.

Design

You are given a public/protected design that you can follow, or you can create your own with the following stipulations:

Documentation

Here is the documentation for all the classes in the provided design.

Starter Code

You can access the starter code here. Besides the provided source it contains makefiles that will allow you to build with CLion, as well as on our CS machines.

You are free to use any C++ version, e.g. -std=c++98, -std=c++11, -std=c++14, or -std=c++17. The makefiles provided to you use C++17, but the provided design uses only a few things from the C++11 standard, e.g. auto, default, and override. Feel free to change the standard in all the makefiles to the one you want to use.

Project Structure

If you follow the provided design, your project structure should look like the following once you have created all the necessary files. Note that there are three directories, game, hero and util. Make sure you put the C++ source files in the right location. Note, if you are developing in CLion the CMakeLists.txt makefile should be at the top level (along with the src directory).

Implementation

Command Line

The program can be run on the command line as:

    $ main dragon_seed_# lion_seed_# shark_seed_#

If the number of arguments are correct, they are guaranteed to be valid unsigned long long's that will be used as separate seeds to the random number generators that each squad maintains.

If the number of arguments is incorrect, display a usage message and exit the program, i.e.:

    Usage: main dragon_seed_# lion_seed_# shark_seed_#

Input

This program has no user input outside of the seed values provided on the command line. Your program should not prompt for any input while running and should run the game to completion.

Output

After the seeds are set, the output of the game follows through each of the battles until eventually one team is victorious over the other. A typical battle will have the following output:

    Battle #1
    ==========
    DRAGON:
    Dragon_Name1, ROLE, #/#
    Dragon_Name2, ROLE, #/#
    ...

    LION:
    Lion_Name1, ROLE, #/#
    Lion_Name2, ROLE, #/#
    ...

    SHARK:
    Shark_Name1, ROLE, #/#
    Shark_Name2, ROLE, #/#
    ...

    *** Hero_Name1 vs Hero_Name2

    {details of the individual battle}

For each hero, #/#, refers to their current hit points followed by their maximum hit points.

For each battle you should display the current active party of heroes from Team Dragon, Team Lion and Team Shark. Heroes who are defeated are no longer included in the party, but should be maintained for the statistics that happen at the end. The order the heroes battle is chosen by the battle number (see the Gameplay section).

If all heroes in combat are not healers, you will see a maximum of three messages that correlate to the attacks by each hero (only if they all survive):

    Hero_Name1 {damages} Hero_Name2 for # points
    Hero_Name2 {damages} Hero_Name3 for # points
    Hero_Name3 {damages} Hero_Name1 for # points

The message for {damages} depends on the hero who is attacking. A fighter "slashes", a healer "smites", and a tank "bonks".

If the first hero defeats the second hero with their attack, the second hero falls and does not get to respond with an attack of their own. The same goes for when the third hero goes to attack. In this case the output would look like:

    Hero_Name1 {damages} Hero_Name2 for # points
    Hero_Name2 has fallen!

In the event a healer is a hero who is attacking, they first heal themselves, then their party, followed by a low damage attack to their enemy, e.g.:

    Healer_Name heals # points
    Healer_Ally1 heals # points
    Healer_Ally2 heals # points
    Healer_Name smites Enemy_Name for # points

Keep in mind the healer will only heal the allies in their team that have not been defeated.

When an entire team has fallen, you should display a message at the end of the battle number, e.g.:

    Team {Dragon|Lion|Shark} is defeated!

At some point the game will come to an end when the two other teams have no more members in their squad (they have all been defeated). When this happens you should print out the statistics of the game in the format:

    STATISTICS
    ==========
    Victor: {DRAGON|LION|SHARK}
    Battles: #
    Fallen:
        Hero1, ROLE, #/#
        Hero2, ROLE, #/#
        ...
    Damage:
        Hero1: #
        Hero2: #
        ...

The fallen should appear in the order they fall in battle, from first to last. For the damage summary, the heroes should be ordered alphabetically by name, and the number should be the total amount of attack damage they did over the course of the game.

For further details you can look at the Sample Runs for complete outputs when running with different seeds, as well as the documentation for when/where the messages get displayed.

Implementation Details

Seeding a Random Number Generator

You are given a Random class that when constructed should be passed a seed (otherwise the seed is random). Each Squad should have their own internal random number generated seeded by the command line input.

When initializing your squad of heroes, you should do a dice roll between 0 and 5 inclusive and use the table in the constructor which is repeated here:

Random Value Hero Order
0 Fighter, Healer, Tank
1 Healer, Tank, Fighter
2 Tank, Fighter, Healer
3 Fighter, Tank, Healer
4 Healer, Fighter, Tank
5 Tank, Healer, Fighter

Factory Method Pattern

From your game package perspective, the Hero constructor is protected and not accessible when you are building your squad. Instead, you should use the static method Hero::createHero to create and return the new hero. This requires you call the correct subclass constructor, and in turn it will call the protected Hero constructor with the appropriate values.

Constant Field Values

Each of the heroes have their own names which you can access with the provided class, Heroes.

Besides this, each Hero has their own sets of values for things like hit points, how much damage they can deal, and how much they can heal (if applicable). Look at the Member Data Documentation section for each hero to see what values were used by the program that generated the sample outputs below.

Queue

You are required to implement a templated Queue that will be used by the squads to store the heroes while the game is being played. This class is a simple wrapped for the STL deque collection.

Don't forget that since you are implementing your templated code outside of the header file that you must put explicit instantiations into your queue.cpp.

We are providing you with a test program, test_queue.cpp, that you can use to verify your queue implementation is correct. It uses the following types that you must specify in your implementation: int, string and Hero*.

Sample Runs

You can access some of the sample outputs from the links below. The format of the files indicates the seeds, for example the file 3-0-8.txt means Team Dragon has a seed of 3, Team Lion has a seed of 0, and Team Shark has a seed of 8.

Submission

You must have all your code on the CS machines in order to submit to try. You should be able to build already with the supplied makefiles. These are the steps you should follow:

Grading

The grade breakdown for this lab is as follows: