Вычислить бросок костей из текстового поля

ВОПРОС: Как я могу прочитать строку "d6+2-d4", чтобы каждый d # случайно генерировал число в параметре броска костей?

ПОЯСНИТЕЛЬ: Я хочу прочитать строку и получить ее, чтобы при появлении объявления # оно генерировало случайное число, например, для имитации броска игральных костей. Затем сложите все рулоны и числа, чтобы получить общее количество. Очень похоже на то, как Roll20 делает с их командой /roll для примера. 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...")}

Информация: я делал Java-программу для Dungeons and Dragons, но обнаружил, что столкнулся с проблемой выяснения способа вычисления пользовательского ввода: я не знаю, как оценить строку, подобную этой.

Я предполагаю, что мне может понадобиться Java eval в конце. Я знаю, что я хочу, чтобы иметь / есть теория о том, как выполнить (это больше PseudoCode, чем 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);

РЕДАКТИРОВАТЬ: С помощью Уэстон, я отточил то, что, вероятно, необходимо, используя сплиттер с массивом, он может обнаружить определенные символы и добавить его в список. Однако я виноват в том, что не уточнил, что еще было нужно. Приведенный выше псевдокод не помогает, так что это то, что мне еще нужно выяснить.

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

Поскольку эта часть - то, что также сбивает меня с толку. Должен ли я делать сплиты там, где есть числа? Итак, уравнение вроде:

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

у goon это было, просто мне показалось, что это не для меня (пока я не понял, что не определился с тем, что я хотел), поэтому в основном нужно обновить строку, которую я хочу оценить (я знаю, что это немного неортодоксально, но это важно, я также надеюсь, что это прояснит еще больше того, что нужно, чтобы это работало):

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

Прочитав это, вы можете увидеть места, которые я не знаю, как работать очень хорошо... Но именно поэтому я прошу всех вас, милые, умные программисты! Я надеюсь, что спросил это достаточно ясно и спасибо за ваше время:3

1 ответ

Решение

Хитрость в любой проблеме программирования состоит в том, чтобы разбить ее и написать метод для каждой части, поэтому ниже у меня есть метод для бросания одного кубика, который вызывается одним для бросания многих.

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;
}
Другие вопросы по тегам