dice: little bit faster this way.

db4
John Benediktsson 2015-07-14 20:35:10 -07:00
parent 94bb834eae
commit 58695edbd6
2 changed files with 25 additions and 16 deletions

View File

@ -1,5 +1,6 @@
USING: math random tools.test ; USING: kernel math tools.test ;
IN: dice IN: dice
{ [ 0 1 [ 4 random + 1 + ] times ] } [ "1d4" parse-roll ] unit-test { [ 1 4 random-roll ] } [ "1d4" roll-quot ] unit-test
{ [ 0 15 [ 45 random + 1 + ] times ] } [ "15d45" parse-roll ] unit-test { [ 1 4 random-roll 3 + ] } [ "1d4+3" roll-quot ] unit-test
{ [ 15 45 random-roll ] } [ "15d45" roll-quot ] unit-test

View File

@ -1,21 +1,29 @@
! Copyright (C) 2010 John Benediktsson ! Copyright (C) 2010 John Benediktsson
! See http://factorcode.org/license.txt for BSD license ! See http://factorcode.org/license.txt for BSD license
USING: fry kernel lexer macros math math.parser peg.ebnf random USING: fry kernel lexer macros math math.parser namespaces
sequences ; random random.private sequences splitting ;
IN: dice IN: dice
EBNF: parse-roll : (random-roll) ( #dice #sides obj -- n )
[ 0 ] 3dip '[ _ _ (random-integer) + 1 + ] times ;
number = ([0-9])+ => [[ string>number ]] : random-roll ( #dice #sides -- n )
dice = "d" number => [[ second '[ _ random ] ]] random-generator get (random-roll) ;
roll = number dice => [[ first2 '[ 0 _ [ @ + 1 + ] times ] ]]
added = "+" number => [[ second '[ _ + ] ]]
total = roll added? => [[ first2 [ append ] when* ]]
error = .* => [[ "unknown dice" throw ]]
rolls = total | error
;EBNF : random-rolls ( length #dice #sides -- seq )
random-generator get '[ _ _ _ (random-roll) ] replicate ;
MACRO: roll ( string -- ) parse-roll ; : parse-roll ( string -- #dice #sides #added )
"d" split1 "+" split1 [ string>number ] tri@ ;
SYNTAX: ROLL: scan-token parse-roll append! ; : roll ( string -- n )
parse-roll [ random-roll ] dip [ + ] when* ;
: roll-quot ( string -- quot: ( -- n ) )
parse-roll [
'[ _ _ random-roll _ + ]
] [
'[ _ _ random-roll ]
] if* ;
SYNTAX: ROLL: scan-token roll-quot append! ;