pharaun / alldice

Restful interface to a dice expression eval and generator.
Apache License 2.0
0 stars 1 forks source link

PCGEN dice roller. #26

Open pharaun opened 10 years ago

pharaun commented 10 years ago

PCGEN dice roller rules:

PCGEN RollInfo Dice:

ndm([/\|mM]a)*([+-]b){0,1}([tT]c){0,2}

    n - dices
    m - sides
    /a - keep top a dices
    \a - keep bottom a dices
    ma - Reroll if below a.
    Ma - Reroll if above a.
    |a,b,c - keep a,b,c dice (1-indexed sorted ascending)
    +b - Add b
    -b - Minus b
    tc - Min of c total.
    Tc - Max of c total.

Examples:
    d6
        One roll of a d6 dice

    2d6
        Two roll of a d6 dice summed

    4d6/3
        Four roll of a d6, keep highest 3

    4d6\3
        Four roll of a d6, keep lowest 3

    5d6|1,4
        Five roll of d6, keep roll 1, 4 (1-indexed sorted ascending)

    2d6m2
        Two roll of a d6, min of 2

    2d6M2
        Two roll of a d6, max of 2

    d6+3
        One roll of a d6 dice + 3

    10d6t10
        10 roll of d6 dice, with a min of 10 total.

    10d6T20
        10 roll of d6 with a max of 20 total.

PCGEN Data Dice:
min(v1,v2)
max(v1,v2)
pow(base, exponent)
roll(times, sides)
roll(times, sides, [keep])
roll(times, [sides])
roll(times, [sides], [keep])
roll(times, sides, numToKeep, reroll, modifier)

NOTES:
    [keep] - This is an array of 0-indexed dices to keep in the result. The rolls are generated
        and stored in an array, then they are sorted in ascending order (lowest to highest), then the
        values in [keep] are used as index to pull out the dice rolls to keep.

    [sides] - (doc has it as shape), This is an array of dice sides such as for d6 - [1, 2, 3, 4, 5, 6] in which
        the side is randomly selected out of this array and used as a dice-roll.

    d% - 1d100

    dF - fudge dice (1-2 -, 3-4 0, 5-6 +)

    numToKeep - (highest x dices to keep)

    reroll - roll(sides - reroll) + reroll; - Badly done (if not greater than x, reroll)

    modifier - the sum to add to the dice (ie 3d6 + modifier)

Examples:
    roll("3d6")
        Simulates rolling 3 six-sided dice.

    roll("1d20+10")
        Simulates rolling a twenty-sided die and adds 10.

    roll("min(4,7)")
        Returns a value of "4".

    roll("max(4,7)")
        Returns a value of "7".

    roll("pow(10,2)")
        Returns a value of "100".

    roll("roll(3,6)")
        Simulates rolling 3 six-sided dice.

    roll("roll(4,6,[2,3,4])")
        Simulates rolling 4 six-sided dice and keeps the 3 highest rolls.

    roll("roll(1,[3,5,7,9])")
        Similates rolling one 3, 5, 7 or 9 sided die, randomly selected.

    roll("roll(3,[2,3,4,5,6],[2,3])")
        Simulates rolling three 2, 3, 4, 5, or 6 sided dice, randomly selected and keeps the highest 2.

    roll("roll(4, 6, top(3), reroll(1))")
        Simulates rolling four 6 sided dices and picking top 3 and rerolling if not at least 1.

Example rolls:

roll(")
roll("10+d10")
roll("1d10")
roll("1d20+10")
roll("max(4,7)")
roll("min(4,7)")
roll("pow(10,2)")
roll("roll(1,[3,5,7,9])")
roll("roll(3,6)")
roll("roll(3,[2,3,4,5,6],[2,3])")
roll("roll(4,6,[2,3,4])")
roll("x")
roll()
roll(1,20,|VAR|,'text\n')
roll(4,5,[2,3,4])
roll(4,6,reroll(1))
roll(4,6,top(3))
roll(4,6,top(3),reroll(1))

Citation:

pharaun commented 10 years ago

Half way there, I have the data rolls implemented, Working on the programmable rolls. Once we're done with this group the remaining work will be to integrate it into the system + provide a pcgen -> scheme AST builder for building the AST for the scheme engine to execute.

pharaun commented 10 years ago

I now support expression parsing and have a mini AST of the known syntax for pcgen.

Only thing left to do is clean up the parser and the AST, ie I would really like to be able to fold Expr into Function calls since its what will happen under the hood anyway.

Should be able to soon write the PCGenAST -> LispVal AST transformation to get our scheme AST for execution.

The primary question is probably, how to deal with calling functions in the standard library, and how to keep them in sync, or should i only emit primitive AST and no standard library function calls?