Skip to content

Programming by Design

If you're not prepared to be wrong, you'll never come up with anything original. – Sir Ken Robinson

  • About
  • Java-PbD
  • C-PbD
  • ASM-PbD
  • Algorithms
  • Other

DND Code

Posted on April 9, 2018January 11, 2021 By William Jojo
Uncategorized

Stats for the average human!

DND Character Sheet

The code shown below will perform [#]d{#}[+#] rolls.

Examples:

d20
d10
4d6
6d6+8
4d12 + 10

When you run this code, you will run it as:

java RollD '4d12 + 10'

or

java RollD 6d6+8
public class RollD {
  
  public static void usage() {
    System.out.println("\n\nRollD  {#}d##{+#}\n");
    System.exit(1);
  }

  public static int dRandom(int d) {
    // always returns value in range 1 to d.
    int r = (int)(Math.random() * d) + 1;
    // debug
    //System.out.println("d" + d + "=" + r);
    
    return r;
  }
  
  public static void main(String[] args) {
    
    int plusPos, dPos, x;
    int plus, die, numD, total;
    String roll;
    
    // Need something...
    if (args.length == 0)
      usage();
    
    // got something

    // remove spaces
    roll = args[0].replace(" ", "");

    // be there a plus sign?
    plusPos = roll.indexOf('+');

    // look for the 'd'
    dPos = roll.indexOf('d');
    
    // no 'd'? well, that's not good...
    if ( dPos == -1 )
      usage();
    
    // if there is a plus, convert the additive to an int.
    if ( plusPos != -1 ) {
      plus = Integer.parseInt(roll.substring(plusPos + 1));
      roll = roll.substring(0, plusPos);
    } else
      plus = 0;
    
    // if 'd' is not the first char,
    // there should be more than one of that 'd' rolled.
    if ( dPos > 0 )
      numD = Integer.parseInt(roll.substring(0, dPos));
    else
      numD = 1;
    
    // which 'd' are we talking about here?
    die = Integer.parseInt(roll.substring(dPos + 1));
    
    total = 0;
    for ( x = 0; x < numD; x++ )
      total = total + dRandom(die);
    
    System.out.println(total + plus);
    
  }
}

While the previous example allows for command line ability, the following piece of code had turned the concept into a library.

public class D20 {
  
  public static boolean DBG = false;
  
  public static int dRandom(int d) {
    // always returns value in range 1 to d.
    int r = (int)(Math.random() * d) + 1;
    
    if (DBG)
      System.out.println("d" + d + " = " + r);
     
    return r;
  }
  
  public static int hi3of4d6() {
    int r1, r2, r3, r4, sm, sum;
     
    r1 = dRandom(6);
    r2 = dRandom(6);
    r3 = dRandom(6);
    r4 = dRandom(6);
     
    // debug
    if (DBG)
      System.out.println("r1 = " + r1 + " r2 = " + r2 + " r3 = " + r3 + " r4 = " + r4);
     
    sm = Math.min(Math.min(r1, r2), Math.min(r3, r4));
    if ( r4 != sm )
      if ( r1 == sm )
        r1 = r4;
      else if ( r2 == sm )
        r2 = r4;
      else if ( r3 == sm )
        r3 = r4;
         
    sum = r1 + r2 + r3;
        
    // debug
    if (DBG) {
      System.out.println("r1 = " + r1 + " r2 = " + r2 + " r3 = " + r3 + " r4 = " + r4);
      System.out.println("Total = " + (sum));
    }
    
    return sum;
  }
    
  public static int rollD(String s) {
    int plusPos, dPos, x;
    int plus = 0, die, numD = 1, total = 0;
    String roll;
     
    // Need something...
    if (s.length() == 0)
      return -1;
     
    // got something
 
    // remove spaces
    if (DBG)
      System.out.println("roll before \"" + s + "\"");
    roll = s.replace(" ", "");
    if (DBG)
      System.out.println("roll after  \"" + roll + "\"");
 
    // be there a plus sign?
    plusPos = roll.indexOf('+');
 
    // look for the 'd'
    dPos = roll.indexOf('d');
     
    // no 'd'? well, that's not good...
    if ( dPos == -1 )
      return -1;
     
    // if there is a plus, convert the additive to an int.
    if ( plusPos != -1 ) {
      plus = Integer.parseInt(roll.substring(plusPos + 1));
      roll = roll.substring(0, plusPos);
      
      if (DBG) {
        System.out.println("plus is " + plus);
        System.out.println("roll is now \"" + roll + "\"");
      }
    }
     
    // if 'd' is not the first char,
    // there should be more than one of that 'd' rolled.
    if ( dPos > 0 )
      numD = Integer.parseInt(roll.substring(0, dPos));
      
    if (DBG)
      System.out.println("numD is " + numD);
     
    // which 'd' are we talking about here?
    die = Integer.parseInt(roll.substring(dPos + 1));
    if (DBG)
      System.out.println("die is " + die);
     
    for ( x = 0; x < numD; x++ ) {
      int d;
      
      d = dRandom(die);
      if (DBG)
        System.out.println("For roll " + (x + 1) + ", d is " + d);
        
      total = total + d;
    }
    if (DBG)
      System.out.println("total is " + total);
      
    return total + plus;
  }
  
  public static void main(String[] args) {
    
    // This is the test suite for D20.
    if ( args.length == 1 && args[0].compareTo("-d") == 0 ) {
      DBG = true;
      
      System.out.println("hi3of4d6 is " + hi3of4d6());
      
      String[] tests = {"d4", "d6", "d8", "d10", "d12", "d20", "d100", "6d6 + 10", "6 d 6 + 10"};
      
      for (int x = 0 ; x < tests.length ; x++ ) {
        System.out.println("\nDEBUG for Roll #" + (x+1) + "\n");
        System.out.println("\nRoll #" + (x+1) + ": " + tests[x] + " = " + rollD(tests[x]));
      }
    }
    
  }
}

And now we have a Swing version of a GUI that utilizes the D20 class from above.

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
  
public class RollDGUI extends JFrame implements ActionListener {
    
  String[] bval = {"d4", "d6", "d8", "d10", "d12", "d20", "d100"};
  JButton[] buttons = new JButton[7];
  JLabel rollLabel = new JLabel("Roll"), resultLabel = new JLabel("Result");
  JTextField rollTF = new JTextField(""), resultTF = new JTextField("");
  JButton rollButton = new JButton("ROLL!");
  JButton hi3of4d6 = new JButton(">3 of 4d6");
    
  public RollDGUI() {
    int x;
        
    setTitle("RollD");
    //setResizable(false);
    setSize(500,300); 
    setDefaultCloseOperation(EXIT_ON_CLOSE);
      
    setLayout(new GridLayout(3,5));
    
    // Fill the buttons with values and setup ActionListener
    for (x = 0; x < buttons.length; x++) {
      buttons[x] = new JButton(bval[x]);
      buttons[x].addActionListener(this);
      //buttons[x].setBackground(Color.blue);
    }
    rollButton.addActionListener(this);
    hi3of4d6.addActionListener(this);
    
    // row 1
    add(rollLabel);
    add(rollTF);
    add(buttons[0]);
    add(buttons[1]);
    add(buttons[2]);
    // row 2
    add(rollButton);
    add(new JLabel(""));
    add(buttons[3]);
    add(buttons[4]);
    add(buttons[5]);
    // row 3
    add(resultLabel);
    add(resultTF);
    resultTF.setEditable(false);
    add(hi3of4d6);
    add(buttons[6]);
    add(new JLabel(""));
    getRootPane().setDefaultButton(rollButton);
    
    setVisible(true);
  }
    
  public void actionPerformed(ActionEvent e) {
      
    Object s = e.getSource();
    
    //System.err.println("Source is " + s);
      
    if ( s == buttons[0] || s == buttons[1] || s == buttons[2] || s == buttons[3] ||
        s == buttons[4] || s == buttons[5] || s == buttons[6] )
      resultTF.setText("" + D20.rollD(((JButton)s).getText()));
    else if ( s == rollButton ) {
      resultTF.setText("" + D20.rollD(rollTF.getText()));
    } else if ( s == hi3of4d6 ) {
      resultTF.setText("" + D20.hi3of4d6());
    }
  }
    
  public static void main(String[] args) {
    
    try {
      UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
    }
    catch (Exception e) {
      // Not good.
    }

    RollDGUI t = new RollDGUI();
      
  }
}

Example to calculate ability modifiers (not proficiency-based!)

public class AbilityModifier {
  public static void main(String[] args) {
    
    for (int x = 1; x <= 30; x++)
      System.out.println(x + " = " + modifier(x));
  }
  
  public static int modifier(int ab) {
    return (int)(Math.floor((ab - 10) / 2.0));
  }
}

class Abilities {
  
  private int STR, DEX, CON, INT, WIS, CHA;
  

  public int getSTR() {
    return STR;
  }

  public int getDEX() {
    return DEX;
  }

  public int getCON() {
    return CON;
  }

  public int getINT() {
    return INT;
  }

  public int getWIS() {
    return WIS;
  }

  public int getCHA() {
    return CHA;
  }

  public void setSTR(int v) {
    STR = v;
  }
  
  public void setDEX(int v) {
    DEX = v;
  }
  
  public void setCON(int v) {
    CON = v;
  }
  
  public void setINT(int v) {
    INT = v;
  }
  
  public void setWIS(int v) {
    WIS = v;
  }
  
  public void setCHA(int v) {
    CHA = v;
  }
  
  public static void main(String[] args) {
    
  }
}
public class DNDCharacter {

  // housekeeping
  private int a1, a2, a3, a4, a5, a6;
  
  // for character
  private int AC;
  private Abilities abilities;
  private int initiative;
  private int level;
  private int speed;
  private int hit_die;
  
  public static int dRandom(int d) {
    // always returns value in range 1 to d.
    int r = (int)(Math.random() * d) + 1;
    // debug
    //System.out.println("d" + d + "=" + r);
    
    return r;
  }
  
  private static int hi3of4d6() {
    int r1, r2, r3, r4, sm, sum;
    
    r1 = dRandom(6);
    r2 = dRandom(6);
    r3 = dRandom(6);
    r4 = dRandom(6);
    
    // debug
    System.out.println("r1 = " + r1 + " r2 = " + r2 + " r3 = " + r3 + " r4 = " + r4);
    
    sm = Math.min(Math.min(r1, r2), Math.min(r3, r4));
    if ( r4 != sm )
      if ( r1 == sm )
        r1 = r4;
      else if ( r2 == sm )
        r2 = r4;
      else if ( r3 == sm )
        r3 = r4;
        
    sum = r1 + r2 + r3;
       
    // debug
    System.out.println("r1 = " + r1 + " r2 = " + r2 + " r3 = " + r3 + " r4 = " + r4);
    System.out.println("Total = " + (sum));
    
    return sum;
  }
  
  public DNDCharacter() {
    abilities = new Abilities();
  }
  
  public DNDCharacter(int level) {
    abilities = new Abilities();
    this.level = level;
  }

  private void setDefaultScores() {
    a1 = 15;
    a2 = 14;
    a3 = 13;
    a4 = 12;
    a5 = 10;
    a6 = 8;
  }
  
  private void setRandomScores() {
    a1 = hi3of4d6();
    a2 = hi3of4d6();
    a3 = hi3of4d6();
    a4 = hi3of4d6();
    a5 = hi3of4d6();
    a6 = hi3of4d6();
  }
  
  public static void main(String args []) {
    hi3of4d6();
  }

}

Post navigation

❮ Previous Post: Facilitating Learning – Final Project Specification – Spring 2018
Next Post: CISS-150 Syllabus ❯

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.

Copyright © 2018 – 2025 Programming by Design.