录像表达式参考
本页列出网站原生录像播放器,以及录像分析页中计数器、自定义事件的表达式能力。第三方播放器不适用。三种场景均使用 expr-eval 语法,字段范围和结果要求不同。
三种场景
| 项目 | 录像播放器 | 录像页计数器 | 录像页自定义事件 |
|---|---|---|---|
| 位置 | 原生弹窗播放器的自定义计数器 | 录像分析页的数值计数器;数据轨道引用其结果 | 录像分析页的自定义事件行 |
| 取值来源 | 播放位置对应的录像 getter | 原生事件快照和整份录像的静态数据 | 与计数器相同的字段来源 |
| 最终结果 | 转成文本显示;可拼接数字和字符串 | 必须是单一数字,允许 NaN、正负无穷 | 必须是布尔值、数字或字符串 |
| 求值时机 | 播放位置更新时 | 按每行选择的采样模式求值 | 连续采样:每毫秒取最后一个原生事件 |
| 两次采样之间 | 不使用录像页的采样插值 | 数值按时间线性插值;范围外保持最近端点 | 按采样结果判定事件,不插值真假 |
| 显示格式 | 在公式中使用 roundTo、字符串拼接等 | 在独立 format 输入框使用 d3-format,默认 .3f | 颜色和 marker/line 样式;没有数值 format |
| 错误 | 显示错误内容 | 在数值格子显示错误内容 | 解析、求值错误或非法类型均视为未发生 |
差分 d | 不支持 | 支持,前驱由该行采样模式决定 | 支持,前驱由连续采样决定 |
自定义事件使用 JavaScript 原生真假判断:true、非零数字和非空字符串表示发生;false、0、-0、NaN、空字符串表示不发生。正负无穷表示发生,"false"、"0"、仅含空白的字符串也表示发生。数组和函数等其他类型均不发生。
时间轴和棋盘采用相同的事件悬停提示:脉冲显示事件时间及该时刻表达式得到的数字或字符串,布尔结果只显示时间;持续事件显示完整起止时间和持续时间,不受显示范围裁剪影响。时间以秒显示,保留三位小数。
自定义事件的“棋盘标记大小”仅影响棋盘图层;时间轴标记固定为 8px,形状、颜色和不透明度仍跟随事件设置。
棋盘自定义事件图层在新配置中默认开启并选中 pluck。悬停在脉冲标记上可查看时间和值(布尔值不显示);悬停在持续事件轨迹上可查看完整起止时间和持续时间,即使当前只显示部分轨迹。已有保存的图层设置不被默认值覆盖。
连续采样包含所有原生事件类型,每毫秒采样一次;有事件时取该毫秒最后一个,无事件时沿用此前最近原生事件的全部字段,包括 time。采样时间戳使用当前毫秒,但 time 保留来源事件的原始时间。计数器的按键/局面变化模式先筛选符合条件的事件,再保留每毫秒最后一个符合条件的事件,不补齐空白毫秒。自定义事件不随计数器行的模式改变。
支持的字段
“支持”指可以直接作为变量名使用;“—”表示不可直接使用。字段名称区分大小写。计数器和自定义事件的动态值来自采样事件,静态值属于整份录像;播放器读取其当前 getter 原值,不补为 0。以下字段之外的变量(包括 currentMs、current_time、timeMs 和 bvs)不支持;计数器行 key 和事件 key 也不会成为其他公式的变量。
局面与录像静态字段
| 字段 | 含义与单位 | 录像播放器 | 录像页计数器 | 自定义事件 |
|---|---|---|---|---|
row | 棋盘行数 | 支持 | 支持 | 支持 |
column | 棋盘列数 | 支持 | 支持 | 支持 |
mine_num | 棋盘总雷数 | 支持 | 支持 | 支持 |
pix_size | 录像原始格子边长,像素;不是页面显示大小 | 支持 | 支持 | 支持 |
bbbv | 整张棋盘的 3BV | 支持 | 支持 | 支持 |
op | 整张棋盘的空(Opening)数 | 支持 | 支持 | 支持 |
isl | 整张棋盘的岛(Island)数 | 支持 | 支持 | 支持 |
cell0 | 整张棋盘数字 0(空白格)的数量 | 支持 | 支持 | 支持 |
cell1 | 整张棋盘数字 1 的数量 | 支持 | 支持 | 支持 |
cell2 | 整张棋盘数字 2 的数量 | 支持 | 支持 | 支持 |
cell3 | 整张棋盘数字 3 的数量 | 支持 | 支持 | 支持 |
cell4 | 整张棋盘数字 4 的数量 | 支持 | 支持 | 支持 |
cell5 | 整张棋盘数字 5 的数量 | 支持 | 支持 | 支持 |
cell6 | 整张棋盘数字 6 的数量 | 支持 | 支持 | 支持 |
cell7 | 整张棋盘数字 7 的数量 | 支持 | 支持 | 支持 |
cell8 | 整张棋盘数字 8 的数量 | 支持 | 支持 | 支持 |
zini | 贪心算法得到的标雷操作数(ZiNi) | 支持 | 支持 | 支持 |
hzini | 先打开所有空,再用贪心算法计算的操作数(Human ZiNi) | 支持 | 支持 | 支持 |
rtime | 录像总用时,秒;不是当前播放进度 | 支持 | 支持 | 支持 |
level | 录像难度级别代码 | 支持 | 支持 | 支持 |
mode | 录像游戏模式代码 | 支持 | 支持 | 支持 |
cell0 到 cell8 是九个独立变量,cell0-8 不是变量名。数字指标的背景说明见扫雷数据。
动态字段与播放器专有字段
| 字段 | 含义与单位 | 录像播放器 | 录像页计数器 | 自定义事件 |
|---|---|---|---|---|
time | 采样事件的原始时间,秒;计时开始前可能为负,不等同于页面进度 | — | 支持 | 支持 |
path | 累计鼠标路径长度,保留依赖原值,不随页面格子缩放 | 支持 | 支持 | 支持 |
bbbv_solved | 累计完成的 3BV | 支持 | 支持 | 支持 |
left | 累计左键点击数 | 支持 | 支持 | 支持 |
right | 累计右键点击数 | 支持 | 支持 | 支持 |
double | 累计双击数 | 支持 | 支持 | 支持 |
lce | 累计有效左键点击数 | 支持 | 支持 | 支持 |
rce | 累计有效右键点击数 | 支持 | 支持 | 支持 |
dce | 累计有效双击数 | 支持 | 支持 | 支持 |
flag | 标雷数 | 支持 | 支持 | 支持 |
op_solved | 已打开的空数 | — | 支持 | 支持 |
isl_solved | 已解决的岛数 | — | 支持 | 支持 |
mouse_state | 鼠标状态代码;录像页取该原生事件完成后的状态 | 支持 | 支持 | 支持 |
bbbv_s | 3BV/s | 支持 | — | — |
ce | 有效点击数合计 | 支持 | — | — |
ce_s | 有效点击数每秒 | 支持 | — | — |
cl | 点击数合计 | 支持 | — | — |
cl_s | 点击数每秒 | 支持 | — | — |
left_s | 左键点击数每秒 | 支持 | — | — |
right_s | 右键点击数每秒 | 支持 | — | — |
double_s | 双击数每秒 | 支持 | — | — |
flag_s | 标雷速率 | 支持 | — | — |
etime | 预计完成用时(Estimated Time),秒 | 支持 | — | — |
rtime_ms | 录像总用时,毫秒 | 支持 | — | — |
rqp | RQP 速度评价指标 | 支持 | — | — |
stnb | STNB 完成度与速度评价指标 | 支持 | — | — |
corr | 操作准确率指标 | 支持 | — | — |
thrp | 处理效率指标 | 支持 | — | — |
ioe | 操作效率指标 | 支持 | — | — |
pluck | 累计 Pluck 评价指标 | 支持 | 支持 | 支持 |
current_event_id | 当前原生事件数组索引,不是时间 | 支持 | — | — |
game_board_state | 游戏局面状态代码 | 支持 | — | — |
video_start_time | 录像起始时间偏移,秒 | 支持 | — | — |
video_end_time | 录像结束时间坐标,秒 | 支持 | — | — |
录像页没有 bbbv_s、cl、ce 等变量,可以用已有字段组合计算,例如 bbbv_solved / time、left + right + double、lce + rce + dce。这些是自定义公式,不保证等价于播放器 getter 在所有特殊局面下的算法。
录像分析页加载时计算逐事件 pluck。数值保留原值:未得到有效分析值时可能为 NaN,踩雷的失败值为 Number.MAX_VALUE,不替换为 0 或无穷。
mouse_state 编码
| 值 | 状态名 | 含义 |
|---|---|---|
| 1 | UpUp | 左右键均抬起 |
| 2 | UpDown | 左键抬起,右键按下 |
| 3 | UpDownNotFlag | 左键抬起,右键按下,且没有标雷或取消标雷 |
| 4 | DownUp | 左键按下,右键抬起 |
| 5 | Chording | 左右键均按下,双击状态 |
| 6 | ChordingNotFlag | 左右键均按下,先在不能右击的格子上按下右键 |
| 7 | DownUpAfterChording | 双击后先抬起右键,左键仍按下 |
| 8 | Undefined | 未初始化 |
DownUp 等状态名不是表达式常量;请使用数字,例如 mouse_state == 4。
运算与语法
三种场景的以下运算均可使用,但计数器的最终结果仍必须是数字。数组、字符串和布尔值可作为中间结果。表格按大致由高到低的优先级排列,不确定时使用括号。
| 运算或语法 | 含义与示例 | 录像播放器 | 录像页计数器 | 自定义事件 |
|---|---|---|---|---|
(...) | 分组,例如 (left + right) / time | 支持 | 支持 | 支持 |
f(...)、a[i]、x.y | 函数调用、从 0 开始的索引、属性读取,如 [left, right][0]、[left, right].length;不会绕过变量白名单 | 支持 | 支持 | 支持 |
[a, b, ...]、"text"、'text' | 数组及字符串字面量 | 支持 | 支持 | 支持 |
x! | 后缀阶乘,5! 为 120;不是逻辑非 | 支持 | 支持 | 支持 |
x ^ y | 乘方,2 ^ 3 为 8;不是异或 | 支持 | 支持 | 支持 |
+x、-x、not x | 转数字、取负、逻辑非;一元数学函数见下表 | 支持 | 支持 | 支持 |
*、/、% | 乘、除、取余 | 支持 | 支持 | 支持 |
+、- | 数值加、减;+ 不是字符串拼接 | 支持 | 支持 | 支持 |
x || y | 拼接字符串;两侧均为数组时拼接数组,不是逻辑或 | 支持 | 支持 | 支持 |
==、!=、<、<=、>、>= | 比较,例如 left > right | 支持 | 支持 | 支持 |
x in a | 是否属于数组,例如 mouse_state in [4, 5, 7] | 支持 | 支持 | 支持 |
x and y | 逻辑且;左侧为假时不计算右侧 | 支持 | 支持 | 支持 |
x or y | 逻辑或;左侧为真时不计算右侧 | 支持 | 支持 | 支持 |
c ? a : b | 条件表达式,只计算选中的分支,支持嵌套 | 支持 | 支持 | 支持 |
a; b | 顺序求值并返回最后一个结果,不是变量声明 | 支持 | 支持 | 支持 |
x = value | 赋值 | 不支持 | 不支持 | 不支持 |
f(x) = expr | 定义函数 | 不支持 | 不支持 | 不支持 |
if (...) { ... }、&&、!x、**、===、=> | JavaScript 语句/运算符或箭头函数;不是这里的语法 | 不支持 | 不支持 | 不支持 |
and、or、not 使用关键字,逻辑结果是布尔值;计数器需要数值时使用 条件 ? 1 : 0。也支持科学计数法,例如 1e-3。括号建议写全,如 sin(time)^2,避免一元函数省略括号时的优先级歧义。
常量
| 常量或写法 | 含义 | 三种场景 |
|---|---|---|
PI | 圆周率 | 支持 |
E | 自然常数 | 支持 |
true、false | 布尔常量 | 支持,计数器不可直接作为最终结果 |
0 / 0 | 产生 NaN | 支持,计数器保留此数字,自定义事件判为未发生 |
1 / 0、-1 / 0 | 产生正负无穷 | 支持,计数器保留此数字,自定义事件判为发生 |
NaN、Infinity、Inf、null、undefined | 这些名称不是可用的内置常量 | 不支持 |
函数
以下为当前内置函数和可写成函数形式的一元运算,三种场景均支持。x、a、f 等表示参数占位符,不是新增的录像字段。角度均以弧度为单位。
| 函数 | 含义与示例 | 录像播放器 | 录像页计数器 | 自定义事件 |
|---|---|---|---|---|
abs(x) | 绝对值,如 abs(-3) | 支持 | 支持 | 支持 |
sign(x) | 符号,负/零/正数通常得到 -1/0/1 | 支持 | 支持 | 支持 |
ceil(x) | 向上取整 | 支持 | 支持 | 支持 |
floor(x) | 向下取整 | 支持 | 支持 | 支持 |
round(x) | 四舍五入到整数,使用 JavaScript 的舍入规则 | 支持 | 支持 | 支持 |
trunc(x) | 向零截断小数部分 | 支持 | 支持 | 支持 |
roundTo(x, n) | 保留 n 位小数,如 roundTo(time, 3);n 为负可舍入到十位、百位等,不固定输出末尾零 | 支持 | 支持 | 支持 |
min(a, b, ...) | 最小值,也可传数组 min([left, right]) | 支持 | 支持 | 支持 |
max(a, b, ...) | 最大值,也可传数组 max([left, right]) | 支持 | 支持 | 支持 |
sqrt(x) | 平方根 | 支持 | 支持 | 支持 |
cbrt(x) | 立方根 | 支持 | 支持 | 支持 |
pow(x, y) | 乘方,等价于 x ^ y | 支持 | 支持 | 支持 |
hypot(a, b, ...) | 各参数平方和的平方根 | 支持 | 支持 | 支持 |
pyt(a, b, ...) | hypot 的别名 | 支持 | 支持 | 支持 |
exp(x) | E ^ x | 支持 | 支持 | 支持 |
expm1(x) | exp(x) - 1 | 支持 | 支持 | 支持 |
ln(x) | 自然对数 | 支持 | 支持 | 支持 |
log(x) | 自然对数,ln 的别名,不是以 10 为底 | 支持 | 支持 | 支持 |
log2(x) | 以 2 为底的对数 | 支持 | 支持 | 支持 |
log10(x) | 以 10 为底的对数 | 支持 | 支持 | 支持 |
lg(x) | log10 的别名 | 支持 | 支持 | 支持 |
log1p(x) | ln(1 + x) | 支持 | 支持 | 支持 |
sin(x) | 正弦 | 支持 | 支持 | 支持 |
cos(x) | 余弦 | 支持 | 支持 | 支持 |
tan(x) | 正切 | 支持 | 支持 | 支持 |
asin(x) | 反正弦 | 支持 | 支持 | 支持 |
acos(x) | 反余弦 | 支持 | 支持 | 支持 |
atan(x) | 反正切 | 支持 | 支持 | 支持 |
atan2(y, x) | 向量 (x, y) 的方向角;注意参数 y 在前 | 支持 | 支持 | 支持 |
sinh(x) | 双曲正弦 | 支持 | 支持 | 支持 |
cosh(x) | 双曲余弦 | 支持 | 支持 | 支持 |
tanh(x) | 双曲正切 | 支持 | 支持 | 支持 |
asinh(x) | 反双曲正弦 | 支持 | 支持 | 支持 |
acosh(x) | 反双曲余弦 | 支持 | 支持 | 支持 |
atanh(x) | 反双曲正切 | 支持 | 支持 | 支持 |
gamma(x) | Gamma 函数,对正整数 n 有 gamma(n) = (n - 1)! | 支持 | 支持 | 支持 |
fac(x) | 阶乘,与 x! 对应;非整数使用 Gamma 扩展 | 支持 | 支持 | 支持 |
random(n) | 生成 [0, n) 的随机数;省略 n 或 n=0 时使用 1,不适合可复现的分析 | 支持 | 支持 | 支持 |
length(x) | 字符串或数组长度 | 支持 | 支持 | 支持 |
indexOf(x, a) | x 在字符串或数组 a 中的首个索引,从 0 开始;不存在返回 -1 | 支持 | 支持 | 支持 |
join(sep, a) | 用分隔符 sep 将数组 a 拼成字符串 | 支持 | 支持 | 支持 |
map(f, a) | 将函数应用于数组元素,返回数组,如 map(abs, [-1, 2]) | 支持 | 支持 | 支持 |
filter(f, a) | 保留函数返回值为真的元素,返回数组,如 filter(abs, [-1, 0, 2]) | 支持 | 支持 | 支持 |
fold(f, initial, a) | 依次归约为一个值,如 fold(pow, 2, [3, 2]) 得到 64 | 支持 | 支持 | 支持 |
if(c, a, b) | 根据 c 返回 a 或 b,但两个分支都会先求值;需要短路时使用 c ? a : b | 支持 | 支持 | 支持 |
not(x) | 逻辑非,也可写 not x;返回布尔值 | 支持 | 支持 | 支持 |
d(expr) | 当前采样点的数值表达式减去上一采样点的值 | — | 支持 | 支持 |
d(expr, n) | 减去前 n 个采样点的值;n 必须是正整数 | — | 支持 | 支持 |
map、filter、fold 的函数参数可以使用兼容的内置函数;不支持 JavaScript 箭头函数或在公式里定义新函数。没有通用的 String、Number、isNaN、isFinite、Math.* 函数:转数字使用一元 +,拼接文本使用 "" || value,检测 NaN 可使用 value != value,其中 value 应替换为实际字段或表达式。d 必须直接调用,不作为这些数组函数的回调。
差分规则
| 规则 | 说明 |
|---|---|
| 差分对象 | 可以是字段或数值表达式,如 d(left)、d(left + right)、d(bbbv_solved) / d(time) |
| 默认步长 | d(expr) 等价于 d(expr, 1);按保留的采样点数量计数,不是毫秒数或原生事件数量 |
| 步长表达式 | n 在当前采样点求值,如 d(left, time > 1 ? 2 : 1);非正整数会报错 |
| 前驱不足 | 返回 NaN;计数器保留该数字,自定义事件判为未发生 |
| 嵌套差分 | 支持 d(d(left))、d(d(left, 2), 3);前者前两点、后者前五点为 NaN |
| 不自动归一化 | 差分不自动除以步长或时间差;需要速率时显式除以 d(time) |
| 求值顺序 | 先筛选、合并毫秒采样点,再求差分;计数器之后才插值和格式化 |
| 条件分支 | 分支跳过某次差分调用不会改变“上一采样点”的含义 |
默认计数器
首次使用时,计数器默认采用连续采样、.3f 显示格式:
| key | 表达式 | 默认 Plot |
|---|---|---|
Bvs | d(bbbv_solved, 1000) / d(time, 1000) | Plot 1 |
Ces | d(lce+rce+dce, 1000)/d(time, 1000) | Plot 1 |
Mov | d(path, 1000) / d(time, 1000) / 16 | Plot 2 |
这里的 1000 表示连续采样的 1000 个毫秒采样点;分母使用原始事件 time 的差值。开头不足 1000 点时为 NaN,时间差为零时也可能出现非有限值。原有小写 bvs 不再作为默认计数器;已保存的计数器和 Plot 配置不会被新默认值覆盖。
默认自定义事件
首次使用时,默认包含以下事件:
| key | 类型 | 表达式 |
|---|---|---|
left | 持续 | mouse_state in [4, 5, 6, 7] |
right | 持续 | mouse_state in [2, 3, 5, 6] |
pluck | 脉冲 | d(pluck) |
pluck 脉冲在累计值相比上一毫秒发生变化时出现;值不变或差分为 NaN 时不出现。已有保存的自定义事件不会被新默认值覆盖。
示例
| 场景 | 公式 | 效果 |
|---|---|---|
| 录像播放器 | roundTo(bbbv_s, 3) || "@" || bbbv_solved || "/" || bbbv | 拼接速率、已完成 BV 和总 BV |
| 录像页计数器 | time > 0 ? bbbv_solved / time : 0 | 计算累计 3BV/s;独立 format 可设为 .3f |
| 录像页计数器 | d(bbbv_solved) / d(time) | 两个采样点之间的 3BV/s,首点为 NaN |
| 自定义脉冲事件 | d(left) > 0 | 在累计左键点击数增加的毫秒产生脉冲 |
| 自定义持续事件 | mouse_state in [4, 5, 6, 7] | 选择左键处于按下状态的连续事件段 |
| 自定义事件 | mouse_state == 4 and d(left) > 0 | 同时满足鼠标状态和点击增量条件 |
