Project 1 – Overview
Welcome all to the first project of the C++ Workshop. This project will be a combat simulator following very simple combat logic, roughly equivalent to that found in Dungeons & Dragons 3.5 Edition. Participants will have 1 month (ending September 15) to complete the project. In the mean time, feel free to post your questions and ideas here on the thread. In order to complete this project you may find you need to draw upon not only what you’ve already learned, but also what WILL be learned during the course of the next 4 weeks.
As we have already covered the chapter on Object-Oriented Analysis and Design the remainder of this post will follow the guidelines provided. I will provide the conceptualization and the analysis of the project. It will be up to each participant to do the design and implementation of the project, though design and implementation questions may be posted here if you get stuck.
Project 1 - Conceptualization
The program will be a console application consisting of various menus and submenus. The primary functionality will be the ability to create a character, purchase equipment, view your character’s stats, and enter the arena for combat. Once in the arena the character can select which level of opponent he wishes to face (from 1 to 20). After the level of opponent is chosen the opponent will be randomly generated and then him and the player will exchange blows until someone “dies.” Blows will be exchanged on the rate of one attack every 2 seconds and each attack/defense will be displayed on the screen. If the player is the winner he will receive experience points and money which can be used to purchase better equipment. Once a player receives the required experience he will automatically “level up,” resulting in an increase in stats at the end of a fight. The user may continue to buy equipment and fight in the arena until he loses a battle. At that point the character is dead and the user must create a new character. Finally, output should be color-coded. Menus, status information, and lists should all be in white, damage received should be shown in red, and damage given should be in another suitable color. Feel free to add other colors as you feel inclined.
Project 1 - General Analysis
1. When the user first executes the program they will be shown a main menu similar to that displayed below. When the user makes a choice the screen will be cleared and the user will be shown a new menu or screen depending upon which choice was made.
a. Create Character
b. Purchase Equipment
c. View Stats
2. When the user selects the option to create a character they will be shown a menu similar to that shown below. If the user selects “Name Character” they will receive a prompt allowing them to enter a name for the character. If the user selects roll for stats, then he will enter a loop where he can continue to “roll for stats” until he finds a suitable distribution. Returning to the previous menu clears the screen and then once again shows the main menu.
2a. If the user has already created a character by previously entering this submenu then entering the “Create Character” menu additional times should first prompt the user that they have already created a character, and that continuing will result in the removal of the old character to make room for the new. If the user opts to continue to “Create a Character” then the menu below is shown. If they decide NOT to create a new character, they will simply be returned to the main menu and their previously created character will remain.
2b. If the user had created a character but the character died in the arena, entering this menu does not prompt the user with a warning as described in 2b.
a. Name Character
b. Roll for Stats
R. Return to previous menu
3. If the user selects Purchase Equipment they will be shown a menu similar to that shown below. From this screen the user can opt to purchase either armor or weapons. Depending upon which submenu the user selects he will be shown a new menu listing the items available, their cost, and benefits. See the Armor and Weapons table below for information about what should be displayed and what items are available. The meaning of the fields in the tables below will be explained later. For now, just use it as a reference of what should be displayed in the item lists.
a. Purchase Armor
b. Purchase Weapon
R. Return to previous menu
Table 3.1 - Weapons
Unarmed Strike 1d3 (20/x2)
Brass Knuckles 1d4 (20/x2) 1g
Dagger 1d4 (19-20/x2) 2g
Mace 1d6 (20/x2) 5g
Handaxe 1d6 (20/x3) 6g
Shortsword 1d6 (19-20/x2) 6.5g
Scimitar 1d6 (18-20/x2) 7g
Morningstar 1d8 (20/x2) 8g
Spear 1d8 (20/x3) 9g
Longsword 1d8 (19-20/x2) 9.5g
Greatclub 1d10 (20/x2) 11g
Halberd 1d10 (20/x3) 12g
Bastard Sword 1d10 (19-20/x2) 12.5g
Greataxe 1d12 (20/x3) 16.0g
Greatsword 2d6 (19-20/x2) 20.0g
Table 3.2 - Armor
Unarmored AC: +0 Max Dex: INF
Padded Armor AC: +1 Max Dex: +8 5g
Leather Armor AC: +2 Max Dex: +6 10g
Hide Armor AC: +3 Max Dex: +4 15g
Studded Leather AC: +3 Max Dex: +5 25g
Scale Mail AC: +4 Max Dex: +3 50g
Chain Shirt AC: +4 Max Dex: +4 100g
Chainmail AC: +5 Max Dex: +2 150g
Breastplate AC: +5 Max Dex: +3 200g
Splint Mail AC: +6 Max Dex: +0 225g
Banded Mail AC: +6 Max Dex: +1 250g
Half-Plate AC: +7 Max Dex: +0 600g
Full Plate AC: +8 Max Dex: +1 1000g
4. If the user selects “View Stats” he will be shown a screen that displays the character’s stats. If no character has been created or if the character was killed in the arena, the output is simply “No Character Found.” After the stats or ‘no character’ message is displayed the player will be prompted to press any key. Doing so clears the screen and returns the player to the main menu. How the stats are displayed are up to the developer, but the following stats should be shown:
Name // Name of the Character
Level // Level of the Character (1-20)
Strength // Strength of the Character (8-20)
Dexterity // Dexterity of the Character (8-20)
Constitution // Constitution of the Character (8-20)
Hit Point // The hit points of the character
Experience // How many experience points the character has earned
Gold // The amount of gold the character has earned through victorious battles
5. If the user selects “Fight!” at the main menu he will be taken to another menu which allows the user to select which level of opponent he wants to fight, in the range of 1 to 20, depending on whether or not he’s defeated an opponent of the previous level. For example, the first time the user enters the menu, “Level 1” will be the only choice. After he defeats a “Level 1” opponent and returns to the menu, “Level 1” and “Level 2” will both be options. Similarly, after the player defeats a level 15 opponent, the level 16 opponent will become available…and the pattern continues with level 20 being the most difficult opponent.
Since the user can decide whether to fight an opponent of his level or less difficult, the choice he makes will determine how much experience and gold the player will get if he wins the battle. Listed below is a table that shows how much gold and experience a character gets for fighting mobs – relative to his own level.
Table 5.1 – Experience Rewards based on Opponent Level
Character Level: 300xp
Character Level - 1: 150xp
Character Level - 2: 75xp
Character Level – 3: 35xp
Character Level – 4: 15xp
Character Level – 5: 5xp
More than 5 levels below is 5xp
Table 5.2 – Treasure Rewards based on Opponent Level
Character Level: 25g
Character Level – 1: 12g
Character Level – 2 : 6g
Character Level – 3 : 3g
Character Level – 4 : 1g
Character Level – 5 : 0.5g
More than 5 levels below is 0.5g
Table 5.3 – Total Experience Points Required at each level
Level 1 - 0
Level 2 – 1,000
Level 3 – 3,000
Level 4 – 6,000
Level 5 – 10,000
To compute the remaining entries in the table up to level 20, simply take the previous level, multiply it by 1,000 and add it to the experience required for the previous level. Example:
Level 11 = (10 * 1,000) + 45,000 = 55,000
Level 12 = (11 * 1,000) + 55,000 = 66,000
If a character dies and the player returns to the “Fight” menu a “No Character Found” message will be shown, and the user will be returned to the main menu after pressing a key. If the character has died and a new character was created, the possible opponents are reset back to Level 1 and the character’s experience and gold are reset to 0.
6. Once the user has chosen an opponent, combat begins. Who attacks first is referred to as “Initiative” and is calculated based on the formula below. Once initiative is calculated for both the player and his opponent the scores are compared. Whoever has the higher initiative attack first. From then on the player’s character and his opponent alternate attacking each other every 2 seconds until someone dies.
Initiative: d20 + (Dexterity Modifier)
Each attack the success or failure of an attack and how much damage it does will be output to the screen, scrolling down. As an Example:
Round 3 (Caspian vs. Level 4); 25hp remaining
> Caspian swings his Shortsword at his opponent and misses.
> The level 4 opponent swings his Scimitar and strikes Caspian for 4 damage.
…2 second pause … // don’t display this…just note it in your mind
Round 4 (Caspian vs. Level 4); 21hp remaining
> Caspian swings his Shortsword at his opponent and critically hits him for 12 damage!
> The level 4 opponent dies.
> Caspian earns 300xp and 25g
> Press any key to continue….
When the combat finally ends one of two things will happen. If the player won, he will receive an amount of gold and experience according to the above table, and the additions will be output to the screen. If the player earned enough experience to be promoted to a new level then this too will be output to the screen, along with his new level number and his new hit points. If the player’s character died, however, then a message indicating the character died will be displayed, along with a message letting them know they must create a new combatant.
Project 1 - Discussion of Combat and Modifiers
Each round of combat we must determine a few things: We must determine whether or not an attack was successful (and if so was it critical) and then we need to determine how much damage was done to the opponent. This process is done for both the player and his opponent, depending on who’s currently attacking whom.
Step 1: Determining Attack Role
Whenever a character attempts to strike another an “Attack Roll” is performed. This is essentially calculating a random number between 1 and 20 (d20), and then adding on to the random number two values: the level of the attacker, and the attacker’s Strength Modifier. The attacker’s Strength Modifier is determined the same way as determining his Dexterity Modifier and his Constitution Modifier. You simply take the particular score, subtract 10 from it, and then divide the result by 2 (using integer truncation). As an example, lets assume my Strength is 15.
Attack Role: d20 + (Level + StrMod)
Strength Bonus: (15 – 10) / 2 = 2.5 = 2
So the final result is 2, after integer truncation. This value, plus the attacker’s level (1-20) is added to the random number that was calculated, and that becomes the attacker’s “Attack Role.”
Step 2: Determining Success of Attack
Now that we know what the attacker “rolled” we must determine whether or not it was high enough to successfully penetrate his opponents’ armor and fast reflexes. To do this simply compare the attack role with his opponents Armor Check. If the Attack Role was greater than or equal to his opponent’s armor check, the hit was successful. If it was lower, the hit was a ….miss.
Successful Attack: Attack Role >= Armor Check
To determine the opponent’s Armor Check, simply take 10, add onto it the opponent’s Armor Value (determined by equipment), and then add on to it the character’s Dexterity Modifier (calculated as the Strength Modifier above). Note that some armor limits the maximum value the Dexterity Modifier can contribute to the Armor Check. Scale Mail, for example, has a maximum Dexterity Bonus of +3…which means even if the person has a Dexterity Modifier of +4, only +3 of it counts towards the Armor Check. As an Example:
My character is equipped with Scale Mail, and has a Dexterity of 14.
Armor Value: +4
Dexterity Modifier: +2
Armor Check: 10 + 4 + 2 = 16
So based upon my Armor Check above, any Attack Role of 16 or higher would result in a successful attack.
Step 4: Determining Damage
If a successful attack role is made, then the next step is to determine how much damage will be subtracted from the opponent’s hit points. To determine the amount of damage, compute a random value based upon the weapon carried, and then add to it the Strength Modifier of the Attacker. For example lets assume my character has a Strength of 14 and is wielding a Shortsword (1d6). My damage would be a random value between 1 and 6, and then I would add to that value 2 (My computed Strength Modifier). The minimum damage would then be 3, and the maximum would be 8.
You can also see in the weapon list above, the Greatsword has a damage of 2d6. This means a random number between 1 and 6, twice. (ie the value from two 6-sided dice). So the actual range of values is from 2 to 12. In general you can determine the range of a roll by looking at the two numbers. The first number is the minimum, and the first number multiplied by the second number is the maximum value.
Step 5: Critical Strikes
By default if the random component of the Attack Role was 20 (called a natural 20), then a critical strike was made. By default this means that rather than computing the damage done once, it is computed twice. The addition of BOTH damage calculations are applied to the opponent’s hit points. So for example if I were still using my Shortsword (1d6) and I rolled a natural 20, I would then get to apply 1d6 damage, twice (x2).
Now, above I said that the default was a natural 20 (the random value came up 20), and the default was a x2 damage roll. Depending upon the weapon the attacker is carrying, this can be different. In the weapon list above you can see that some weapons say 18-20, 19-20, and also x2 or x3. These are critical strike modifiers. A 18-20 means that a natural roll of 18, 19, or 20 will result in the application of a critical strike (additional damage rolls). The x2 and x3 tell you how many damage rolls will actually be applied. So by default (non critical strike) you apply a x1 damage modifier. If the weapon says x2, you apply an extra damage roll. If the weapon says x3 you apply TWO extra damage rolls.
Project 1 - Hit points and Leveling
Whenever a character is first created they have hit points equal to 10 + their Constitution Modifier. Any time a character levels they receive additional hit points equal to 1d10 (random value between 1 and 10), plus their Constitution Modifier.
Starting HP : 10 + ConMod
Additional HP: 1d10 + ConMod
For example, I just created a new character with a Constitution of 14. Total starting hit points is 12. (10+2). The next time I level I roll a 10-sided dice (range: 1-10) and I add to it 2. So any time I level I can gain a possible 3 to 12 hit points.
After every battle, hit points should be restored back to the total value. So this means characters have a “maximum hit points” and then while fighting they have a “current hit points.” If current hit points ever drops to 0…the character is dead.
Project 1 - Conclusion
I’ve tried to give you a reasonable overview of how the menus should look, what kinds of items and treasures should be available and how combat should proceed. If you have any questions about the logistics of the program, please feel free to post your questions on the forums.
I encourage all people participating in the C++ Workshop to complete this project, as you can be assured it will be used again in later projects.