Problem of the Week

Stories
The Ds of D&D
This is a beginner level assignment that gets progressively more difficult and complex.  Topics Covered:
 
  • Output
  • Random Number Generation
  • Decisions
  • Looping
  • Accumulation
  • Averaging
  • Reasoning
The D’s of D&D
 
TEACHER’S NOTES
===================================================================================
Modules:
 
Structured Programming 1 (random number generation, input, output)
Structured Programming 2 (IF statements, FOR loops, accumulation algorithms)
 
Notes:
 
Many people will think that the Great Sword will be the best weapon because its damage range is from 2 to 12 while the Great Axe has a damage range from 1 to 12.  However, it is important to realize that, because the Great Sword’s damage is made by rolling two six-sided dice, it is more likely to achieve results that tend towards the average and rarely get numbers at the edges of the damage range.  Thus, there is a 2.8% chance that a Great Sword will deal 12 damage while a Great Axe has an 8.3% chance of doing the same damage.
 
At the end, students should try to interpret the results of the simulation for the barbarian.  The results will usually be that the Great Sword deals more damage than the Great Axe in any particular round but that the Great Axe deals more damage on average than the Great Sword?  How could this be?  The answer is that the Great Sword is more consistent in its damage output while the Great Axe is more explosive.  That is, it wins less often but when it does, it wins by a lot.
===================================================================================
 
 
 
The D’s of D&D
In the game of Dungeons and Dragons, players can choose weapons for their characters.  One of these weapons, the Great Axe, does 1D12 damage which means that the player rolls a single 12-sided die for damage.  The result of this would be damage from 1 to 12.  Another weapon, the Great Sword, does 2D6 damage meaning that the player rolls two 6-sided dice for damage and the result is damage from 2 to 12.  Are there any real differences between these two weapon choices?
 
Exploration:
Part 1:
Write a program that generates a random number from 1 to 12 to simulate the damage done by the Great Axe.  The program will display the damage done by this weapon.  The program will then generate two random numbers from 1 to 6 and find the sum of these two numbers to simulate the damage from the Great Sword.  The program will then display the damage done by this weapon.
After displaying the damage from each weapon, the program will say which of the two weapons dealt more damage.  If there is a tie, the program will announce that both weapons did the same damage.
 
SAMPLE OUTPUT:
WEAPONS TEST:
Great Axe: 8
Great Sword: 10
The Great Sword did more damage.
 
 
Part 2:
Modify your program to include a FOR loop that runs 1000 trials and tracks which of the two weapons dealt more damage over the course of the trials.
SAMPLE OUTPUT:
WEAPONS TEST:
Great Axe: 8
Great Sword: 10
The Great Sword did more damage.
Running 1000 Tests…
Great Axe Wins: 450
Great Sword Wins: 550
The Great Sword wins more often.
 
Part 3:
Modify the algorithm to show the average damage that was dealt by each weapon during the 1000 trials.
SAMPLE OUTPUT:
WEAPONS TEST:
Great Axe: 8
Great Sword: 10
The Great Sword did more damage.
Running 1000 Tests…
Great Axe Wins: 450
Great Sword Wins: 550
The Great Sword wins more often.
 
AVG Damage:
-----------
Great Axe: 7.7
Great Sword: 8.2
 
Part  4:
One of the characters in the game is a barbarian who deals double damage whenever they roll an 11 or a 12 for damage.  Modify your program to calculate the average damage for each weapon under these conditions and suggest the best choice for this character.
 
 
 
Solution (C++)
#include <iostream>
#include <time.h>
#include <cstdlib>
 
using namespace std;
 
int main()
{
    srand(time(0));
    int axeDMG, swordDMG;
 
    cout << "WEAPONS TEST:" << endl;
 
    axeDMG = rand()%12+1;
    swordDMG = (rand()%6+1) + (rand()%6+1);
 
    cout << "Great Axe: " << axeDMG << endl;
    cout << "Great Sword: " << swordDMG << endl;
 
    if(axeDMG > swordDMG)
        cout << "The Great Axe did more damage." << endl;
    else if (swordDMG > axeDMG)
        cout << "The Great Sword did more damage." << endl;
    else
        cout << "Both weapons did the same damage." << endl;
 
    cout << "Running 1000 Tests..." << endl;
 
    int axeWins = 0, swordWins = 0;
 
    //PART 3:============
        int totalAxeDMG = 0, totalSwordDMG = 0;
    //===================
 
    for(int x = 0; x < 1000; x++) {
        axeDMG = rand()%12+1;
        swordDMG = rand()%6+1 + rand()%6+1;
 
    //Part 4:============
    if(axeDMG >= 10)
        axeDMG *= 2;
    if(swordDMG >= 10)
        swordDMG *= 2;
    //===================
 
    //PART 3:============
        totalAxeDMG += axeDMG;
        totalSwordDMG += swordDMG;
    //===================
 
        if(axeDMG > swordDMG)
            axeWins++;
        else if (swordDMG > axeDMG)
            swordWins++;
    }
 
    cout << "Great Axe Wins:" << axeWins << endl;
    cout << "Great Sword Wins:" << swordWins << endl;
 
    if(axeWins > swordWins)
        cout << "The Great Axe wins more often." << endl;
    else if(axeWins < swordWins)
        cout << "The Great Sword wins more often" << endl;
    else
        cout << "It was a tie!";
 
    cout << "AVG Damage:" << endl;
    cout << "-----------" << endl;
    cout << "Great Axe: " << totalAxeDMG/1000.0 << endl;
    cout << "Great Sword: " << totalSwordDMG/1000.0 << endl;
    //NOTE: Divide by 1000.0 to get a floating point result.
    return 0;
}
 
 
 
Solution (JAVA)
 
public class Main {
 
       public static void main(String[] args) {
             
           int axeDMG, swordDMG;
 
           System.out.println("WEAPONS TEST:");
 
           axeDMG = (int)(Math.random()*12+1);
           swordDMG = (int)(Math.random()*6+1) + (int)(Math.random()*6+1);
 
           System.out.println("Great Axe: " + axeDMG);
           System.out.println("Great Sword: " + swordDMG);
 
           if(axeDMG > swordDMG)
               System.out.println("The Great Axe did more damage.");
           else if (swordDMG > axeDMG)
              System.out.println("The Great Sword did more damage.");
           else
               System.out.println("Both weapons did the same damage.");
 
           System.out.println("Running 1000 Tests...");
          
           int axeWins = 0, swordWins = 0;
          
           //Part 3:=====
           int totalAxeDMG = 0, totalSwordDMG = 0;
           //============
          
           for(int x = 0; x < 1000; x++) {
              axeDMG = (int)(Math.random()*12+1);
              swordDMG = (int)(Math.random()*6+1) + (int)(Math.random()*6+1);
      
              //Part 4:================
              if(axeDMG >= 10)
                     axeDMG *= 2;
              if(swordDMG >= 10)
                     swordDMG *= 2;
              //=======================
             
              //Part 3:=====
              totalAxeDMG += axeDMG;
              totalSwordDMG += swordDMG;
              //============
             
                     if(axeDMG > swordDMG)
                           axeWins++;
                     else if (swordDMG > axeDMG)
                           swordWins++;
           }
          
           System.out.println("Great Axe Wins:" + axeWins);
           System.out.println("Great Sword Wins:" + swordWins);
          
           if(axeWins > swordWins)
              System.out.println("The Great Axe wins more often.");
           else if(axeWins < swordWins)
              System.out.println("The Great Sword wins more often");
           else
              System.out.println("It was a tie!");
          
           //Part 3:==============
           System.out.println("AVG Damage:");
           System.out.println("-----------");
           System.out.println("Great Axe: " + totalAxeDMG/1000.0);
           System.out.println("Great Sword: " + totalSwordDMG/1000.0);
           //Note: Divide by 1000.0 to make a floating point answer
           //======================
          
       }
 
}
 
Read more...