Files
Ubuntu 32b43f85bd a
2026-07-03 16:58:28 +08:00

199 lines
5.7 KiB
TypeScript

import { Piece, Position, Color, Difficulty, AIMove } from "../types/chess";
import { getPieceAt, isValidMove } from "./chessRules";
import { findBestMove } from "./astarAI";
// Deepseek API配置 - 请在这里填写您的API密钥
const DEEPSEEK_API_KEY: string = "sk-b8e21ac94e624691844269f0e0605cf2"; // Deepseek API密钥
const PLACEHOLDER_KEY = "your-api-key-here";
const DEEPSEEK_API_URL = "https://api.deepseek.com/v1/chat/completions";
const DEEPSEEK_MODEL = "deepseek-chat";
// 将棋盘转换为FEN-like字符串表示
function boardToString(pieces: Piece[]): string {
const board: string[][] = Array(10)
.fill(null)
.map(() => Array(9).fill("."));
for (const piece of pieces) {
if (piece.alive) {
const char = pieceTypeToChar(piece.type, piece.color);
board[piece.position.row][piece.position.col] = char;
}
}
return board.map((row) => row.join("")).join("/");
}
// 棋子类型转换为字符
function pieceTypeToChar(type: string, color: Color): string {
const charMap: Record<string, string> = {
帅: "K",
将: "k",
仕: "A",
士: "a",
相: "B",
象: "b",
马: "N",
车: "R",
炮: "C",
兵: "P",
卒: "p",
};
return charMap[type] || "?";
}
// 获取难度对应的系统提示词
function getSystemPrompt(difficulty: Difficulty, color: Color): string {
const colorText = color === "red" ? "红方" : "黑方";
const basePrompt = `你是一个中国象棋AI助手。当前你是${colorText}。
棋盘表示:每行用/分隔,每行9个格子,空位用.表示。
棋子表示:K=帅 k=将 A=仕 a=士 B=相 b=象 N=马 R=车 C=炮 P=兵 p=卒
红方用大写字母,黑方用小写字母。
你必须以以下JSON格式回复你的走法:
{
"from": {"row": 行号(0-9), "col": 列号(0-8)},
"to": {"row": 行号(0-9), "col": 列号(0-8)},
"reason": "简要说明你的走法思路"
}
注意:
1. 只能移动己方棋子
2. 必须遵守中国象棋规则
3. 行号0是黑方底线,行号9是红方底线
4. 列号0是左侧,列号8是右侧`;
switch (difficulty) {
case "容易":
return `${basePrompt}
你是初级水平的棋手。请:
1. 优先选择简单的进攻或防守走法
2. 避免复杂的战术组合
3. 偶尔可以犯一些小错误
4. 优先考虑吃子和将军`;
case "一般":
return `${basePrompt}
你是中级水平的棋手。请:
1. 选择合理的战术走法
2. 注意保护重要棋子
3. 寻找吃子机会
4. 避免明显的错误`;
case "困难":
return `${basePrompt}
你是高级水平的棋手。请:
1. 选择最优的战术走法
2. 进行深度计算,寻找最佳着法
3. 积极进攻,同时注意防守
4. 利用战术组合获得优势
5. 优先考虑将死对方的将/帅`;
default:
return basePrompt;
}
}
// 调用Deepseek API获取走法
export async function getDeepseekMove(
pieces: Piece[],
color: Color,
difficulty: Difficulty,
moveHistory: string[]
): Promise<AIMove | null> {
// 如果API密钥未配置,回退到A* AI
if (DEEPSEEK_API_KEY === PLACEHOLDER_KEY || !DEEPSEEK_API_KEY) {
console.log("Deepseek API密钥未配置,使用A* AI代替");
return findBestMove(pieces, color, difficulty);
}
const boardStr = boardToString(pieces);
const systemPrompt = getSystemPrompt(difficulty, color);
const historyStr = moveHistory.slice(-10).join("\n"); // 最近10步
const userPrompt = `当前棋盘状态(${color === "red" ? "红方" : "黑方"}走):
${boardStr}
最近走棋记录:
${historyStr || "无"}
请给出你的走法。`;
try {
const response = await fetch(DEEPSEEK_API_URL, {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${DEEPSEEK_API_KEY}`,
},
body: JSON.stringify({
model: DEEPSEEK_MODEL,
messages: [
{ role: "system", content: systemPrompt },
{ role: "user", content: userPrompt },
],
temperature: difficulty === "容易" ? 0.8 : difficulty === "一般" ? 0.5 : 0.2,
max_tokens: 500,
}),
});
if (!response.ok) {
throw new Error(`API请求失败: ${response.status}`);
}
const data = await response.json();
const content = data.choices?.[0]?.message?.content;
if (!content) {
throw new Error("API返回内容为空");
}
// 解析JSON响应
const jsonMatch = content.match(/\{[\s\S]*\}/);
if (!jsonMatch) {
throw new Error("无法解析API响应");
}
const moveData = JSON.parse(jsonMatch[0]);
const from: Position = moveData.from;
const to: Position = moveData.to;
// 验证走法是否合法
const validation = isValidMove(pieces, from, to, color);
if (!validation.valid) {
console.warn(`Deepseek返回的走法不合法: ${validation.reason},回退到A* AI`);
return findBestMove(pieces, color, difficulty);
}
return {
from,
to,
};
} catch (error) {
console.error("Deepseek API调用失败:", error);
console.log("回退到A* AI");
return findBestMove(pieces, color, difficulty);
}
}
// 检查API密钥是否已配置
export function isDeepseekConfigured(): boolean {
return DEEPSEEK_API_KEY !== PLACEHOLDER_KEY && !!DEEPSEEK_API_KEY;
}
// 获取API配置状态信息
export function getDeepseekStatus(): { configured: boolean; message: string } {
if (isDeepseekConfigured()) {
return { configured: true, message: "Deepseek API已配置" };
} else {
return {
configured: false,
message: "Deepseek API未配置,将使用本地A* AI",
};
}
}