The Bot Bikeshed
-
@DMBot roll 3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3
-
-
@Gribnit
4206457
-
@DMBot roll 3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3
-
@Gribnit
1520361844
-
BRUTAL. so, one way to go is to, once you've got your ast, estimate your worst execution path cost. for instance you have a number of dependent executions in 3d3d3. you could also decouple the number of times you run the sampler against your random source this way, if you don't want to simply refuse to evaluate trees this deep.
-
@error said in The Bot Bikeshed:
I think I've got the lexer figured out. Going from stream of tokens to tree of nodes is the missing link.
My own bot used someone else's expression parser, but it was in C#. I can look it up if needed be...
-
@Gribnit said in The Bot Bikeshed:
BRUTAL. so, one way to go is to, once you've got your ast, estimate your worst execution path cost. for instance you have a number of dependent executions in 3d3d3. you could also decouple the number of times you run the sampler against your random source this way, if you don't want to simply refuse to evaluate trees this deep.
You realize you're testing Mason's bot right? Not my implementation.
-
@error yeah but your implementation didn't have a DoS vector
-
@Gribnit said in The Bot Bikeshed:
@error yeah but your implementation didn't have a DoS vector
It did but I found it before you guys did.
-
@error said in The Bot Bikeshed:
@Gribnit said in The Bot Bikeshed:
@error yeah but your implementation didn't have a DoS vector
It did but I found it before you guys did.
in any case, estimating the worst-case number of samples vs the RNG and taking them in a separate thread is probably best to avoid sideband exposure.
-
@error said in The Bot Bikeshed:
@Gribnit said in The Bot Bikeshed:
@error yeah but your implementation didn't have a DoS vector
It did but I found it before you guys did.
Did you find the DoS vector in the proposed capital-R reroll implementation? I was kinda looking forward to testing that...
-
@Mason_Wheeler He cut it off before capital-R reroll was even a thing. If the probability of rolling more than 256 dice (according to the parsed elements) is greater than some epsilon, it's rejected.
-
Overflow condition that could result in negative roll results has been fixed in DMBot. Dice rolling will now reject any value greater than 1000 on either side of the
d
operator.
-
@Mason_Wheeler said in The Bot Bikeshed:
Overflow condition that could result in negative roll results has been fixed in DMBot. Dice rolling will now reject any value greater than 1000 on either side of the
d
operator.Sounds like it won't be much use for a Shadowrun game then...
-
@DMBot 2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2
-
@Gribnit
Huh?
-
@DMBot roll 2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2
-
@Gribnit
Please keep all nonsense in the Garage where it belongs
-
@DMBot roll 2d2d2d2d2d2d2d2d2d2d2d2d2d2d2
-
@Gribnit
663
-
FWIW, I like this one:
The devs never did get around to adding a dice roller to Realm Works. :(
-
@Parody said in The Bot Bikeshed:
FWIW, I like this one:
The devs never did get around to adding a dice roller to Realm Works. :(
I may steal
theiryour? syntax.
-
@error said in The Bot Bikeshed:
@Parody said in The Bot Bikeshed:
FWIW, I like this one:
The devs never did get around to adding a dice roller to Realm Works. :(
I may steal
theiryour? syntax.Feel free.
It helped me learn a little JavaScript and work around the limitations of the web viewer in a .NET WinForms program. (Reports as IE 7.)
-
@error_bot lex (3d6+3)*5, 1+2^3-max(2d6k1l)
-
[ Â { type: 'operator', symbol: '(' }, Â { type: 'dice', count: 3, sides: 6 }, Â { type: 'operator', symbol: '+' }, Â { type: 'numericLiteral', value: 3 }, Â { type: 'operator', symbol: ')' }, Â { type: 'operator', symbol: '*' }, Â { type: 'numericLiteral', value: 5 }, Â { type: 'operator', symbol: ',' }, Â { type: 'whitespace', ws: ' ' }, Â { type: 'numericLiteral', value: 1 }, Â { type: 'operator', symbol: '+' }, Â { type: 'numericLiteral', value: 2 }, Â { type: 'operator', symbol: '^' }, Â { type: 'numericLiteral', value: 3 }, Â { type: 'operator', symbol: '-' }, Â { type: 'identifier', name: 'max' }, Â { type: 'operator', symbol: '(' }, Â { type: 'dice', count: 2, sides: 6 }, Â { type: 'operator', symbol: ')' } Â]
-
Strategy:
- separate statements (,;)
- foreach statement, build a tree of tokens that get replaced by nodes
- match parens (use a stack; if count != 0 at the end, then mismatch)
- parens yield a preliminary tree structure
- parens preceded by identifier? then method; else bracketed expression
- parse operators in order: {^}, {*, /}, {+, -}
- determine if binary or unary expression... backtrack? maybe don't support unary for now
- verify tree contains only nodes, no tokens
-
@error said in The Bot Bikeshed:
Strategy
If you're working in C++, I came across Parsing Expression Grammar Template Library at one point. Haven't needed it yet, just have it bookmarked.
-
@error remember the subtlety of the d operator, as it relates to implied multiplication. also, whether to respect the rounding rules properly on repeated multiplications.
I was planning to wait until you were mostly done to mention how sneak attack dice need to work relative to crit multipliers, but I am in a good mood today.
You may want to consider having whitespace influence associativity. This sounds insane, it isn't, people write dice expressions using this convention.
-
So far...
@error_bot parse 2d2+(3d3-2*min(3+2d2-1))
-
{ Â type: 'statement', Â expressions: [ Â { Â value: null, Â children: [ Â { value: { type: 'dice', count: 2, sides: 2 }, children: [] }, Â { value: { type: 'operator', symbol: '+' }, children: [] }, Â { Â value: { type: 'bracketOpen', symbol: '(', close: ')' }, Â children: [ Â { Â value: { type: 'dice', count: 3, sides: 3 }, Â children: [] Â }, Â { value: { type: 'operator', symbol: '-' }, children: [] }, Â { Â value: { type: 'numericLiteral', value: 2 }, Â children: [] Â }, Â { value: { type: 'operator', symbol: '*' }, children: [] }, Â { Â value: { type: 'identifier', name: 'min' }, Â children: [] Â }, Â { Â value: { type: 'bracketOpen', symbol: '(', close: ')' }, Â children: [ Â { Â value: { type: 'numericLiteral', value: 3 }, Â children: [] Â }, Â { Â value: { type: 'operator', symbol: '+' }, Â children: [] Â }, Â { Â value: { type: 'dice', count: 2, sides: 2 }, Â children: [] Â }, Â { Â value: { type: 'operator', symbol: '-' }, Â children: [] Â }, Â { Â value: { type: 'numericLiteral', value: 1 }, Â children: [] Â } Â ] Â } Â ] Â } Â ] Â } Â ] Â}
-
@error_bot parse d6d6
-
Error: invalid count:
-
@error_bot you're an invalid count
-
@Gribnit said in The Bot Bikeshed:
@error_bot you're an invalid count
I will not have my bot's nobility called into question.
-
@error I beg their pardon, I was referring to their (still graceful) debility.
-
@error_bot lex luthor
-
@error_bot parse lee
-
{ Â type: 'statement', Â expressions: [ Â { Â value: null, Â children: [ { value: { type: 'identifier', name: 'lee' }, children: [] } ] Â } Â ] Â}
-
@error_bot query user pleegwat
-
uid 893 username PleegWat userslug pleegwat groups garage-modsnominatedpeople-who-are-not-abarkerprogrammers_testersself-serve-mafiatrolleybus-garage-mechanicstrust_level_3trust_level_three_and_a_halfroles
-
@error said in The Bot Bikeshed:
@Gribnit said in The Bot Bikeshed:
@error_bot you're an invalid count
I will not have my bot's nobility called into question.
Your bot is noble enough; it's just too ill to go out in public.
-
@error said in The Bot Bikeshed:
@Gribnit said in The Bot Bikeshed:
@error_bot you're an invalid count
I will not have my bot's nobility called into question.
Nobility? Certainly not. Promiscuity? Definitely!
-
@error_bot parse 2-(1+2d10)+(3*(4d6-10d10÷2)**2+max(2d2-1))*2d2+1
-
{  type: 'statement',  expressions: [  {  type: 'binaryExpression',  operator: { type: 'additionOperator', symbol: '+' },  left: {  type: 'binaryExpression',  operator: { type: 'subtractionOperator', symbol: '-' },  left: { type: 'numericLiteral', value: 2 },  right: {  type: 'binaryExpression',  operator: { type: 'additionOperator', symbol: '+' },  left: {  type: 'bracketExpression',  expression: {  type: 'binaryExpression',  operator: { type: 'additionOperator', symbol: '+' },  left: { type: 'numericLiteral', value: 1 },  right: {  type: 'diceExpression',  sides: 10,  count: 2,  modifiers: []  }  }  },  right: {  type: 'binaryExpression',  operator: { type: 'multiplicationOperator', symbol: '*' },  left: {  type: 'bracketExpression',  expression: {  type: 'binaryExpression',  operator: { type: 'additionOperator', symbol: '+' },  left: {  type: 'binaryExpression',  operator: { type: 'multiplicationOperator', symbol: '*' },  left: { type: 'numericLiteral', value: 3 },  right: {  type: 'binaryExpression',  operator: { type: 'exponentiationOperator', symbol: '**' },  left: {  type: 'bracketExpression',  expression: {  type: 'binaryExpression',  operator: { type: 'subtractionOperator', symbol: '-' },  left: {  type: 'diceExpression',  sides: 6,  count: 4,  modifiers: []  },  right: {  type: 'binaryExpression',  operator: { type: 'divisionOperator', symbol: '÷' },  left: {  type: 'diceExpression',  sides: 10,  count: 10,  modifiers: []  },  right: { type: 'numericLiteral', value: 2 }  }  }  },  right: { type: 'numericLiteral', value: 2 }  }  },  right: {  type: 'callExpression',  functionName: 'max',  arguments: [  {  type: 'binaryExpression',  operator: { type: 'subtractionOperator', symbol: '-' },  left: {  type: 'diceExpression',  sides: 2,  count: 2,  modifiers: []  },  right: { type: 'numericLiteral', value: 1 }  }  ]  }  }  },  right: {  type: 'diceExpression',  sides: 2,  count: 2,  modifiers: []  }  }  }  },  right: { type: 'numericLiteral', value: 1 }  }  ] Â}
-
Parser works... Some limitations (that I still need to fix)...
- no dice modifiers yet (re-roll, keep)
- functions only support a single argument (round, ceil, floor will be fine; min, max are problematic... hmm, and they need to be variadic)
- unary operators aren't a thing.... I think only unary
-
would be applicable, and I'm not sure negative numbers are even useful here - I'm not sure how I can limit this thing so it doesn't expose a DoS vector
-
I think I have a plan to solve each issue listed.
-
Hm, things like "with advantage" are looping structures. It should be able to handle it.
-
I can't solve the halting problem, but I can run the interpreter a maximum number of steps and abort after that.
-
@error Infinite reroll again?