尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

五子棋代码实战:用 TaoToken 统一 Key 接入 Java AI 对弈引擎

发布时间:2026/9/29 20:09:05

资讯中心
01
ARTICLE

五子棋代码实战:用 TaoToken 统一 Key 接入 Java AI 对弈引擎

五子棋代码实战:用 TaoToken 统一 Key 接入 Java AI 对弈引擎
1. 五子棋 AI 对弈为什么卡在“落子决策”这一步很多人写 Java 五子棋棋盘绘制、鼠标落子、五子连珠判定都能跑通代码量也就几百行。但一旦想加“AI 对手”问题就来了本地写死的评分函数只能看眼前一两步遇到活三、冲四、双三这种局面就开始乱下想接大模型做棋力评估又发现每个模型都要单独申请 Key、单独改请求格式Java 里还得为不同厂商写不同的 HTTP 封装。这篇就聚焦这个场景Java 五子棋代码 AI 对弈引擎用 TaoToken 的统一 Key 和统一 API 通道把“棋力评估”和“落子决策”这两件事接上大模型。你不需要为每个模型维护一套 SDK只要一个 Key、一个兼容接口就能在本地五子棋项目里跑通“人类落子 → 棋盘状态序列化 → 大模型给出候选点 → Java 解析并落子”的完整链路。适合谁看已经有一份能跑的五子棋 Java 代码Swing 或控制台都行想给它加一个“会思考”的对手或者你正在做课程设计、小项目需要把大模型能力嵌进游戏逻辑里。下面会给出可复制的config.toml配置骨架、Java 调用示例以及一次落子决策的验证动作。实测下来整条链路从配置到出结果十分钟内能跑通。2. TaoToken 前置统一 Key 与 API 通道怎么理解TaoToken 在这里扮演的角色是一个统一的模型接入层。你可以把它想成“模型世界的 USB-C 口”以前每个模型是一根专用线现在你只需要一个 Key通过一个兼容接口去调用不同模型。对 Java 五子棋项目来说这意味着你的AiEngine类里只写一套 HTTP 请求逻辑换模型只改配置里的模型名不用动业务代码。需要提前准备的东西一个 TaoToken 账号登录后在控制台创建 API Key本地 Java 环境JDK 8 以上即可示例用 JDK 17一个能发 HTTP 请求的依赖示例用 Java 11 自带的java.net.http.HttpClient不额外引包一个 TOML 解析库示例用tomljMaven 坐标org.tomlj:tomlj:1.1.1。关键地址先记好官网入口https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentAPI 基址https://taotoken.net/api创建 Keyhttps://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_campaignrewriteutm_contentapi_keys接入文档https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_campaignrewriteutm_contentdoc注意API 基址不带 UTM 参数直接写https://taotoken.net/api即可控制台和文档链接带上 UTM 方便你回看来源。拿到 Key 之后先别急着写 Java。建议去模型对话页面手动发一条消息确认 Key 可用、模型能正常返回。这一步能帮你排除掉后面 80% 的“请求 401/404”问题。3. 可复制配置config.toml 骨架与 Java 读取把配置和代码分离是让五子棋项目能长期维护的关键。下面这份config.toml放在项目src/main/resources下字段含义都写在注释里你可以直接复制。# config.toml —— 五子棋 AI 对弈配置骨架 [taotoken] # API 基址固定不带 UTM base_url https://taotoken.net/api # 在控制台创建的 Key建议用环境变量覆盖不要硬编码进仓库 api_key sk-你的Key # 模型名按文档里的可用模型填写 model claude-sonnet-4-20250514 # 单次请求超时秒 timeout_seconds 30 [game] # 棋盘大小19 表示 19x19 board_size 19 # AI 执子颜色1 黑2 白 ai_color 2 # 传给模型的候选点数量上限避免 prompt 过长 max_candidates 12 [prompt] # 系统提示词约束模型只输出坐标 system 你是一个五子棋引擎。只输出一个坐标格式为 row,col不要输出任何解释。 # 温度落子决策建议低温度 temperature 0.2Java 侧读取 TOML用tomlj很简单。下面这个GameConfig类把配置读成对象后续AiEngine直接用。import org.tomlj.Toml; import org.tomlj.TomlParseResult; import java.nio.file.Path; public class GameConfig { public final String baseUrl; public final String apiKey; public final String model; public final int timeoutSeconds; public final int boardSize; public final int aiColor; public final int maxCandidates; public final String systemPrompt; public final double temperature; public GameConfig(Path tomlPath) throws Exception { TomlParseResult r Toml.parse(tomlPath); if (r.hasErrors()) { throw new IllegalStateException(config.toml 解析失败: r.errors()); } this.baseUrl r.getString(taotoken.base_url); // 优先读环境变量避免 Key 进仓库 String envKey System.getenv(TAOTOKEN_API_KEY); this.apiKey (envKey ! null !envKey.isBlank()) ? envKey : r.getString(taotoken.api_key); this.model r.getString(taotoken.model); this.timeoutSeconds r.getLong(taotoken.timeout_seconds).intValue(); this.boardSize r.getLong(game.board_size).intValue(); this.aiColor r.getLong(game.ai_color).intValue(); this.maxCandidates r.getLong(game.max_candidates).intValue(); this.systemPrompt r.getString(prompt.system); this.temperature r.getDouble(prompt.temperature); } }这里有个小设计api_key优先从环境变量TAOTOKEN_API_KEY读配置文件里留空或写占位符都行。这样你把项目传到 Git 时不会泄露 Key团队协作也方便。4. Java 调用示例把棋盘状态变成一次落子决策核心思路分三步序列化棋盘 → 构造请求 → 解析坐标。棋盘用int[][]表示0 空、1 黑、2 白和大多数五子棋代码一致。下面AiEngine类负责和 TaoToken 通信。import java.net.URI; import java.net.http.*; import java.time.Duration; import java.util.*; public class AiEngine { private final GameConfig cfg; private final HttpClient http; public AiEngine(GameConfig cfg) { this.cfg cfg; this.http HttpClient.newBuilder() .connectTimeout(Duration.ofSeconds(cfg.timeoutSeconds)) .build(); } /** 把棋盘转成紧凑文本只保留有棋子的位置减少 token */ private String serializeBoard(int[][] board) { StringBuilder sb new StringBuilder(); for (int r 0; r board.length; r) { for (int c 0; c board[r].length; c) { if (board[r][c] ! 0) { sb.append(r).append(,).append(c) .append().append(board[r][c]).append(;); } } } return sb.toString(); } /** 请求 AI 给出落子坐标返回 int[]{row, col}失败返回 null */ public int[] decide(int[][] board) throws Exception { String boardText serializeBoard(board); String userPrompt 当前棋盘row,col颜色1黑2白 boardText 。AI 执 cfg.aiColor 。请给出你的落子坐标。; String json buildRequestBody(userPrompt); HttpRequest req HttpRequest.newBuilder() .uri(URI.create(cfg.baseUrl /v1/messages)) .timeout(Duration.ofSeconds(cfg.timeoutSeconds)) .header(Content-Type, application/json) .header(x-api-key, cfg.apiKey) .header(anthropic-version, 2023-06-01) .POST(HttpRequest.BodyPublishers.ofString(json)) .build(); HttpResponseString resp http.send(req, HttpResponse.BodyHandlers.ofString()); if (resp.statusCode() ! 200) { System.err.println(请求失败 resp.statusCode() : resp.body()); return null; } return parseCoordinate(resp.body()); } private String buildRequestBody(String userPrompt) { // 手动拼 JSON避免额外依赖生产环境建议用 Jackson String sys escape(cfg.systemPrompt); String usr escape(userPrompt); return {\model\:\ cfg.model \, \max_tokens\:64, \temperature\: cfg.temperature , \system\:\ sys \, \messages\:[{\role\:\user\,\content\:\ usr \}]}; } private String escape(String s) { return s.replace(\\, \\\\).replace(\, \\\) .replace(\n, \\n); } /** 从返回 JSON 里抠出 row,col简单正则即可 */ private int[] parseCoordinate(String body) { java.util.regex.Matcher m java.util.regex.Pattern .compile((\\d{1,2})\\s*,\\s*(\\d{1,2})).matcher(body); if (m.find()) { int r Integer.parseInt(m.group(1)); int c Integer.parseInt(m.group(2)); if (r 0 r cfg.boardSize c 0 c cfg.boardSize) { return new int[]{r, c}; } } return null; } }接入到原有五子棋代码里只需要在“轮到 AI 落子”的分支调用decide拿到坐标后写入allChess并repaint()。如果你原来的代码是flag2表示白方那就在白方回合里加if (flag cfg.aiColor canPlay) { int[] move aiEngine.decide(allChess); if (move ! null allChess[move[0]][move[1]] 0) { allChess[move[0]][move[1]] cfg.aiColor; x move[0]; y move[1]; checkFive(); flag (cfg.aiColor 1) ? 2 : 1; repaint(); } }注意x、y是你原代码里用于绘制红框和胜负判定的成员变量赋值后checkFive()才能正确判断 AI 这一手是否连五。5. 验证请求一次落子决策的完整动作配置和代码都就位后先别急着开图形界面。写一个main方法做最小验证构造一个空棋盘黑棋先占天元然后让 AI 执白落子打印它给出的坐标。public class AiSmokeTest { public static void main(String[] args) throws Exception { GameConfig cfg new GameConfig(Path.of(src/main/resources/config.toml)); AiEngine engine new AiEngine(cfg); int[][] board new int[cfg.boardSize][cfg.boardSize]; board[9][9] 1; // 黑棋天元 long t0 System.currentTimeMillis(); int[] move engine.decide(board); long cost System.currentTimeMillis() - t0; if (move null) { System.out.println(AI 未返回有效坐标检查 Key 和模型名); } else { System.out.println(AI 落子: move[0] , move[1] 耗时 cost ms); } } }成功时你会看到类似输出AI 落子: 8,8耗时 1840ms坐标落在天元附近是合理的——白棋通常贴着黑棋下。如果返回null先看控制台打印的状态码401 是 Key 问题404 是模型名或路径问题429 是频率限制。耗时在 1~3 秒属于正常取决于模型和网络。提示验证阶段可以把max_tokens调小到 32只让模型输出坐标响应会更快。6. 本篇常见错排查报错一401 Unauthorized。九成是 Key 没传对。检查x-api-key请求头是否带了sk-前缀以及环境变量TAOTOKEN_API_KEY是否覆盖了配置文件里的占位符。可以在控制台的 API Keys 页面重新生成一个再试。报错二404 Not Found。路径写错了。Anthropic 兼容接口的路径是/v1/messages拼在base_url后面就是https://taotoken.net/api/v1/messages。如果你用的是 OpenAI 兼容格式路径会不同以接入文档为准。报错三模型返回一堆解释文字正则抠不出坐标。这是系统提示词没约束住。把prompt.system改成更硬的约束比如“只输出 row,col禁止任何其他字符”同时把temperature降到 0.1。如果还不行在parseCoordinate里加一层兜底先找最后一个匹配的坐标。报错四AI 返回的坐标已经有棋子。说明模型没理解棋盘状态。检查serializeBoard是否把已有棋子都带上了以及userPrompt里是否明确说了“AI 执白”。另外可以在提示词里加一句“不要选择已有棋子的位置”。报错五图形界面卡死。http.send是同步阻塞的放在 Swing 的事件线程里会冻结界面。解决办法是把decide放到SwingWorker的doInBackground里done回调里再repaint()。报错六TOML 解析报hasErrors。多半是字符串引号或数字类型写错。temperature要写0.2而不是0.2board_size写整数不要加引号。用tomlj的r.errors()打印具体行号。7. 下一步把统一 Key 用在长期编码与 Agent 场景跑通一次落子决策之后你会发现这套结构的扩展性很好换模型只改config.toml里的model字段想加“棋力评估”接口就在AiEngine里再加一个方法复用同一个 Key 和HttpClient。如果你打算把五子棋 AI 做成长期维护的项目或者想把它接进更大的 Agent 工作流里可以了解一下 Coding Plan它更适合需要持续调用、多模型切换的编码场景。想先手动验证模型输出模型对话需要创建或轮换 KeyAPI Keys接入细节和参数说明接入文档长期编码 / Agent 场景Coding Plan我自己的习惯是每加一个新模型先在模型对话里发一条“输出 8,8”确认格式再回到 Java 里跑AiSmokeTest。两步都过了才把它写进正式对局逻辑。这样排障路径最短也不会把配置问题误判成代码 bug。
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。