OpenSpiel 状态方法 is_terminal 详解:判定游戏结束的 API 与源码实现
人工智能强化学习深度学习【免费下载链接】open_spielOpenSpiel is a collection of environments and algorithms for research in general reinforcement learning and search/planning in games.项目地址https://gitcode.com/gh_mirrors/op/open_spiel点击查看免费下载state.is_terminal()是 OpenSpiel 中判断当前状态是否为终态游戏是否结束的核心状态查询方法几乎出现在每一个游戏循环、搜索树遍历与强化学习算法中。本文将基于 OpenSpiel 仓库的官方 API 文档结合 C 核心抽象层与 Python 绑定源码完整讲解该方法的使用方式、返回语义、底层实现原理及典型实战场景帮助你正确地在自研算法中利用终态判定驱动训练与评估流程。方法签名与返回语义在 OpenSpiel 的 Python 接口中每个状态对象State都提供is_terminal()方法is_terminal() - bool其语义为如果当前状态是终态游戏已经结束返回True否则返回False。该方法不接受任何参数返回值为布尔类型。它是状态节点类型判定方法族中的一员与之并列的还有is_initial_state()是否为初始状态、is_chance_node()是否为机会节点、is_simultaneous_node()是否为同时行动节点、is_player_node()是否为玩家决策节点、is_mean_field_node()是否为平均场节点等详见 核心 API 参考 中对应的 state_is_terminal.md 文档。官方文档示例精讲示例一井字棋tic_tac_toe官方文档给出的第一个示例是回合制游戏井字棋import pyspiel game pyspiel.load_game(tic_tac_toe) state game.new_initial_state() print(state.is_terminal()) # Output: False新创建的游戏初始状态下棋盘为空、双方均未获胜游戏显然尚未结束因此is_terminal()返回False。示例二石头剪刀布矩阵博弈matrix_rps第二个示例演示了同时行动博弈的终态判定import pyspiel game pyspiel.load_game(matrix_rps) state game.new_initial_state() print(state.is_terminal()) # Output: False state.apply_actions([1, 1]) print(state.is_terminal()) # Output: True这里matrix_rps是 OpenSpiel 内置的石头剪刀布矩阵博弈Rock, Paper, Scissors。初始状态下两位玩家尚未出招游戏未结束返回False随后state.apply_actions([1, 1])让两位玩家同时选择动作1即都出“布”由于矩阵博弈是单轮one-shot同时行动游戏联合动作一经应用状态立即变为终态is_terminal()返回True。值得说明的是apply_actions是同时行动博弈专用接口用于一次性提交所有玩家的联合动作而在回合制博弈中则应使用apply_action逐个玩家应用动作。这一点在两个示例的对比中体现得很清楚。源码级原理从 Python 绑定到 C 纯虚函数state.is_terminal()并非 Python 单独实现的逻辑而是直接绑定到 C 核心层的State::IsTerminal()。在 Python 绑定文件 open_spiel/python/pybind11/pyspiel.cc 中可以看到.def(is_terminal, State::IsTerminal)也就是说Python 侧每次调用state.is_terminal()都会调用 C 虚函数IsTerminal()。在状态基类 open_spiel/spiel.h 中该方法被声明为纯虚函数// Is this a terminal state? (i.e. has the game ended?) virtual bool IsTerminal() const 0;这意味着每一个具体游戏的状态类都必须实现该方法而“游戏是否结束”的具体判定规则完全由各游戏自定义。这也解释了为什么不同游戏对“终态”的定义可以完全不同回合制棋类游戏如井字棋、五子棋通常判定为“某一方达成获胜条件”或“棋盘已满无法继续落子”单轮矩阵博弈如matrix_rps判定为“联合动作已执行”扑克类游戏则通常判定为“所有玩家已完成全部下注轮并到达摊牌或弃牌阶段”。终态与收益的联动Rewards() 的默认实现IsTerminal()不仅驱动游戏循环的终止还直接影响收益计算。在 open_spiel/spiel.h 中Rewards()的默认实现以IsTerminal()为分界virtual std::vectordouble Rewards() const { if (IsTerminal()) { return Returns(); } else { return std::vectordouble(num_players_, 0.0); } }即终态时返回各玩家的最终收益Returns()非终态时返回全零向量。该默认实现只适用于“仅终局结算”的游戏对于存在中途奖励intermediate rewards的 RL 风格游戏子类必须同时重写Rewards()与Returns()。这从侧面说明了IsTerminal()在 OpenSpiel 收益模型GameType::RewardModel::kTerminal与kModelBased中的枢纽地位。两个代表游戏的终态判定实现井字棋条件组合判定在 open_spiel/games/tic_tac_toe/tic_tac_toe.cc 中井字棋的终态判定实现为bool TicTacToeState::IsTerminal() const { return outcome_ ! kInvalidPlayer || IsFull(); }即满足以下任一条件即为终态outcome_ ! kInvalidPlayer已有玩家连成一线获胜IsFull()9 个格子全部被占满平局。对应的收益实现Returns()tic_tac_toe.cc在玩家 0 获胜时返回{1.0, -1.0}玩家 1 获胜时返回{-1.0, 1.0}平局返回{0.0, 0.0}。可见is_terminal()返回True并不意味着一定存在赢家——平局同样属于终态。另外在 tic_tac_toe.cc 中LegalActions()也优先检查IsTerminal()终态时直接返回空列表避免在已结束的状态上继续落子。石头剪刀布矩阵博弈联合动作驱动matrix_rps属于 OpenSpiel 的矩阵博弈家族其状态类型MatrixState定义在 open_spiel/matrix_game.hbool IsTerminal() const override { return !joint_move_.empty(); }只要joint_move_联合动作记录非空即两位玩家都已出招状态即为终态。这与官方文档示例中apply_actions([1, 1])之后is_terminal()立即返回True的行为完全吻合。终态时的收益由 matrix_game.h 中的Returns()按行玩家与列玩家的效用矩阵查表得到非终态时两者均为 0。matrix_rps游戏本身在 open_spiel/games/matrix_games/matrix_games.cc 中注册两名玩家、同时行动kSimultaneous、确定性、零和kZeroSum、单轮kOneShot、终局奖励kTerminal。这些GameType属性正是理解“为何一步之后即为终态”的关键。实战在游戏循环与算法中使用 is_terminal通用游戏循环范式is_terminal()最常见的用法是驱动一个通用的对局循环。OpenSpiel 官方示例 open_spiel/python/examples/example.py 展示了完整范式while not state.is_terminal(): # The state can be three different types: chance node, # simultaneous node, or decision node if state.is_chance_node(): # Chance node: sample an outcome outcomes state.chance_outcomes() num_actions len(outcomes) print(Chance node, got str(num_actions) outcomes) action_list, prob_list zip(*outcomes) action np.random.choice(action_list, pprob_list) state.apply_action(action) elif state.is_simultaneous_node(): # Simultaneous node: sample actions for all players. ... else: # Decision node: sample a uniform random action. ...这个循环在每一轮开头都调用state.is_terminal()作为退出条件随后按节点类型分派处理。无论是机会节点掷骰子、洗牌、同时行动节点还是普通决策节点统一由这一个循环覆盖——这正是is_terminal()作为“通用状态查询”接口的价值所在。类似的while not state.is_terminal():循环模式还大量出现在 open_spiel/python/examples/mcts.py、open_spiel/python/examples/dots_and_boxes_example.py、open_spiel/python/examples/benchmark_games.py 等示例中是 OpenSpiel 生态中最主流的对局驱动方式。在搜索与求解算法中的关键作用在 MCTS、CFR 等树搜索算法中is_terminal()是递归展开的终止条件。以 open_spiel/python/algorithms/mcts.py 为例节点展开Expand、回溯BackUp等流程都依赖对终态的判定来决定是否继续生成子节点、是否直接以终局收益作为估值。在 open_spiel/python/algorithms/minimax.py 等极小极大求解器中叶子节点终态直接返回静态评估值Returns()非终态才递归搜索。可以说is_terminal()构成了几乎所有树形算法递归基base case的判定基础。结合其他状态查询方法使用在编写循环时is_terminal()通常与以下方法配合使用方法作用典型用途is_terminal()游戏是否结束循环退出条件、树搜索递归基is_chance_node()是否为机会节点决定是否按概率抽样is_simultaneous_node()是否为同时行动节点决定用apply_actions还是apply_actionis_player_node()是否为单个玩家决策节点决定是否为决策点legal_actions()当前合法动作列表终态时返回空列表returns()/player_return(p)各玩家累计收益终态后读取结算结果其中值得注意的细节是在终态下调用legal_actions()会返回空列表如 open_spiel/matrix_game.h 中if (IsTerminal()) return {};因此在编写算法时应先检查is_terminal()再查询合法动作避免对已结束状态执行无效操作。测试与验证OpenSpiel 的 Python 测试套件对初始状态的终态判定有明确断言。在 open_spiel/python/tests/pyspiel_test.py 中def test_othello(self): game pyspiel.load_game(othello) state game.new_initial_state() self.assertFalse(state.is_chance_node()) self.assertFalse(state.is_terminal()) self.assertEqual(state.legal_actions(), [19, 26, 37, 44]) def test_tic_tac_toe(self): game pyspiel.load_game(tic_tac_toe) state game.new_initial_state() self.assertFalse(state.is_chance_node()) self.assertFalse(state.is_terminal()) self.assertEqual(state.legal_actions(), [0, 1, 2, 3, 4, 5, 6, 7, 8])可以看到奥赛罗othello与井字棋的初始状态均被断言为非终态且初始合法动作列表完整。如果你在实现自定义游戏时发现is_terminal()行为异常可参考这类测试模式断言“初始状态非终态、执行完整动作序列后为终态、终态时legal_actions()为空”。使用注意事项小结终态不等于有赢家井字棋平局、矩阵博弈平局同样返回True应结合returns()区分胜负平。不同游戏的终态规则差异巨大IsTerminal()是纯虚函数语义完全由具体游戏实现切换游戏时不要假设终态触发的动作数一致。终态是“一次性”的分界一旦is_terminal()返回True通常不应再调用apply_action/apply_actions推进状态legal_actions()此时为空列表。收益读取要在终态之后默认Rewards()实现下非终态收益恒为 0真正的结算结果需在终态后通过returns()或player_return()获取。性能考量在 MCTS 等高频调用场景中is_terminal()会被反复执行其成本取决于具体游戏的判定逻辑如井字棋只需检查outcome_与棋盘是否填满成本极低。通过本文的介绍你应当能够熟练运用state.is_terminal()驱动 OpenSpiel 的游戏循环与树搜索算法并理解其在 C 核心层与 Python 绑定层的完整调用链Python 方法 → pyspiel.cc 绑定 → spiel.h 纯虚函数 → 各游戏状态类的自定义实现。这一理解将帮助你在编写自定义游戏或调试算法循环时快速定位终态判定相关的逻辑问题。赞分享人工智能强化学习深度学习【免费下载链接】open_spielOpenSpiel is a collection of environments and algorithms for research in general reinforcement learning and search/planning in games.项目地址https://gitcode.com/gh_mirrors/op/open_spiel点击查看免费下载相关推荐OpenSpiel 核心 API 详解new_initial_state() 与游戏初始状态OpenSpiel 核心 API 详解new_initial_state 与游戏初始状态 导读 new_initial_state 是 OpenSpiel 中人工智能强化学习深度学习OpenSpiel 游戏 API 详解max_move_number() 与 move_number 上限约束OpenSpiel 游戏 API 详解max_move_number 与 move_number 上限约束 导读 max_move_number 是 Open人工智能强化学习深度学习OpenSpiel 游戏方法 max_game_length() 详解决策节点上限的定义、源码实现与实战应用OpenSpiel 游戏方法 max_game_length 详解决策节点上限的定义、源码实现与实战应用 导读 max_game_length 是 OpenS人工智能强化学习深度学习创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

Access 2021 数据库程序实战:从表设计到VBA自动化与部署

Access 2021 数据库程序实战:从表设计到VBA自动化与部署

简介:面向需要安装和使用 Access 2021 数据库程序的用户,这份资源包提供了完整的六十四位安装文件与配套辅助材料。其中包含解压密码说明、安装必看要点以及在线咨询通道,能有效解决获取安装包和初始化配置时的常见问题。资源内共五个文件&am…

2026/10/12 15:27:41 阅读更多 →
VB中如何实现手型光标?TaoToken统一Key接入AI辅助排查

VB中如何实现手型光标?TaoToken统一Key接入AI辅助排查

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 15:26:40 阅读更多 →
openJiuwen DeepSearch 大纲模式路由:从 system.md 规则到 hybrid 路由的源码级解析

openJiuwen DeepSearch 大纲模式路由:从 system.md 规则到 hybrid 路由的源码级解析

人工智能大模型AI AgentRAG深度研究搜索引擎后端代码智能体 【免费下载链接】deepsearch openJiuwen DeepSearch是一款知识增强的深度搜索与研究框架,有业界领先的片段级引用和溯源推理能力,提供精准Agentic搜索与研究能力 项目地址: https:/…

2026/10/12 15:26:40 阅读更多 →

最新新闻

2026年亲测AI论文平台榜单(合规高效版):把Base URL改到TaoToken的实测记录

2026年亲测AI论文平台榜单(合规高效版):把Base URL改到TaoToken的实测记录

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 19:48:04 阅读更多 →
AI原生全栈开发训练营:从写代码到编排AI的实战指南

AI原生全栈开发训练营:从写代码到编排AI的实战指南

最近总有人问我:AI时代还要不要学全栈开发?我的回答很直接——要学,但不能再用原来那套学法。我自己做了好几年传统前后端,后来把AI能力嵌进产品,也在带一个叫“AI原生超级全栈开发工程师训练营”的项目。这个训练营的…

2026/10/12 19:48:04 阅读更多 →
企业级AI编程软件必看:2026最新8款权威工具深度推荐与TaoToken统一接入实践

企业级AI编程软件必看:2026最新8款权威工具深度推荐与TaoToken统一接入实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 19:48:04 阅读更多 →
小白也能轻松玩转龙虾:虾壳云一键部署 OpenClaw 桌面快速安装与 TaoToken 通道配置

小白也能轻松玩转龙虾:虾壳云一键部署 OpenClaw 桌面快速安装与 TaoToken 通道配置

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 19:48:04 阅读更多 →
【异常】解决 Windows PowerShell 无法识别 ‘claude‘ 命令的实战指南:把 PATH 改到 TaoToken 的排查路径

【异常】解决 Windows PowerShell 无法识别 ‘claude‘ 命令的实战指南:把 PATH 改到 TaoToken 的排查路径

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 19:48:03 阅读更多 →
电商商品分类库实战:从类目映射到数据清洗的完整指南

电商商品分类库实战:从类目映射到数据清洗的完整指南

简介:这份商品分类库面向电商平台搭建者、零售运营人员及ERP/CRM系统开发者,提供一套可直接落地的货品分类数据方案,解决新建商城或系统升级时分类体系从零构建耗时费力的问题。资源包共1个文件,为SQL脚本类型,压缩包约…

2026/10/12 19:47:03 阅读更多 →

日新闻

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

在数码相机、高清显示屏与现代矢量图形技术高度发达的今天,画面可以做到绝对的锐利、平滑与无瑕。然而,当一张秋日手账插画或拍立得照片过于“平整无瑕”时,往往会散发出一种冰冷生硬的“数码塑料感(Digital Plasticity&#xff0…

2026/10/12 0:00:59 阅读更多 →
活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

在现代网页与移动端设计中,横排(Horizontal Layout)早已经成为了绝对的主流。然而,当我们翻开泛黄的线装古籍、宋版木刻诗集,或是欣赏一张茶道雅集的手写便签时,那种**自上而下纵向书写、自右向左逐列铺展&…

2026/10/12 0:00:59 阅读更多 →
周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

每到周日的晚上八点到十点,很多人心里都会悄悄亮起一盏警示灯。 在心理学上,这种现象有一个专门的称谓——“周日夜晚焦虑症(Sunday Scaries)”。明天又是周一,闹钟又要重新在七点响彻卧房;脑海里仿佛有一个…

2026/10/12 0:00:59 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/12 0:16:30 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/12 0:16:43 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 10:45:37 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 14:48:49 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →