Skip to content

Commit

Permalink
feat: 实现d优势语法,实现上下界配置,改进计算过程输出
Browse files Browse the repository at this point in the history
  • Loading branch information
fy0 committed Jul 2, 2024
1 parent 0e5e379 commit 36f357b
Show file tree
Hide file tree
Showing 10 changed files with 627 additions and 462 deletions.
35 changes: 15 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,22 @@
Simple script language for TRPG dice engine.

特性:
- 支持整数、浮点数、字符串、数组、字典、函数,常见算符以及if和while逻辑语句
- 支持形如d20等的trpg用骰点语法
- 全类型可序列化(包括函数在内)
- 对模板字符串语法做大量优化,可胜任模板引擎
- 易于使用,方便扩展
- 稳定可靠,极高的测试覆盖率
- 免费,并可商用
- 支持JavaScript
- 海豹TRPG骰点核心的第二代解释器
- 免费并可商用
- 可编译到JavaScript

测试页面:

https://sealdice.github.io/dicescript/

这个项目是海豹核心的骰点解释器的完全重构。
从第一次实现中吸取了很多经验和教训,并尝试做得更好。

## 如何使用

[DiceScript指南](./GUIDE.md)
Expand All @@ -28,20 +34,9 @@ https://sealdice.github.io/dicescript/

## 设计原则

先随便写一些想到的,然后再细化

这是未来SealDice项目的一部分,一次从零重构。

目前SealDice使用一个叫做RollVM的解释器来完成脚本语言的解析。

DiceScript将更好的实现骰点功能,语法规范化的同时,具有更好的接口设计和自定义能力。


几个设计原则:

* 从主流语言和跑团软件中借鉴语法,如Golang/Python/JS/Ruby/Fvtt/BCDice,不随意发明
* 兼容中国大陆地区跑团指令的一般习惯
* 要具有较强的配置和扩展能力,符合trpg场景额需求
* 从主流语言和跑团软件中借鉴语法,如Golang/Python/JS/Fvtt/BCDice,不随意发明
* 符合国内跑团指令的一般习惯
* 要具有较强的配置和扩展能力,符合trpg场景的需求
* 一定限度内容忍全角符号
* 兼容gopherjs
* 良好的错误提示文本
Expand All @@ -55,7 +50,7 @@ DiceScript将更好的实现骰点功能,语法规范化的同时,具有更
- [x] 二元算符 +-*/% >,>=,==,!=,<,<=,&,|,&&,||
- [x] 三元算符 ? :
- [x] 空值合并算符 ??
- [x] 骰点运算 流行: d20, 3d20, (4+5)d(20), 2d20k1, 2d20q1
- [x] 骰点运算 - 流行语法: d20, 3d20, (4+5)d(20), 2d20k1, 2d20q1
- [x] 骰点运算 - fvtt语法: 2d20kl, 2d20kh, 2d20dl, 2d20dh, d20min10, d20max10
- [x] 骰点运算 - CoC / Fate / WoD / Double Cross
- [ ] 骰点运算 - 自定义算符
Expand All @@ -75,15 +70,15 @@ DiceScript将更好的实现骰点功能,语法规范化的同时,具有更
- [x] 报错信息优化
- [x] 线程安全
- [x] 变量作用域
- [ ] 测试覆盖率 85% / 90%
- [ ] 测试覆盖率 86% / 90%

## 更新记录

[更新记录](./CHANGELOG.md)

## TODO

* ~~d2d(4d4d5)d6 计算过程问题~~
* 骰点运算 - 自定义算符

## 开发

Expand Down
5 changes: 3 additions & 2 deletions parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,9 @@ type BufferSpan struct {
End IntType
Ret *VMValue
Text string
// 来源标记
Tag string

Expr string // 如果存在Expr,用来替代等号左边的内容,不存在的话用Begin和End从原文提取
Tag string // 来源标记
}

func (e *ParserData) LoopBegin() {
Expand Down
11 changes: 6 additions & 5 deletions roll.peg
Original file line number Diff line number Diff line change
Expand Up @@ -243,22 +243,23 @@ _diceMod <- ("kl" / [qQ]) nos { c.data.AddOp(typeDiceSetKeepLowNum); } // 这
_diceModType2 <- "min" nos { c.data.AddOp(typeDiceSetMin) }
/ "max" nos { c.data.AddOp(typeDiceSetMax) }

_dicePearMod <- "优势" { c.data.PushIntNumber("2"); c.data.AddOp(typeDiceSetTimes); c.data.PushIntNumber("1"); c.data.AddOp(typeDiceSetKeepHighNum); }
/ "劣势" { c.data.PushIntNumber("2"); c.data.AddOp(typeDiceSetTimes); c.data.PushIntNumber("1"); c.data.AddOp(typeDiceSetKeepLowNum); }
_dicePearMod <- ("优势"/"優勢") { c.data.PushIntNumber("2"); c.data.AddOp(typeDiceSetTimes); c.data.PushIntNumber("1"); c.data.AddOp(typeDiceSetKeepHighNum); }
/ ("劣势"/"劣勢") { c.data.PushIntNumber("2"); c.data.AddOp(typeDiceSetTimes); c.data.PushIntNumber("1"); c.data.AddOp(typeDiceSetKeepLowNum); }

// 3d20, 3d20d2, 2d20优势
_diceType1 <- nos [dD] nos
// d20
_diceType2 <- [dD] nos
// 3d
_diceType3 <- nos [dD]
// d
_diceType4 <- [dD] !xidStart
// d / d优势 / d劣势
_diceType4 <- [dD] ("优势" / "優勢" / "劣势" / "劣勢" / !xidStart)

// XdY/dY/Xd 中的 dy + 后缀部分,跟上面 _diceTypeX 一一对应
_diceExpr1 <- [dD] { c.data.AddOp(typeDiceInit); c.data.AddOp(typeDiceSetTimes); } nos _diceMod? _diceModType2?
_diceExpr2 <- [dD] { c.data.AddOp(typeDiceInit); } nos (_dicePearMod / _diceMod)? _diceModType2? // 注: 这一条是 dY 而不是 xdY
_diceExpr3 <- [dD] { c.data.AddOp(typeDiceInit); c.data.AddOp(typeDiceSetTimes); } _diceMod? _diceModType2?
_diceExpr4 <- [dD] { c.data.AddOp(typeDiceInit); c.data.AddOp(typeDiceSetTimes); } (_dicePearMod / _diceMod)? _diceModType2?

// 多重式子 d4d6d8
_diceExprX <- &_diceType2 detailStart _diceExpr1 detailEnd { c.data.AddOp(typeDice) }
Expand All @@ -283,7 +284,7 @@ _fateDiceType <- [fF] !xidContinue
exprDice <- &_diceType1 detailStart nos _diceExpr1 detailEnd { c.data.AddOp(typeDice); } _diceExprX*
/ &_diceType2 detailStart _diceExpr2 detailEnd { c.data.AddOp(typeDice) } _diceExprX*
/ &{return !c.data.Config.DisableNDice} &_diceType3 detailStart nos _diceExpr3 detailEnd { c.data.AddOp(typePushDefaultExpr); c.data.AddOp(typeDice) } _diceExprX*
/ &{return !c.data.Config.DisableNDice} &_diceType4 detailStart { c.data.PushIntNumber("1") } _diceExpr3 detailEnd { c.data.AddOp(typePushDefaultExpr); c.data.AddOp(typeDice) } _diceExprX*
/ &{return !c.data.Config.DisableNDice} &_diceType4 detailStart { c.data.PushIntNumber("1") } _diceExpr4 detailEnd { c.data.AddOp(typePushDefaultExpr); c.data.AddOp(typeDice) } _diceExprX*
/ &{return c.data.Config.EnableDiceCoC} &_cocDiceType detailStart (_diceCocBonus / _diceCocPenalty)
/ &{return c.data.Config.EnableDiceWoD} &_wodDiceType detailStart { c.data.AddOp(typeWodSetInit) } (nos { c.data.AddOp(typeWodSetPool) } _wodMain / _wodMain !xidContinue) detailEnd { c.data.AddOp(typeDiceWod) }
/ &{return c.data.Config.EnableDiceDoubleCross} &_dcDiceType detailStart { c.data.AddOp(typeDCSetInit) } nos { c.data.AddOp(typeDCSetPool) } [cC] nos (([mM] nos { c.data.AddOp(typeDCSetPoints) }) )* detailEnd { c.data.AddOp(typeDiceDC) }
Expand Down
Loading

0 comments on commit 36f357b

Please sign in to comment.