diff --git a/Cargo.lock b/Cargo.lock index 59e6cd1..91a8c2f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,12 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "bytemuck" +version = "1.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b37c88a63ffd85d15b406896cc343916d7cf57838a847b3a6f2ca5d39a5695a" + [[package]] name = "byteorder" version = "1.5.0" @@ -14,6 +20,32 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "colored" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbf2150cce219b664a8a70df7a1f933836724b503f8a413af9365b4dcc4d90b8" +dependencies = [ + "lazy_static", + "windows-sys", +] + +[[package]] +name = "drawille" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e64e461c3f1e69d99372620640b3fd5f0309eeda2e26e4af69f6760c0e1df845" +dependencies = [ + "colored", + "fnv", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + [[package]] name = "getrandom" version = "0.2.15" @@ -25,6 +57,12 @@ dependencies = [ "wasi", ] +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + [[package]] name = "libc" version = "0.2.164" @@ -110,12 +148,22 @@ dependencies = [ "getrandom", ] +[[package]] +name = "rgb" +version = "0.8.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57397d16646700483b67d2dd6511d79318f9d057fdbd21a4066aeac8b41d310a" +dependencies = [ + "bytemuck", +] + [[package]] name = "rust-roller" version = "0.1.0" dependencies = [ "nom", "rand", + "textplots", ] [[package]] @@ -129,6 +177,16 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "textplots" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f59b64803118dbff62f92842b3154a2c802dfd8e18660132bbcbfb141c637ae3" +dependencies = [ + "drawille", + "rgb", +] + [[package]] name = "unicode-ident" version = "1.0.14" @@ -141,6 +199,72 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + [[package]] name = "zerocopy" version = "0.7.35" diff --git a/Cargo.toml b/Cargo.toml index 2d6ea56..2fd91d8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,3 +6,4 @@ edition = "2021" [dependencies] nom = "7.1.3" rand = "0.8.5" +textplots = "0.8.6" diff --git a/src/lib.rs b/src/lib.rs index 23f054f..94a96ca 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,4 @@ -use nom::{branch::alt, character::complete, IResult}; +use nom::{branch::alt, character::complete::{self, multispace0}, combinator::opt, IResult}; use rand::Rng; #[derive(Debug)] @@ -48,6 +48,10 @@ impl Buckets { pub fn labels(&self) -> &[i64] { &self._offsets[..] } + + pub fn max(&self) -> u64 { + *self._buckets.iter().max().unwrap() + } } pub struct Roller { @@ -71,6 +75,10 @@ impl Roller { return Err(nom::Err::Incomplete(nom::Needed::new(S + 1))); } + // Ignore trailing whitespace + let (e, _) = multispace0(expr)?; + expr = e; + // Get the next oper if e.len() > 0 { let (e, _op) = oper(expr)?; @@ -192,11 +200,17 @@ impl Roll { fn term(e: &str) -> IResult<&str, Term> { + // Ignore whitespace + let (e, _) = multispace0(e)?; alt((roll, cnst))(e) } -fn roll(e: &str) -> IResult<&str, Term> { - let (e, reps) = complete::u64(e)?; +fn roll(mut e: &str) -> IResult<&str, Term> { + let mut reps = 1; + if let (_e, Some(_reps)) = opt(complete::u64)(e)? { + e = _e; + reps = _reps; + } let (e, _) = complete::char('d')(e)?; let (e, dice) = complete::u64(e)?; Ok((e, Term::Roll(Roll{reps, dice}))) @@ -208,6 +222,8 @@ fn cnst(e: &str) -> IResult<&str, Term> { } fn oper(e: &str) -> IResult<&str, Oper> { + // Ignore whitespace + let (e, _) = multispace0(e)?; alt((add, sub))(e) } diff --git a/src/main.rs b/src/main.rs index e7a11a9..295f124 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,45 @@ +use rand::thread_rng; +use std::io::{self, BufRead, Write}; +use rust_roller::{Buckets, Roller}; +use textplots::{Chart, Plot, Shape}; + fn main() { - println!("Hello, world!"); + let stdin = io::stdin(); + print!("> "); + io::stdout().flush().unwrap(); + for line in stdin.lock().lines() { + let line = line.unwrap(); + let roller = match Roller::<1024>::parse(&line) { + Ok(r) => r, + Err(e) => { + println!("bad input; err: {}", e); + continue; + }, + }; + let mut bins = Buckets::<180>::new(&roller); + + for _ in 0..5000 { + bins.insert(roller.roll(&mut thread_rng())); + } + + let points: Vec<(f32, f32)> = bins + .labels() + .iter() + .zip(bins.buckets()) + .map(|(a, b)| (*a as f32, *b as f32)) + .collect(); + + Chart::new_with_y_range( + 180, + 100 as u32, + roller.min() as f32, + roller.max() as f32, + 0.0, + bins.max() as f32, + ) + .lineplot(&Shape::Bars(&points)) + .display(); + print!("> "); + io::stdout().flush().unwrap(); + } }