Created
December 2, 2017 00:16
-
-
Save dragon0/8d5ef67759aaede643a5d5997f8bc8bd to your computer and use it in GitHub Desktop.
Command-line dice roller
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import scala.math.{round, ceil, random} | |
//val pattern = """(\d*)d(%|\d+)(([*/])(\d+))?([+-]\d+)?""".r | |
val fullPattern = """(\d*d(%|\d+))(r[hl<>]?\d+)?(k[hl<>]?\d+)?(s[hl<>]?\d+)?([*/]\d+)?([+-]\d+)?""".r | |
val dicePattern = """(\d*)d(%|\d+)""".r | |
val rerollPattern = """r([hl<>]?)(\d+)""".r | |
val keepPattern = """k([hl<>]?)(\d+)""".r | |
val scrapPattern = """s([hl<>]?)(\d+)""".r | |
val multiplierPattern = """([*/])(\d+)""".r | |
val bonusPattern = """([+-]\d+)""".r | |
val dieString = args(0) | |
def roll(sides: Long): Long = round(ceil(random * sides)) | |
def roll(quantity: Int, sides: Long): Seq[Long] = { | |
(for( i <- 1 to quantity) yield roll(sides)) sortWith { _ > _ } | |
} | |
def roll(dieString: String):(Seq[Long], Seq[Long], Seq[Long], Double) = | |
dieString match { | |
case fullPattern(dice, _, reroll, keep, scrap, multiplier, bonus) => { | |
val (quantity, sides) = dice match { | |
case dicePattern("", "%") => (1, 100) | |
case dicePattern("", sides) => (1, Integer.parseInt(sides)) | |
case dicePattern(quantity, "%") => | |
(Integer.parseInt(quantity), 100) | |
case dicePattern(quantity, sides) => | |
(Integer.parseInt(quantity), Integer.parseInt(sides)) | |
} | |
val rolls = roll(quantity, sides) | |
val rerolls = (reroll match { | |
case null => rolls | |
case rerollPattern("", sn) => { | |
val n = Integer.parseInt(sn) | |
val (high, low) = ((rolls dropRight n), (rolls takeRight n)) | |
high ++ roll(low.size, sides) | |
} | |
case rerollPattern("h", sn) => { | |
val n = Integer.parseInt(sn) | |
val (high, low) = rolls splitAt n | |
roll(n, sides) ++ low | |
} | |
case rerollPattern("l", sn) => { | |
val n = Integer.parseInt(sn) | |
val (high, low) = ((rolls dropRight n), (rolls takeRight n)) | |
high ++ roll(low.size, sides) | |
} | |
case rerollPattern(">", sn) => { | |
val n = Integer.parseInt(sn) | |
val (high, low) = rolls partition { _ > n } | |
roll(high.size, sides) ++ low | |
} | |
case rerollPattern("<", sn) => { | |
val n = Integer.parseInt(sn) | |
val (low, high) = rolls partition { _ < n } | |
high ++ roll(low.size, sides) | |
} | |
}) sortWith { _ > _ } | |
val keptRolls = keep match { | |
case null => | |
rerolls | |
case keepPattern("", n) => | |
rerolls take (Integer.parseInt(n)) | |
case keepPattern("h", n) => | |
rerolls take (Integer.parseInt(n)) | |
case keepPattern("l", n) => | |
rerolls takeRight (Integer.parseInt(n)) | |
case keepPattern(">", sn) => | |
val n = Integer.parseInt(sn) | |
rerolls filter { _ > n } | |
case keepPattern("<", sn) => | |
val n = Integer.parseInt(sn) | |
rerolls filter { _ < n } | |
} | |
val finalRolls = scrap match { | |
case null => | |
keptRolls | |
case scrapPattern("", n) => | |
keptRolls dropRight (Integer.parseInt(n)) | |
case scrapPattern("h", n) => | |
keptRolls drop (Integer.parseInt(n)) | |
case scrapPattern("l", n) => | |
keptRolls dropRight (Integer.parseInt(n)) | |
case scrapPattern(">", sn) => | |
val n = Integer.parseInt(sn) | |
keptRolls filterNot { _ > n } | |
case scrapPattern("<", sn) => | |
val n = Integer.parseInt(sn) | |
keptRolls filterNot { _ < n } | |
} | |
val total = if(finalRolls.isEmpty) 0 else { | |
val sum = finalRolls reduce { _ + _ } | |
val multSum = multiplier match { | |
case null => sum | |
case multiplierPattern("*", mult) => | |
sum * Integer.parseInt(mult) | |
case multiplierPattern("/", mult) => | |
sum / Integer.parseInt(mult).toDouble | |
} | |
multSum + (bonus match { | |
case null => 0 | |
case bonusPattern(n) => Integer.parseInt(n) | |
}) | |
} | |
(rolls, rerolls, finalRolls, total) | |
} | |
} | |
require(args.size >= 1, "need 1 argument") | |
for(arg <- args) { | |
println(arg) | |
val (rolls, rerolls, finalRolls, total) = roll(arg) | |
println(rolls mkString ", ") | |
println(rerolls mkString ", ") | |
println(finalRolls mkString ", ") | |
printf(" = %.0f (%f)\n", total, total) | |
println() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment