Move original dice rolling code into its own 'basic' module.

This gives it parity with the other systems: cofd and cthulhu. More
refactoring and a rewrite later as we trend towards more
system-specific implementations.
This commit is contained in:
projectmoon 2020-11-04 20:34:57 +00:00
parent d2642d1fd3
commit 66f9bc6013
10 changed files with 109 additions and 116 deletions

3
src/basic.rs Normal file
View File

@ -0,0 +1,3 @@
pub mod dice;
pub mod parser;
pub mod roll;

85
src/basic/dice.rs Normal file
View File

@ -0,0 +1,85 @@
use std::fmt;
use std::ops::{Deref, DerefMut};
//Old stuff, for regular dice rolling. To be moved elsewhere.
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub struct Dice {
pub(crate) count: u32,
pub(crate) sides: u32,
}
impl fmt::Display for Dice {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}d{}", self.count, self.sides)
}
}
impl Dice {
pub fn new(count: u32, sides: u32) -> Dice {
Dice { count, sides }
}
}
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum Element {
Dice(Dice),
Bonus(u32),
}
impl fmt::Display for Element {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Element::Dice(d) => write!(f, "{}", d),
Element::Bonus(b) => write!(f, "{}", b),
}
}
}
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum SignedElement {
Positive(Element),
Negative(Element),
}
impl fmt::Display for SignedElement {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
SignedElement::Positive(e) => write!(f, "{}", e),
SignedElement::Negative(e) => write!(f, "-{}", e),
}
}
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct ElementExpression(pub Vec<SignedElement>);
impl Deref for ElementExpression {
type Target = Vec<SignedElement>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for ElementExpression {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl fmt::Display for ElementExpression {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut iter = self.0.iter();
if let Some(first) = iter.next() {
write!(f, "{}", first)?;
for roll in iter {
match roll {
SignedElement::Positive(e) => write!(f, " + {}", e)?,
SignedElement::Negative(e) => write!(f, " - {}", e)?,
}
}
}
Ok(())
}
}

View File

@ -1,10 +1,24 @@
use nom::bytes::complete::take_while;
use nom::{ use nom::{
alt, bytes::complete::tag, character::complete::digit1, complete, many0, named, alt, bytes::complete::tag, character::complete::digit1, complete, many0, named,
sequence::tuple, tag, IResult, sequence::tuple, tag, IResult,
}; };
use crate::dice::{Dice, Element, ElementExpression, SignedElement}; use super::dice::*;
use crate::parser::eat_whitespace;
//******************************
//Legacy Code
//******************************
fn is_whitespace(input: char) -> bool {
input == ' ' || input == '\n' || input == '\t' || input == '\r'
}
/// Eat whitespace, returning it
pub fn eat_whitespace(input: &str) -> IResult<&str, &str> {
let (input, whitespace) = take_while(is_whitespace)(input)?;
Ok((input, whitespace))
}
#[derive(Debug, PartialEq, Eq, Clone, Copy)] #[derive(Debug, PartialEq, Eq, Clone, Copy)]
enum Sign { enum Sign {

View File

@ -1,4 +1,4 @@
use crate::dice; use crate::basic::dice;
use rand::prelude::*; use rand::prelude::*;
use std::fmt; use std::fmt;
use std::ops::{Deref, DerefMut}; use std::ops::{Deref, DerefMut};

View File

@ -1,7 +1,6 @@
use crate::context::Context; use crate::context::Context;
use crate::error::{BotError, DiceRollingError}; use crate::error::{BotError, DiceRollingError};
use crate::parser::{Amount, Element, Operator}; use crate::parser::{Amount, Element, Operator};
use crate::roll::Rolled;
use itertools::Itertools; use itertools::Itertools;
use std::convert::TryFrom; use std::convert::TryFrom;
use std::fmt; use std::fmt;
@ -205,12 +204,6 @@ impl DicePoolRoll {
/// Attach a Context to a dice pool. Needed for database access. /// Attach a Context to a dice pool. Needed for database access.
pub struct DicePoolWithContext<'a>(pub &'a DicePool, pub &'a Context<'a>); pub struct DicePoolWithContext<'a>(pub &'a DicePool, pub &'a Context<'a>);
impl Rolled for DicePoolRoll {
fn rolled_value(&self) -> i32 {
self.successes()
}
}
impl fmt::Display for DicePoolRoll { impl fmt::Display for DicePoolRoll {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let successes = self.successes(); let successes = self.successes();

View File

@ -1,7 +1,7 @@
use super::{Command, Execution}; use super::{Command, Execution};
use crate::basic::dice::ElementExpression;
use crate::basic::roll::Roll;
use crate::context::Context; use crate::context::Context;
use crate::dice::ElementExpression;
use crate::roll::Roll;
use async_trait::async_trait; use async_trait::async_trait;
pub struct RollCommand(pub ElementExpression); pub struct RollCommand(pub ElementExpression);

View File

@ -1,3 +1,4 @@
use crate::basic::parser::parse_element_expression;
use crate::cofd::parser::{create_chance_die, parse_dice_pool}; use crate::cofd::parser::{create_chance_die, parse_dice_pool};
use crate::commands::{ use crate::commands::{
basic_rolling::RollCommand, basic_rolling::RollCommand,
@ -10,7 +11,6 @@ use crate::commands::{
Command, Command,
}; };
use crate::cthulhu::parser::{parse_advancement_roll, parse_regular_roll}; use crate::cthulhu::parser::{parse_advancement_roll, parse_regular_roll};
use crate::dice::parser::parse_element_expression;
use crate::error::BotError; use crate::error::BotError;
use crate::help::parse_help_topic; use crate::help::parse_help_topic;
use crate::variables::parse_set_variable; use crate::variables::parse_set_variable;

View File

@ -1,5 +1,3 @@
pub mod parser;
use crate::context::Context; use crate::context::Context;
use crate::db::variables::UserAndRoom; use crate::db::variables::UserAndRoom;
use crate::error::BotError; use crate::error::BotError;
@ -7,8 +5,6 @@ use crate::error::DiceRollingError;
use crate::parser::Amount; use crate::parser::Amount;
use crate::parser::Element as NewElement; use crate::parser::Element as NewElement;
use futures::stream::{self, StreamExt, TryStreamExt}; use futures::stream::{self, StreamExt, TryStreamExt};
use std::fmt;
use std::ops::{Deref, DerefMut};
//New hotness //New hotness
pub async fn calculate_dice_amount(amounts: &[Amount], ctx: &Context<'_>) -> Result<i32, BotError> { pub async fn calculate_dice_amount(amounts: &[Amount], ctx: &Context<'_>) -> Result<i32, BotError> {
@ -33,86 +29,3 @@ pub async fn calculate_dice_amount(amounts: &[Amount], ctx: &Context<'_>) -> Res
dice_amount dice_amount
} }
//Old stuff, for regular dice rolling. To be moved elsewhere.
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub struct Dice {
pub(crate) count: u32,
pub(crate) sides: u32,
}
impl fmt::Display for Dice {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}d{}", self.count, self.sides)
}
}
impl Dice {
fn new(count: u32, sides: u32) -> Dice {
Dice { count, sides }
}
}
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum Element {
Dice(Dice),
Bonus(u32),
}
impl fmt::Display for Element {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Element::Dice(d) => write!(f, "{}", d),
Element::Bonus(b) => write!(f, "{}", b),
}
}
}
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum SignedElement {
Positive(Element),
Negative(Element),
}
impl fmt::Display for SignedElement {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
SignedElement::Positive(e) => write!(f, "{}", e),
SignedElement::Negative(e) => write!(f, "-{}", e),
}
}
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct ElementExpression(Vec<SignedElement>);
impl Deref for ElementExpression {
type Target = Vec<SignedElement>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for ElementExpression {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl fmt::Display for ElementExpression {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut iter = self.0.iter();
if let Some(first) = iter.next() {
write!(f, "{}", first)?;
for roll in iter {
match roll {
SignedElement::Positive(e) => write!(f, " + {}", e)?,
SignedElement::Negative(e) => write!(f, " - {}", e)?,
}
}
}
Ok(())
}
}

View File

@ -1,3 +1,4 @@
pub mod basic;
pub mod bot; pub mod bot;
pub mod cofd; pub mod cofd;
pub mod commands; pub mod commands;
@ -9,6 +10,5 @@ pub mod dice;
pub mod error; pub mod error;
mod help; mod help;
mod parser; mod parser;
pub mod roll;
pub mod state; pub mod state;
pub mod variables; pub mod variables;

View File

@ -1,6 +1,5 @@
use combine::parser::char::{digit, letter, spaces}; use combine::parser::char::{digit, letter, spaces};
use combine::{many, many1, one_of, Parser}; use combine::{many, many1, one_of, Parser};
use nom::{bytes::complete::take_while, IResult};
use thiserror::Error; use thiserror::Error;
//****************************** //******************************
@ -122,20 +121,6 @@ pub fn parse_amounts(input: &str) -> Result<Vec<Amount>, DiceParsingError> {
} }
} }
//******************************
//Legacy Code
//******************************
fn is_whitespace(input: char) -> bool {
input == ' ' || input == '\n' || input == '\t' || input == '\r'
}
/// Eat whitespace, returning it
pub fn eat_whitespace(input: &str) -> IResult<&str, &str> {
let (input, whitespace) = take_while(is_whitespace)(input)?;
Ok((input, whitespace))
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {