#!/usr/bin/env ruby class Roll def initialize(res, cuts) @res = res @cuts = cuts end def twist? @res.tally.values.max > 1 end def read_cuts Roll.read(@cuts) end def read Roll.read(@res) end def interpret outcome = case @res.max when 1,2,3 "disaster" when 4,5 "conflict" when 6 "triumph" end "#{outcome}#{" with a twist" if twist?}" end def cut_twist (1...@res.length).map do |i| res = Roll.new(@res[0...-i], @res[-i..-1] + @cuts) next if res.twist? return [i, res] end end def self.roll(number, cuts) res = self.roll_dice(number) new(*self.split(res, cuts)) end def self.read(ary) numword = { 1 => "a", 2 => "two", 3 => "three", 4 => "four", 5 => "five", 6 => "six" } readres = "" ary.tally.each do |val, num| readres += "#{numword[num]} #{val}#{?s if num > 1}, " end readres = readres[0...-2] readres.sub!(/.*\K, /, " and ") readres end def self.roll_dice(num) Array.new(num) { rand(6) + 1 }.sort end def self.split(res, cutn) cuts = cutn > 0 ? res[-cutn..-1] : [] res = res[0...-cutn] if cutn > 0 [res, cuts] end end def prompt(msg) print msg print ?? unless msg[-1] == ?? print ?\s gets.to_i end loop do number = prompt "How many dice" break if number == 0 cuts = prompt "How many cuts" roll = Roll.roll(number, cuts) if cuts > 0 print " After cutting #{roll.read_cuts}, y" else print " Y" end print "ou rolled #{roll.read}. " puts "That's a #{roll.interpret}." if roll.twist? i, cutroll = roll.cut_twist puts " If you chose to cut #{i}#{" more" if cuts > 0}, it would just be a #{cutroll.interpret}." end end