Perftree提示‘无效数字’错误,国际象棋引擎输出格式排查求助
Perftree报错"cannot compute diff: invalid digit found in string"的排查与修复
问题背景
我在开发国际象棋引擎,用之前验证过的Perftree工具做测试。按照Perftree文档要求,脚本调用引擎的perft函数,接收$depth、$fen、$moves参数,输出需满足:
- 每行是「行棋步骤 对应深度节点数」,空格分隔
- 行棋列表后输出空行
- 最后单独一行输出总节点数
我写了Rust代码实现输出逻辑:
let mut move_options = Vec::new(); game.generate_moves(&mut move_options, &all_move_data); let mut total_nodes = 0; let mut log_file = OpenOptions::new().create(true).append(true).open("perftree_output.log").expect("failed to open log file"); let mut output = String::new(); for game_move in move_options { let move_nodes = count_nodes(depth, &game_move, &game, &all_move_data); total_nodes += move_nodes; output.push_str(&format!("{} {}\n", game_move, move_nodes)); //println!("{} {}", game_move, move_nodes); } output.push_str("\n"); output.push_str(&format!("{}\n", total_nodes)); //println!("{}", output); output = output.trim().to_string(); write!(io::stdout(), "{}", output).expect("failed to write to stdout"); write!(log_file, "{}", output).expect("failed to write to log");
日志输出看起来完全符合规范:
a2a3 20 b2b4 20 b2b3 20 c2c4 20 c2c3 20 d2d4 20 d2d3 20 e2e4 20 e2e3 20 f2f4 20 f2f3 20 g2g4 20 g2g3 20 h2h4 20 h2h3 20 b1a3 20 b1c3 20 g1f3 20 g1h3 20 400
但Perftree始终报错:
cannot compute diff: invalid digit found in string
我甚至写了模拟输出的bash脚本,问题依旧:
#!/bin/bash echo "a2a4 20" echo "a2a3 20" echo "b2b4 20" echo "b2b3 20" echo "c2c4 20" echo "c2c3 20" echo "d2d4 20" echo "d2d3 20" echo "e2e4 20" echo "e2e3 20" echo "f2f4 20" echo "f2f3 20" echo "g2g4 20" echo "g2g3 20" echo "h2h4 20" echo "h2h3 20" echo "b1a3 20" echo "b1c3 20" echo "g1f3 20" echo "g1h3 20" echo echo "400"
之前用Perftree没出过问题,现在找不到错误原因,求解决思路。
排查方向与修复建议
1. 换行符格式问题
Perftree大概率只识别**LF(\n)**作为换行符,而Windows环境下Rust的标准输出或文件写入可能默认使用CRLF(\r\n)。即使日志看起来正常,隐藏的\r字符会导致Perftree解析数字时出错(比如把20\r当成非纯数字字符串)。
修复:
- 去掉
output.trim()调用,确保所有换行都是\n,避免CR字符干扰:// 删除这一行:output = output.trim().to_string(); write!(io::stdout(), "{}", output).expect("failed to write to stdout"); - 若仍有问题,强制替换所有CR字符:
output = output.replace("\r", ""); - 对于bash脚本,确保脚本文件的换行符是LF(可通过Notepad++等工具转换格式)。
2. 检查隐藏不可见字符
输出的数字部分(比如20、400)可能包含不可见的ASCII控制字符(比如全角空格、非标准空格),导致Perftree无法识别为纯数字。
排查:
- 用十六进制工具查看日志文件,确认字符编码:
正常情况下,数字应是ASCII码hexdump -C perftree_output.log30-39,空格是20,换行是0a。若出现其他编码(如c2 a0代表全角空格),说明存在异常字符。
修复:
- 确保Rust中
game_move输出纯ASCII格式的行棋字符串,move_nodes直接转换为无额外格式的整数字符串。
3. 移除多余的trim()调用
代码中output.trim().to_string()会去掉输出首尾的空白字符,可能导致总节点行缺少结尾换行,或中间空行格式被修改,触发Perftree的严格解析逻辑。直接删除这一行即可。
4. 验证Perftree版本与参数传递
- 回退到之前成功使用的Perftree版本,确认是否是新版本解析逻辑变更导致问题。
- 检查调用脚本中
$depth、$fen、$moves参数的传递是否正确,比如$fen是否包含特殊字符或未正确转义,间接导致输出解析失败。
5. 测试最小用例
简化测试场景:设置depth=1,只输出2-3个行棋步骤和总节点数,看Perftree是否正常工作。若最小用例正常,再逐步增加复杂度,定位是否是特定行棋格式或节点数导致的问题。
内容的提问来源于stack exchange,提问作者UnoriginalName369636
相关产品推荐
相关产品推荐

