Forums
New posts
Search forums
Members
Current visitors
Log in
Register
What's new
Search
Search
Search titles only
By:
New posts
Search forums
Menu
Log in
Register
Install the app
Install
Forums
Archive
Archive
Ruby
[QUIZ] Dice Roller (#61)
JavaScript is disabled. For a better experience, please enable JavaScript in your browser before proceeding.
Reply to thread
Message
[QUOTE="Morus Walter, post: 4500845"] Another solution: #! /usr/bin/ruby # change this to some fixed value for reproducable results def random(i) # i # FIXME: check rand's usabilty for throwing dices... rand(i)+1 end class DiceExpr def initialize(rolls, sides) @rolls, @sides = rolls, sides end def to_i sides = @sides.to_i (1..@rolls.to_i).inject(0) { | sum, i | sum += random(sides) } end def to_s "(#{@rolls}d#{@sides})" end end class Expr def initialize(lhs, rhs, op) @lhs, @rhs, @op = lhs, rhs, op end def to_i @lhs.to_i.send(@op, @rhs.to_i) end def to_s "(#{@lhs}#{@op}#{@rhs})" end end class Dice def initialize(expr) @expr_org = @expr_str = expr next_token @expr = addend() if @token raise "parser error: tokens left: >#{@fulltoken}#{@expr_str}<" end end # "lexer" @@regex = Regexp.compile(/^\s*([()+\-*\/]|[1-9][0-9]*|d%|d)\s*/) def next_token @prev_token = @token return @token = nil if @expr_str.empty? match = @@regex.match(@expr_str) if !match raise "parser error: cannot tokenize input #{@expr_str}" end @expr_str = @expr_str[match.to_s.length, @expr_str.length] @fulltoken = match.to_s # for "tokens left" error message only... @token = match[1] end # "parser" # bit lengthy but basically straightforward def number() # number or parenthesized expression raise "unexpeced >)<" if ( @token == ')' ) if ( @token == '(' ) next_token val = addend raise "parser error: parenthesis error, expected ) got #{@token}" if @token != ')' next_token return val end raise "parse error: number expected, got #{@token}" if @token !~ /^[0-9]*$/ next_token @prev_token end def dice() if ( @token == 'd' ) rolls = 1 else rolls = number() end while ( @token == 'd' || @token == 'd%' ) if @token == 'd%' rolls = DiceExpr.new(rolls, 100) next_token else next_token sides = number() raise "parser error: missing sides expression" if !sides rolls = DiceExpr.new(rolls, sides) end end rolls end def factor() lhs = dice() while ( @token == '*' || @token == '/' ) op = @token next_token rhs = dice() raise "parser error: missing factor" if !rhs lhs = Expr.new(lhs, rhs, op) end lhs end def addend() lhs = factor() while ( @token == '+' || @token == '-' ) op = @token next_token rhs = factor() raise "parser error: missing addend" if !rhs lhs = Expr.new(lhs, rhs, op) end lhs end def to_s "#{@expr_org} -> #{@expr.to_s}" end def roll @expr.to_i end end d = Dice.new(ARGV[0]) #puts d.to_s (ARGV[1] || 1).to_i.times { print "#{d.roll} " } puts [/QUOTE]
Verification
Post reply
Forums
Archive
Archive
Ruby
[QUIZ] Dice Roller (#61)
Top