Evaluate dice rolling notation strings

前端 未结 14 1456
甜味超标
甜味超标 2021-01-30 14:55

Rules

Write a function that accepts string as a parameter, returning evaluated value of expression in dice notation, including addition and multiplication.

To

14条回答
  •  时光取名叫无心
    2021-01-30 15:09

    JAVASCRIPT, 1399 chars, no eval

    old post, i know. but i try to contribute

    Roll = window.Roll || {};
    
    Roll.range = function (str) {
        var rng_min, rng_max, str_split,
            delta, value;
    
        str = str.replace(/\s+/g, "");
        str_split = str.split("-");
        rng_min = str_split[0];
        rng_max = str_split[1];
    
        rng_min = parseInt(rng_min) || 0;
        rng_max = Math.max(parseInt(rng_max), rng_min) || rng_min;
    
        delta = (rng_max - rng_min + 1);
    
        value = Math.random() * delta;
        value = parseInt(value);
    
        return value + rng_min;
    };
    
    Roll.rollStr = function (str) {
        var check,
            qta, max, dice, mod_opts, mod,
            rng_min, rng_max,
            rolls = [], value = 0;
    
        str = str.replace(/\s+/g, "");
        check = str.match(/(?:^[-+]?(\d+)?(?:\/(\d+))?[dD](\d+)(?:([-+])(\d+)\b)?$|^(\d+)\-(\d+)$)/);
    
        if (check == null) {return "ERROR"}
        qta = check[1];
        max = check[2];
        dice = check[3];
        mod_opts = check[4];
        mod = check[5];
        rng_min = check[6];
        rng_max = check[7];
        check = check[0];
    
        if (rng_min && rng_max) {return Roll.range(str)}
    
        dice = parseInt(dice);
        mod_opts = mod_opts || "";
        mod = parseInt(mod) || 0;
        qta = parseInt(qta) || 1;
        max = Math.max(parseInt(max), qta) || qta;
    
        for (var val; max--;) {
            val = Math.random() * dice;
            val = Math.floor(val) + 1;
            rolls.push(val);
        }
    
        if (max != qta) {
            rolls.sort(function (a, b) {return a < b});
            rolls.unshift(rolls.splice(0, qta));
        }
    
        while (rolls[0][0]) {value += rolls[0].shift();}
    
        if (mod_opts == "-") {value -= mod;}
        else {value += mod;}
    
        return value
    };
    
    if (!window.diceRoll) {window.diceRoll= Roll.rollStr;}
    

    it's a single dice roll, like "2d8+2" or "4-18" "3/4d6" (best 3 of 4 d6)

    diceRoll("2d8+2"); 
    diceRoll("4-18");
    diceRoll("3/4d6");
    

    to check cumulative rolls, better loop on matched result ove rthe input string like

    r = "2d8+2+3/4d6"
    r.match(/([-+])?(\d+)?(?:\/(\d+))?[dD](\d+)(?:([-+])(\d+)\b)?/g);
    // => ["2d8+2", "+3/4d6"]
    // a program can manage the "+" or "-" on the second one (usually is always an addiction)
    

提交回复
热议问题