11 个版本

0.9.10 2023年7月28日
0.9.9 2021年5月3日
0.9.8 2021年4月12日
0.9.1 2021年3月31日

#57 in 游戏开发

46 次月下载

MIT/Apache

69KB
1K SLoC

关于

解析骰子记法并评估骰子组合的代数运算。

此模块提供了 DiceRollSet 结构体,它们实现了 FromStr,用于从字符串转换。它还提供了与解析骰子相关字符串直接相关的错误类型。

示例

骰子示例

掷骰子

从字符串字面量创建 Dice

use ndm::Dice;

let d6 = "1d6".parse::<Dice>().unwrap();

您可以直接创建它们

use ndm::Dice;

let d4 = Dice::new(1, 4);

爆炸骰子

创建爆炸骰子(当掷出最高点数时再次掷骰子)

use ndm::Dice;

let exploding_d20 = "1d20!".parse::<Dice>().unwrap();
let exploding_d6 = Dice::new_exploding(1, 6, 6);

爆炸骰子可以在大于1的任何数字上爆炸

use ndm::Dice;

let exploding_d13 = "1d13!2".parse::<Dice>().unwrap();

更复杂的示例

一次掷多个 Dice

use ndm::Dice;

let dice = Dice::new(3, 8);
let dice = Dice::new_exploding(2, 4, 4);

保留高或低掷骰结果

保留三个最高的骰子

use ndm::Dice;

let wis = Dice::new_keep_n(4, 6, 3);
let dex: Dice = "4d6/H3".parse().unwrap();

或者最低掷骰结果

use ndm::Dice;

let disadvantage = Dice::new_keep_n(2, 20, -1);
let minimum: Dice = "4d7/L1".parse().unwrap();

(字符串解析不区分大小写。)

保留爆炸骰子

use ndm::Dice;

let dice = Dice::new_extended(4, 7, 5, 3);
// or
let dice = "4d7/H3!5".parse::<Dice>().unwrap();

格式化骰子

Dice 可以使用正常的 {} 操作符进行格式化

use ndm::Dice;

println!("{}", Dice::new(2, 10).unwrap());

解析错误

无法解析的字符串会导致 DiceParseError。字符串解析比构造函数更为严格,构造函数目前不会失败,而是忽略无效参数。

组合

如多个尺寸的骰子组合和骰子的数学运算等骰子集合由 RollSet 表示。

RollSet 只能通过解析字符串切片创建

use ndm::RollSet;

let roll_set: RollSet = "3d6".parse().unwrap();

RollSet 可以包含任何有效的 Dice 和整数的组合,由 +- (或 -) 连接。这些组合也可以乘以浮点数,使用 * (或 xX 或 ×)。

use ndm::RollSet;

let roll_set: RollSet = "1d20+4".parse().unwrap();
let empowered = "4d6 * 1.5".parse::<RollSet>().unwrap();
let sneak = "3d8 + 2d6".parse::<RollSet>().unwrap();

可以包含额外文本

use ndm::RollSet;

let roll_set = "2d8 slashing + 3d6 fire".parse::<RollSet>().unwrap();

可以使用 # 标记结束注释,这将防止进一步解析

use ndm::RollSet;

// Only the 4d6 will be parsed, the 8d6 is just a comment.
let roll_set: RollSet = "4d6 # 8d6 on a critical".parse().unwrap();

RollSet 也可以使用 {} 进行格式化,如果有的话,总计将出现在行尾注释之前。

use ndm::RollSet;

// Prints something like: `3d6 [ 2, 4, 5: 11] slashing + 4 = 15`
println!("{}", "3d6 slashing + 4".parse::<RollSet>().unwrap());
// Prints something like `3d6 [ 3, 5, 6: 14] + 4 = 18 # slashing`
println!("{}", "3d6+4 # slashing".parse::<RollSet>().unwrap());

解析错误

错误通过 RollParseError 返回。一般情况下,RollSet 将非 Dice、运算符或数字的内容视为注释,但如果字符串中没有任何掷骰子,则会失败。一些运算符的组合也是无效的:Dice 不能与其他 Dice 相乘,文本不能加到数字上,等等。

更多信息

骰子数学从左到右进行,不考虑运算符。例如,4d6 + 12 * 1.5 的范围是从 24 ((4 + 12) * 1.5) 到 54 ((24 + 12) * 1.5),而不是从 22 到 42。

可以与整数、掷骰子的结果和先前操作的结果一起进行加法和减法。可以乘以上述所有内容,但右侧必须是一个数字(整数或浮点数)。此外,浮点数运算的结果会被截断:1d6 * 4.9 的范围是从 4 到 29,而不是从 4.9 到 29.4。

爆炸骰子只要掷出的点数不低于“熔断点”(默认为骰子的最高点数,但可能低至 2),就会重新掷骰子。

可以直接构建 Dice,或者构建复杂的 RollSet 表达式。

此库解析的骰子符号为

[数量] d<面数>[/<H|L><保留>][![熔断点]]

  • 数量 是要掷的骰子数量,是可选的,默认为 1
  • 面数 是骰子的面数,是必需的
    • 如果是数字,则必须是非负数
    • fF 可以用来表示 Fudge/Fate 骰子
  • 可选地,跟在 / 后面
    • H(或 h)或 L(或 l)和
    • 一个小于或等于掷骰子数量的正数
  • 可选地,跟在 ! 后面,可以跟一个整数作为熔断点
    • 如果提供了熔断点,则它必须至少为 2
    • 否则,默认为骰子可能掷出的最高点数

可以使用 + 进行骰子的加法,使用 -(或 −)进行减法,或使用 *(或 xX 或 ×)进行乘法。其他文本被视为注释。

Dice 可以通过加法或减法与其他 Dice 结合。您还可以添加或减去整数,并将结果乘以浮点数。(目前不支持直接除法,但您可以通过乘以倒数来实现。)

许可证

根据您的选择,许可方式为 Apache License,Version 2.0 或 MIT 许可证。

贡献

除非您明确声明,否则您提交的任何贡献,按照 Apache License,Version 2.0 的定义,应作为上述双重许可,而不附加任何额外条款或条件。

依赖关系

~3–5MB
~90K SLoC