Diceomatic:一个用于创建儿童骰子游戏的领域特定语言

本文介绍了作者为满足孩子对骰子模拟游戏的需求而开发的Python库diceomatic。它允许用户通过声明变量、定义方程形式和约束条件,来生成高度可定制、无限数量的算术问题,用于驱动各种骰子游戏。

diceomatic: 一个用于制作儿童骰子游戏的DSL

我的五岁孩子非常喜欢足球。真的,非常,坐不住,也不让任何人坐下来的那种喜欢。我和妻子利用每一分钟空闲时间来敷衍地射门;假装痛苦地看着大胆的反击让我们以0-23落后;并回答诸如哈里·凯恩出生在哪家医院之类的测验问题。 为了能让我们喘口气和洗个澡,我发明了一个名为“骰子足球”的游戏。在骰子足球中,你掷两个6面骰子,将点数相加,然后查阅一个表格看接下来会发生什么。比赛结束后,你将结果输入锦标赛追踪表。然后开始下一场比赛。希望你能至少玩上一个小时而不感到无聊。骰子足球是一个单人游戏,这意味着不需要有输赢,爸爸妈妈可以暂时去做点别的事情。

(这是骰子足球的可打印规则表,以及锦标赛追踪表。) 骰子足球出人意料地成为了一个令人着迷的热门游戏。只要我们给儿子提供足够的笔和练习本,我们想洗多久的澡都行。骰子足球也是进入基于骰子的模拟游戏世界的一个入口,在接下来的几周里,我几乎跟不上儿子对新游戏的渴望。他最喜欢的是“骰子美国联邦选举”,你通过掷骰子来决定哪个党派赢得每个州,完成后借爸爸的手机来统计选举人团票数。

随着新游戏不断涌现,我用6面骰子生成有趣算式的方式开始枯竭。我买了一些20面骰子,这些“大家伙”让游戏又保持了一两周的新鲜感。但我开始对任何简单多面体骰子的局限性感到不满。我开始变得雄心勃勃。

我想制作使用具有任意可定制结构和难度的算式的游戏。例如,我不想再局限于两个6面骰子的简单 A+B = ?? (其中 1<=A<=6 且 1<=B<=6)形式,而是想要像这样的算式:

AB + CD = ?? (例如:42 + 143 = ??) 并且加法部分要跨越10的边界 同时 AB < 20 且 CD < 50 并且所有变量都在2到100之间

如果答案是偶数,切尔西队就得分;如果是奇数,利物浦队得分。诸如此类。 我无法用骰子构建这些算式,当然也不想手动构建。我需要一种方法来生成无限流的、高度特定的问题。 所以我写了一个:diceomatic。

diceomatic

diceomatic 是一个Python库,用于构建高度可定制的、无限的骰子游戏。

例如,要使用上面列出的示例约束生成一个问题流,你可以这样写:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
from diceomatic import *

# 声明变量
a, b, c, d, e = variables(["a", "b", "c", "d", "e"])
vs = [a, b, c, d, e]

# 声明方程形式
lhs = Add(Multiply(a, b), Multiply(c, d))
rhs = e

# 声明约束条件
constraints = [
	AdditionCrosses10Boundary(Multiply(a, b), Multiply(c, d)),
	IsLessThan(Multiply(a, b), Literal(20)),
	IsLessThan(Multiply(c, d), Literal(50)),
	Equal(lhs, rhs),
]
# 声明用于搜索有效算式的变量值域
domains = uniform_domains(vs, range(2, 100))

# 寻找构成有效方程的变量绑定
bindings = find_bindings(vs, domains, constraints, n_bindings=10)

# 将每个绑定集合打印为一个方程,并随机隐藏一个值
for bnd in bindings:
	lhs_expr = expression_string(lhs, bnd, hold_out=e)
	rhs_expr = expression_string(rhs, bnd, hold_out=e)
	print(f"{lhs_expr} = {rhs_expr}")

这会打印出:

1
2
3
4
5
9 * 2 + 11 * 2 = __
4 * 2 + 10 * 4 = __
2 * 5 + 16 * 3 = __
6 * 2 + 5 * 6 = __
# ...等等...

然后你可以将算式保存为PDF,打印在纸上,并用它来驱动“极限骰子足球”游戏。

高级用法

不过,你能做的远不止打印问题!你可以通过编程方式访问它们,这意味着你可以做任何你想做的事情。你可以把它们放到网站、游戏或应用程序上。你的代码知道每个问题的正确答案,因此可以检查玩家的答案是否正确。你甚至可以根据玩家的表现自动调整生成问题的难度。

例如,我制作了一个Streamlit应用程序来显示算式并检查答案,并将其部署到了Streamlit云上。现在我可以编写一个具有新规则的新游戏,将其格式编程到应用程序中,递给我儿子一个iPad,然后让iPad生成驱动游戏所需形式和难度的方程。

这真是一个无尽的乐趣源泉。

自己试试

使用以下命令安装diceomatic:

1
pip install diceomatic

查看GitHub仓库获取文档和示例。欢迎提交PR!

链接

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计