#dice-notation #dice #dice-roll #expression #expression-parser #rpg #numbers

bin+lib dicexp

一个用于解析(和掷)RPG风格骰子表示法的Dice Expression Interpreter程序和库(例如“2d8+5”)

4个稳定版本

1.1.1 2023年10月9日
1.0.1 2023年10月9日

#314 in 文本处理


twas中使用

MPL-2.0许可证

31KB
544

DiceXp - RPG骰子表达式解释器

DiceXp是一个用于解析和掷RPG风格骰子表示法的库和命令行界面(CLI)应用程序(例如“2d8+5”)。

此包包含两个组件:CLI应用程序和库模块。CLI应用程序可以使用cargo install dicexp --features app安装,然后在终端中用于掷骰子。库提供了一个DiceBag结构,您可以使用来自rand crate的随机数生成器(RNG)初始化它,然后在每个要评估的骰子表达式中调用DiceBag.eval(...)

使用标准RPG骰子表示法掷骰子

DiceXp支持标准RPG骰子表示法,例如“1d20+3”或“3d6”,其中'd'前面的数字是要掷的骰子数量,'d'后面的数字是每颗骰子的面数。您可以使用多种不同类型的骰子,例如“1d4+1d6+1d8-1d12”。

算术(+、-、*、/)

DiceXp支持基本算术,具体为加法(+)、减法(-)、乘法(*或x)和除法(/)。请注意,除法是整数除法(除非计算平均值,见下文),这意味着它始终向下取整到整数。 DiceXp还支持嵌套括号。因此,以下所有内容都是有效的dicexp表达式

  • "1d4*1d20"
  • "-3*(1+2)"
  • "(1d10+5)x10+(1d20-10)"
  • "4d6/10-5"
  • "4(9(10/2-6-3x8+1x4/2)x8/2x5+4)x5+4(7+7-3x8)x3-10x(10)-1"

平均值、最小值和最大值

DiceXp评估骰子表达式时,它还会计算掷骰子的统计平均结果,以及可能的最大和最小值(即如果所有骰子都掷出最大值或都掷出1的情况)。

DiceXp的替代方案

DiceXp 是为标准骰子记号设计的,旨在处理相对复杂的数学骰子公式。它不支持所有桌面角色扮演游戏系统或骰子滚动机制(例如掷两个骰子并保留较大的一个)。DiceXp 的最佳替代方案是 ndm 包,它更好地支持桌面角色扮演游戏。以下是与 ndm 的功能对比

功能 DiceXp ndm
命令行应用
掷标准骰子
加法和减法
乘法 ~
除法
嵌套括号
爆炸骰子
保留 N 个最高/最低
平均值、最小值和最大值

*~ ndm 只能将骰子乘以常数,不能乘以其他骰子*

DiceXp 命令行应用

dicexp 命令行应用评估通过命令行参数提供的骰子表达式。例如

$ dicexp 1d6x10+1d10
>>> 1d6x10+1d10 => 64

可以一次性提供多个表达式

$ dicexp 1d6 1d6 1d6 1d6
>>> 1d6 => 2
>>> 1d6 => 5
>>> 1d6 => 3
>>> 1d6 => 1

您还可以使用 -r/--range 选项打印骰子表达式的可能值范围,以及使用 -a/--average 选项打印平均值

$ dicexp -a -r 3d6
>>> 3d6 => 12 (3-18, 10.5 ave.)

安装

要安装 dicexp 应用,只需运行以下命令

cargo install dicexp --features app

用法

dicexp[选项] [DICE_EXPRESSIONS]...

选项

  • -a, --average: 显示每个骰子表达式的平均结果
  • -r, --range: 显示每个骰子表达式的最小和最大可能结果
  • -q, --quiet: 仅显示掷骰结果,不显示其他内容(与 -a/--average-r/--range 不兼容)
  • -s, --seed : 随机数生成器的可选种子
  • -h, --help: 打印帮助信息
  • -V, --version: 打印版本

DiceXp Rust 库

DiceXp 库模块提供了三个结构体:DiceBagDiceRollSyntaxError。它还提供了两个实用函数来简化实例化新的 RNG:simple_rng(u64) -> StdRngnew_simple_rng() -> StdRng

结构体 DiceBag

大多数情况下,您只需要使用 DiceBag 结构体。通过 DiceBag::new(Rng) 使用您选择的 RNG 实例化 DiceBag,然后即可使用。要评估一个骰子表达式,使用 eval(&str) 方法,或者仅评估最小、最大或平均值,使用相应的 ...(&str) 方法。

结构体 DiceRoll

此结构体由 DiceBag.eval(&str) 返回,包含投掷的总和,以及表达式的最小值、最大值和平均值。

结构体 SyntaxError

此错误类型是在 Err() 中返回的,每当 DiceBag 方法无法评估骰子表达式时。

示例

从用户输入中投掷骰子

此示例提示用户输入一个骰子表达式,然后评估它。如果投掷总和大于预期平均值,则打印 "That's a good roll!",否则打印 "That's not a good roll :("。

fn main() {
	use dicexp::{DiceBag, new_simple_rng};
	use std::io;
	let mut dice_bag = DiceBag::new(new_simple_rng());
	println!("What would you like to roll? ");
	let mut input = String::new();
	io::stdin()
		.read_line(&mut input)
		.expect("failed to read from stdin");
	let dice_roll = dice_bag.eval(input.as_str()).expect("invalid dice expression");
	println!("You rolled a {}", dice_roll);
	if dice_roll.total >= dice_roll.average as i64 {
		println!("That's a good roll!");
	} else {
		println!("That's not a good roll :(");
	}
}

计算各种 D&D 武器的平均伤害

此示例比较了桌面角色扮演游戏《龙与地下城》(简称 D&D)中各种武器的平均伤害。

fn main() {
	use dicexp::{DiceBag, new_simple_rng};
	let mut dice_bag = DiceBag::new(new_simple_rng());
	let armory = vec![
		("great axe", "1d12"),
		("great sword", "2d6"),
		("heavy crossbow", "1d10+2"),
		("firebolt", "1d10"),
		("magic missile", "3d4+3")
	];
	println!("Average Damage:");
	for (name, dmg) in armory {
		println!("{}\t{}", dice_bag.eval_ave(dmg).unwrap(), name)
	}
}

依赖项

~0.4–10MB
~90K SLoC