CS 235 Unit 12 Exercise: Polymorphism

Table of Contents


1. Introduction

About
Polymorphism in C++ refers to the ability of objects of different classes to be used interchangeably, as they share a common base class. This allows for more flexible and extensible code, as new derived classes can be added without requiring changes to the existing code that uses the base class.
Goals
  • Practice writing a class interface.
  • Practice utilizing polymorphism to reduce duplicate code
Setup
Download the starter code here: https://gitlab.com/moosadee/courses/-/tree/main/wip_exercises/starter_code/c3_u12_Polymorphism?ref_type=heads

Files included:

.
├── BattleProgram.cpp
├── BattleProgram.hpp
├── Character.cpp
├── Character.hpp
├── main.cpp
├── Helper.cpp
└── Helper.hpp

2. Battle game

Make sure to download the starter code.

This program is a simple RPG-style battle and the user can select however many characters they’d like. Characters can be created as NPCs (non-player characters) or PCs (player characters). Using Polymorphism, we store pointers to Character* objects, but instantiate either NonPlayerCharacter or PlayerCharacter objects. You’ll just have to implement a few lines of code that get the polymorphism working.

How many players? 2

Player 0, (1) NPC or (2) PC? 1
Player 0 name: Bobbert

Player 1, (1) NPC or (2) PC? 2
Player 1 name: Jimothy
--------------------------------------------------------------------------------
 | ROUND 1 |
 -----------

NAME      TYPE      HP        STRENGTH  DEFENSE   CHARACTER #         
--------------------------------------------------------------------------------
Bobbert   NPC       100       5         2         0                   
Jimothy   PC        100       7         3         1                   

Bobbert's turn... They heal themself for 3 hp!
Jimothy's turn... 
Choose an action:
1. Attack
2. Heal
>> 

UML Diagram:

Class Name  
+ BattleProgram()  
+ ~BattleProgram()  
+ Run() : void
- Setup() : void
- Cleanup() : void
- DisplayStats() : void
- HorizBar() : void
- m_done : bool
- m_round : int
- m_characters : vector<Character*>

Note that it stores a vector or Character pointers. This is an array of items from the Character family.


2.1. void BattleProgram::Setup()

The setup function is where the characters are made. The user will select 1 for NPC or 2 for PC and set the character’s name. After that, a pointer is created. Based on the user’s response, it should be instantiated as either a new NonPlayerCharacter or PlayerCharacter before being added to the m_characters vector.

Character* character = nullptr;
if ( choice == 1 )
{
    // TODO: Instantiate as NPC
}
else if ( choice == 2 )
{
    // TODO: Instantiate as PC
}
m_characters.push_back( character );

Nullptr note: If these characters don’t get instantiated, then the characters vector will just store a bunch of =nullptr=s and when the program tries to run the game it will just crash once it tries to dereference a nullptr.

Freeing memory note: The BattleProgram::Cleanup() function handles freeing the memory so you don’t have to. :)


2.2. Characters

In Character.hpp, three classes are declared: Character (the abstract base class, which acts as an interface), NonPlayerCharacter, and PlayerCharacter. Character is already implemented with a bunch of functions common to both the PCs and NPCs. The only thing that differs are these two functions:

virtual int Action() = 0;
virtual int AttackWho( int maxIndex ) = 0;

Each of these functions must be defined in the child classes in Character.cpp.

2.2.1. int NonPlayerCharacter::Action()

Randomly select a number 1 or 2 and return the decision.

To get a random number between 0 and 1, we use: rand() % 2

To get a random number between 1 and 2, we offset it by 1: rand() % 2 + 1

2.2.2. int NonPlayerCharacter::AttackWho( int maxIndex )

Randomly select a number from 0 to the maxIndex and return the decision. (Hint: rand() % maxIndex).

2.2.3. int PlayerCharacter::Action()

For this function, ask the player to choose 1 to attack, or 2 to heal. Validate their input with a while loop before returning their choice.

Choose an action:
1. Attack
2. Heal
>> 66
Invalid selection. Try again.
>> -25
Invalid selection. Try again.
>> 1
Attack who? (0 to 1):

2.2.4. int PlayerCharacter::AttackWho( int maxIndex )

This function will ask the player to enter an index for another character to attack. Valid indices are [0, maxIndex] (inclusive). Ask them to enter a number and validate their input before returning their decision.

Attack who? (0 to 1): -58
Invalid selection. Try again.
>> 200
Invalid selection. Try again.
>> 1

* Bobbert attacks Jimothy for 6 damage!

2.3. Testing the game

Run the program and test it out with NPC and PC characters. The NPC should select its action and who it attacks at random:

Human's turn... 
Choose an action:
1. Attack
2. Heal
>> 1
Attack who? (0 to 2): 1

* Human attacks ComputerA for 6 damage!

While the PC should display the menus we implemented to get what action to take and who to attack:

ComputerB's turn... They attack ComputerA for 5 damage!

3. Turning in your work

Once you're done making an update of your program, you will just be submitting a presentation… but also a presentational part.

Screen capture video (preferred)
  • Use a screen capture tool to record your console window as your program runs. Make sure that your new functionality is visible.
  • Speak over the video OR add text comments when uploading to let me know what you updated in the program.
  • Highlight the parts of the code that you updated.
Screen capture images
  • Create a Word or LibreOffice Writer document.
  • Take a series of screenshots of your program running. Enough to show off your new functionality.
  • Add text to the document to explain what you updated in the program.
  • Highlight the parts of the code that you updated. (Include as screenshots, preferably)
  • Export as a PDF for upload, please.

Screen capture info:

Author: Rachel Wil Sha Singh

Created: 2023-10-01 Sun 00:08

Validate