0

QUESTION: How can I read the string "d6+2-d4" so that each d# will randomly generate a number within the parameter of the dice roll?

CLARIFIER: I want to read a string and have it so when a d# appears, it will randomly generate a number such as to simulate a dice roll. Then, add up all the rolls and numbers to get a total. Much like how Roll20 does with their /roll command for an example. If !clarifying {lstThen.add("look at the Roll20 and play with the /roll command to understand it")} else if !understandStill {lstThen.add("I do not know what to say, someone else could try explaining it better...")}

Info: I was making a Java program for Dungeons and Dragons, only to find that I have come across a problem in figuring out how to calculate the user input: I do not know how to evaluate a string such as this.

I theorize that I may need Java's eval at the end. I do know what I want to happen/have a theory on how to execute (this is more so PseudoCode than Java):

Random rand = new Random();
int i = 0;
String toEval;
String char;

String roll = txtField.getText();

while (i<roll.length) {
    check if character at i position is a d, then highlight the numbers
    after d until it comes to a special character/!aNumber
    // so if d was found before 100, it will then highlight 100 and stop
    // if the character is a symbol or the end of the string
    if d appears {
        char = rand.nextInt(#);
        i + #'s of places;
        // so when i++ occurs, it will move past whatever d# was in case
        // d# was something like d100, d12, or d5291
    } else {
        char = roll.length[i];
    }
    toEval = toEval + char;
    i++;
}

perform evaluation method on toEval to get a resulting number
list.add(roll + " = " + evaluated toEval);

EDIT: With weston's help, I have honed in on what is likely needed, using a splitter with an array, it can detect certain symbols and add it into a list. However, it is my fault for not clarifying on what else was needed. The pseudocode above doesn't helpfully so this is what else I need to figure out.

roll.split("(+-/*^)");

As this part is what is also tripping me up. Should I make splits where there are numbers too? So an equation like:

String[] numbers = roll.split("(+-/*^)");
String[] symbols = roll.split("1234567890d")

// Rough idea for long way
loop statement {
    loop to check for parentheses {
        set operation to be done first
    }

    if symbol {
        loop for symbol check {
            perform operations
    }}} // ending this since it looks like a bad way to do it...

// Better idea, originally thought up today (5/11/15)
int val[];
int re = 1;

loop {
    if (list[i].containsIgnoreCase(d)) {
        val[]=list[i].splitIgnoreCase("d");
        list[i] = 0;
        while (re <= val[0]) {
            list[i] = list[i] + (rand.nextInt(val[1]) + 1);
            re++;
        }
    }
}
// then create a string out of list[]/numbers[] and put together with
// symbols[] and use Java's evaluator for the String

wenton had it, it just seemed like it wasn't doing it for me (until I realised I wasn't specific on what I wanted) so basically to update, the string I want evaluated is (I know it's a little unorthodox, but it's to make a point; I also hope this clarifies even further of what is needed to make it work):

(3d12^d2-2)+d4(2*d4/d2)

From reading this, you may see the spots that I do not know how to perform very well... But that is why I am asking all you lovely, smart programmers out there! I hope I asked this clearly enough and thank you for your time :3

Kanto Ruki
  • 27
  • 9
  • Your goal is not 100% clear, Can you please give a full example of what you want, so it will make your goal clear ? – Mercury May 10 '15 at 08:38
  • It's not fair stack overflow practice to ask one question, then completely change it. No one can answer a moving goalpost. You have enough information now to have a stab at some **real** java code, enough with the pseudo code! When you're stuck again, ask another question. – weston May 12 '15 at 07:46
  • Okay, I'll leave it alone... – Kanto Ruki May 12 '15 at 08:33

1 Answers1

0

The trick with any programming problem is to break it up and write a method for each part, so below I have a method for rolling one dice, which is called by the one for rolling many.

private Random rand = new Random();

/**
 * @param roll can be a multipart roll which is run and added up. e.g. d6+2-d4
 */
public int multiPartRoll(String roll) {
    String[] parts = roll.split("(?=[+-])"); //split by +-, keeping them
    int total = 0;
    for (String partOfRoll : parts) { //roll each dice specified
        total += singleRoll(partOfRoll);
    }
    return total;
}

/**
 * @param roll can be fixed value, examples -1, +2, 15 or a dice to roll
 * d6, +d20 -d100
 */
public int singleRoll(String roll) {
    int di = roll.indexOf('d');
    if (di == -1) //case where has no 'd'
        return Integer.parseInt(roll);
    int diceSize = Integer.parseInt(roll.substring(di + 1)); //value of string after 'd'
    int result = rand.nextInt(diceSize) + 1; //roll the dice
    if (roll.startsWith("-")) //negate if nessasary
        result = -result;
    return result;
}
weston
  • 54,145
  • 21
  • 145
  • 203
  • Oh! So I could use a loop with something like if parts[i] contains d, remove d and use number for rand. – Kanto Ruki May 10 '15 at 10:39
  • That is what I am doing – weston May 10 '15 at 11:41
  • I knew there was something I missed, would you use the splitter again for something like 2d6 to roll 2 6-sided die? – Kanto Ruki May 12 '15 at 05:00
  • Wait... I didnt realise this until now, but I'll need multiple conditions on handling them... I'll update the question – Kanto Ruki May 12 '15 at 05:14
  • You could use the splitter again. And as for the other conditions, pay close attention to how I am splitting by + and - and keeping the +,- see here for more on that http://stackoverflow.com/a/2206432/360211 – weston May 12 '15 at 07:38