koishi-plugin-cchess 1.0.7 → 1.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/index.d.ts +1 -1
- package/lib/index.js +75 -91
- package/package.json +2 -2
- package/readme.md +14 -34
package/lib/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Context, Schema } from 'koishi';
|
|
2
2
|
export declare const name = "cchess";
|
|
3
|
-
export declare const usage = "## \u4F7F\u7528\n\
|
|
3
|
+
export declare const usage = "## \u4F7F\u7528\n\n`cchess.\u52A0\u5165` \u5165\u5EA7\uFF0C`cchess.\u5F00\u59CB.\u4EBA\u4EBA\u5BF9\u6218` \u6216 `cchess.\u5F00\u59CB.\u4EBA\u673A\u5BF9\u6218` \u5F00\u5C40\u3002\u7740\u6CD5\u53EF\u76F4\u63A5\u53D1\u9001\uFF0C\u5982\u70AE\u4E8C\u5E73\u4E94\u6216 `b2e2`\u3002\n\n## \u6307\u4EE4\n\n| \u6307\u4EE4 | \u8BF4\u660E |\n| --- | --- |\n| `cchess.\u52A0\u5165 [\u7EA2/\u9ED1]` | \u5165\u5EA7 |\n| `cchess.\u9000\u51FA` | \u5F00\u5C40\u524D\u79BB\u5E2D |\n| `cchess.\u5F00\u59CB.\u4EBA\u4EBA\u5BF9\u6218` | \u4EBA\u4EBA\u5BF9\u6218 |\n| `cchess.\u5F00\u59CB.\u4EBA\u673A\u5BF9\u6218` | \u4EBA\u673A\u5BF9\u6218\uFF08\u76AE\u5361\u9C7C\uFF09 |\n| `cchess.\u79FB\u52A8 <\u7740\u6CD5>` | \u843D\u5B50 |\n| `cchess.\u6094\u68CB.\u8BF7\u6C42` | \u6094\u68CB |\n| `cchess.\u8BA4\u8F93` | \u8BA4\u8F93 |\n| `cchess.\u7ED3\u675F` | \u5F3A\u5236\u6E05\u76D8 |\n| `cchess.\u7F16\u8F91\u68CB\u76D8.\u5BFC\u5165 <FEN>` | \u5BFC\u5165\u5C40\u9762 |\n| `cchess.\u7F16\u8F91\u68CB\u76D8.\u5BFC\u51FA` | \u5BFC\u51FA\u5C40\u9762 |\n| `cchess.\u6392\u884C\u699C.\u603B\u80DC\u573A [\u4EBA\u6570]` | \u80DC\u573A\u699C |\n| `cchess.\u67E5\u8BE2\u73A9\u5BB6\u8BB0\u5F55 [@\u67D0\u4EBA]` | \u67E5\u770B\u6218\u7EE9 |";
|
|
4
4
|
export declare const inject: string[];
|
|
5
5
|
export interface Config {
|
|
6
6
|
boardSkin: string;
|
package/lib/index.js
CHANGED
|
@@ -28,55 +28,39 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
28
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
29
|
|
|
30
30
|
// src/index.ts
|
|
31
|
-
var
|
|
32
|
-
__export(
|
|
31
|
+
var index_exports = {};
|
|
32
|
+
__export(index_exports, {
|
|
33
33
|
Config: () => Config,
|
|
34
34
|
apply: () => apply,
|
|
35
35
|
inject: () => inject,
|
|
36
36
|
name: () => name,
|
|
37
37
|
usage: () => usage
|
|
38
38
|
});
|
|
39
|
-
module.exports = __toCommonJS(
|
|
39
|
+
module.exports = __toCommonJS(index_exports);
|
|
40
40
|
var import_koishi = require("koishi");
|
|
41
41
|
var path = __toESM(require("path"));
|
|
42
42
|
var fs = __toESM(require("fs"));
|
|
43
43
|
var name = "cchess";
|
|
44
44
|
var usage = `## 使用
|
|
45
45
|
|
|
46
|
-
|
|
47
|
-
2. 为常用指令设置别名(如「加入」「认输」「悔棋」)。
|
|
46
|
+
\`cchess.加入\` 入座,\`cchess.开始.人人对战\` 或 \`cchess.开始.人机对战\` 开局。着法可直接发送,如炮二平五或 \`b2e2\`。
|
|
48
47
|
|
|
49
48
|
## 指令
|
|
50
49
|
|
|
51
50
|
| 指令 | 说明 |
|
|
52
51
|
| --- | --- |
|
|
53
|
-
| \`cchess.加入 [红/黑]\` |
|
|
52
|
+
| \`cchess.加入 [红/黑]\` | 入座 |
|
|
54
53
|
| \`cchess.退出\` | 开局前离席 |
|
|
55
|
-
| \`cchess.开始.人人对战\` |
|
|
56
|
-
| \`cchess.开始.人机对战\` |
|
|
57
|
-
| \`cchess.移动 <着法>\` |
|
|
58
|
-
| \`cchess.悔棋.请求\` |
|
|
59
|
-
| \`cchess.认输\` |
|
|
54
|
+
| \`cchess.开始.人人对战\` | 人人对战 |
|
|
55
|
+
| \`cchess.开始.人机对战\` | 人机对战(皮卡鱼) |
|
|
56
|
+
| \`cchess.移动 <着法>\` | 落子 |
|
|
57
|
+
| \`cchess.悔棋.请求\` | 悔棋 |
|
|
58
|
+
| \`cchess.认输\` | 认输 |
|
|
60
59
|
| \`cchess.结束\` | 强制清盘 |
|
|
61
|
-
| \`cchess.编辑棋盘.导入 <FEN>\` |
|
|
62
|
-
| \`cchess.编辑棋盘.导出\` |
|
|
63
|
-
| \`cchess.排行榜.总胜场 [人数]\` |
|
|
64
|
-
| \`cchess.查询玩家记录 [@某人]\` |
|
|
65
|
-
|
|
66
|
-
## Q&A
|
|
67
|
-
|
|
68
|
-
1. 如何移动棋子?
|
|
69
|
-
|
|
70
|
-
- 纵线(炮二平五/炮8平5)或字母坐标(b2e2)。
|
|
71
|
-
- 详见 [中国象棋着法表示](https://www.xqbase.com/protocol/cchess_move.htm)。
|
|
72
|
-
|
|
73
|
-
2. 人机太强/太弱?
|
|
74
|
-
|
|
75
|
-
- 调整「引擎思考深度」,深度越高棋力越强,耗时也越长。
|
|
76
|
-
|
|
77
|
-
## QQ 群
|
|
78
|
-
|
|
79
|
-
- 956758505`;
|
|
60
|
+
| \`cchess.编辑棋盘.导入 <FEN>\` | 导入局面 |
|
|
61
|
+
| \`cchess.编辑棋盘.导出\` | 导出局面 |
|
|
62
|
+
| \`cchess.排行榜.总胜场 [人数]\` | 胜场榜 |
|
|
63
|
+
| \`cchess.查询玩家记录 [@某人]\` | 查看战绩 |`;
|
|
80
64
|
var inject = ["database", "puppeteer", "canvas"];
|
|
81
65
|
var pieceSkins = ["棋弈无限图形棋子", "云库木制棋子", "刘炳森红黑牛角隶书棋子", "木制棋子", "本纹隶书棋子", "银灰将军体棋子", "棋弈无限红绿正棋子", "棋弈无限红绿棋子", "棋天大圣棋子", "棋者象棋棋子", "楷书玉石棋子", "水墨青瓷棋子", "牛皮纸华康金文棋子", "皮卡鱼棋子", "红蓝祥隶棋子", "红黑精典无阴影棋子", "红黑精典棋子", "行书玉石棋子", "象甲棋子", "金属棋子篆体棋子", "镌刻华彩棋子", "鹏飞红黑棋子", "鹏飞经典棋子", "鹏飞绿龙棋子", "龙腾四海棋子"];
|
|
82
66
|
var boardSkins = ["棋弈无限红绿棋盘", "一鸣惊人棋盘", "三星堆棋盘", "云库木制棋盘", "云心鹤眼棋盘", "兰亭集序无字棋盘", "兰亭集序棋盘", "凤舞九天棋盘", "卯兔添福棋盘", "叱咤风云棋盘", "君临天下棋盘", "壁画古梦棋盘", "大闹天宫棋盘", "天山共色棋盘", "女神之约棋盘", "小吕飞刀棋盘", "山海绘卷棋盘", "护眼绿棋盘", "星河璀璨棋盘", "木制棋盘", "本纹隶书白棋盘", "本纹隶书黑棋盘", "桃花源记棋盘", "棋天大圣棋盘", "棋天无大圣棋盘", "武侠江湖棋盘", "水墨青瓷棋盘", "清悠茶道棋盘", "游园惊梦棋盘", "牛转乾坤棋盘", "玉石太极棋盘", "皓月无痕棋盘", "皮卡鱼棋盘", "盲棋神迹棋盘", "空城计棋盘", "竹波烟雨棋盘", "经典木棋盘棋盘", "绿色棋盘", "象甲2023棋盘", "象甲征程棋盘", "象甲重燃棋盘", "金牛降世棋盘", "金虎贺岁棋盘", "金虎贺岁(王天一签名版)棋盘", "鎏金岁月棋盘", "霸王别姬棋盘", "鸿门宴棋盘", "鹏飞红黑棋盘", "鹏飞经典棋盘", "鹏飞绿龙棋盘", "龙腾天坛棋盘"];
|
|
@@ -109,10 +93,10 @@ __name(isLine, "isLine");
|
|
|
109
93
|
function panel(options) {
|
|
110
94
|
const { icon = "♟️", title, at, body = [], tips = [], image } = options;
|
|
111
95
|
const lines = [`${icon} ${title}`, RULE];
|
|
112
|
-
if (at) lines.push(
|
|
96
|
+
if (at) lines.push(`@${at}`);
|
|
113
97
|
lines.push(...body.filter(isLine));
|
|
114
98
|
const validTips = tips.filter(isLine).filter(Boolean);
|
|
115
|
-
if (validTips.length) lines.push(RULE, ...validTips
|
|
99
|
+
if (validTips.length) lines.push(RULE, ...validTips);
|
|
116
100
|
if (image) lines.push(image);
|
|
117
101
|
return lines.join("\n");
|
|
118
102
|
}
|
|
@@ -242,21 +226,21 @@ function apply(ctx, config) {
|
|
|
242
226
|
const gameRecord = await getGameRecord(channelId);
|
|
243
227
|
if (gameRecord.isStarted) {
|
|
244
228
|
return await sendMessage(session, panel({
|
|
245
|
-
icon: "
|
|
229
|
+
icon: "⚠️",
|
|
246
230
|
title: "棋局已经开战",
|
|
247
231
|
at: username,
|
|
248
|
-
body: ["
|
|
249
|
-
tips: ["
|
|
232
|
+
body: ["本局正在进行,无法中途加入。"],
|
|
233
|
+
tips: ["本局结束后可再加入。"],
|
|
250
234
|
image: await renderBoard(channelId)
|
|
251
235
|
}));
|
|
252
236
|
}
|
|
253
237
|
void checkEngine(channelId);
|
|
254
238
|
if (choice?.includes("红") && choice.includes("黑")) {
|
|
255
239
|
return await sendMessage(session, panel({
|
|
256
|
-
icon: "
|
|
240
|
+
icon: "⚠️",
|
|
257
241
|
title: "一次只能选一方",
|
|
258
242
|
at: username,
|
|
259
|
-
body: ["
|
|
243
|
+
body: ["请只选择红方或黑方。"],
|
|
260
244
|
tips: ["「cchess.加入 红」执红先行", "「cchess.加入 黑」执黑应招"]
|
|
261
245
|
}));
|
|
262
246
|
}
|
|
@@ -269,7 +253,7 @@ function apply(ctx, config) {
|
|
|
269
253
|
if (selfRecords.length === 0) {
|
|
270
254
|
await ctx.database.create("cchess_gaming_player_records", { channelId, userId, username, side: choice });
|
|
271
255
|
return await sendMessage(session, panel({
|
|
272
|
-
icon: "
|
|
256
|
+
icon: "✅",
|
|
273
257
|
title: "入座成功",
|
|
274
258
|
at: username,
|
|
275
259
|
body: [field("阵营", withSideIcon(choice)), field("当前人数", `${playersNum + 1} 人`)],
|
|
@@ -278,7 +262,7 @@ function apply(ctx, config) {
|
|
|
278
262
|
} else {
|
|
279
263
|
await ctx.database.set("cchess_gaming_player_records", { channelId, userId }, { side: choice });
|
|
280
264
|
return await sendMessage(session, panel({
|
|
281
|
-
icon: "
|
|
265
|
+
icon: "✅",
|
|
282
266
|
title: "换边成功",
|
|
283
267
|
at: username,
|
|
284
268
|
body: [field("新的阵营", withSideIcon(choice)), field("当前人数", `${playersNum} 人`)]
|
|
@@ -291,11 +275,11 @@ function apply(ctx, config) {
|
|
|
291
275
|
const gameRecord = await getGameRecord(channelId);
|
|
292
276
|
if (gameRecord.isStarted) {
|
|
293
277
|
return await sendMessage(session, panel({
|
|
294
|
-
icon: "
|
|
278
|
+
icon: "⚠️",
|
|
295
279
|
title: "棋局已经开战",
|
|
296
280
|
at: username,
|
|
297
|
-
body: ["
|
|
298
|
-
tips: ["
|
|
281
|
+
body: ["对局进行中,无法退出。"],
|
|
282
|
+
tips: ["可发送「cchess.认输」结束本局"]
|
|
299
283
|
}));
|
|
300
284
|
}
|
|
301
285
|
const selfRecords = await ctx.database.get("cchess_gaming_player_records", { channelId, userId });
|
|
@@ -306,10 +290,10 @@ function apply(ctx, config) {
|
|
|
306
290
|
} else {
|
|
307
291
|
await ctx.database.remove("cchess_gaming_player_records", { channelId, userId });
|
|
308
292
|
return await sendMessage(session, panel({
|
|
309
|
-
icon: "
|
|
293
|
+
icon: "✅",
|
|
310
294
|
title: "已离席",
|
|
311
295
|
at: username,
|
|
312
|
-
body: ["
|
|
296
|
+
body: ["已退出本局。", field("剩余人数", `${playersNum - 1} 人`)]
|
|
313
297
|
}));
|
|
314
298
|
}
|
|
315
299
|
});
|
|
@@ -331,7 +315,7 @@ function apply(ctx, config) {
|
|
|
331
315
|
let assignNotice = "";
|
|
332
316
|
if (playersNum < 2) {
|
|
333
317
|
return await sendMessage(session, panel({
|
|
334
|
-
icon: "
|
|
318
|
+
icon: "⚠️",
|
|
335
319
|
title: "棋差一手,人差一位",
|
|
336
320
|
at: username,
|
|
337
321
|
body: ["人人对战至少需要 2 位棋手。", field("当前人数", `${playersNum} 人`)],
|
|
@@ -352,7 +336,7 @@ function apply(ctx, config) {
|
|
|
352
336
|
await ctx.database.set("cchess_game_records", { channelId }, { isStarted: true });
|
|
353
337
|
const sideString = convertTurnToString(gameRecord.turn);
|
|
354
338
|
return await sendMessage(session, panel({
|
|
355
|
-
icon: "
|
|
339
|
+
icon: "✅",
|
|
356
340
|
title: "楚河汉界,对局开始",
|
|
357
341
|
body: [
|
|
358
342
|
...assignNotice ? [assignNotice, ""] : [],
|
|
@@ -381,7 +365,7 @@ function apply(ctx, config) {
|
|
|
381
365
|
const blackPlayers = playerRecords.filter((player) => player.side === "黑方");
|
|
382
366
|
if (playersNum < 1 && !config.allowFreePieceMovementInHumanMachineMode) {
|
|
383
367
|
return await sendMessage(session, panel({
|
|
384
|
-
icon: "
|
|
368
|
+
icon: "⚠️",
|
|
385
369
|
title: "尚无棋手入座",
|
|
386
370
|
at: username,
|
|
387
371
|
body: ["人机对战至少需要 1 位棋手。"],
|
|
@@ -412,7 +396,7 @@ function apply(ctx, config) {
|
|
|
412
396
|
const sideString = convertTurnToString(gameRecord.turn);
|
|
413
397
|
if (engineSide === sideString) await requestEngineMove(channelId);
|
|
414
398
|
return await sendMessage(session, panel({
|
|
415
|
-
icon: "
|
|
399
|
+
icon: "✅",
|
|
416
400
|
title: "人机对局开始",
|
|
417
401
|
body: [
|
|
418
402
|
field("棋 手", withSideIcon(humanSide)),
|
|
@@ -430,7 +414,7 @@ function apply(ctx, config) {
|
|
|
430
414
|
const gameRecord = await getGameRecord(channelId);
|
|
431
415
|
if (!gameRecord.isStarted) {
|
|
432
416
|
return await sendMessage(session, panel({
|
|
433
|
-
icon: "
|
|
417
|
+
icon: "⚠️",
|
|
434
418
|
title: "棋盘尚且空空",
|
|
435
419
|
at: username,
|
|
436
420
|
body: ["当前没有进行中的对局,无需收拾残局。"],
|
|
@@ -439,7 +423,7 @@ function apply(ctx, config) {
|
|
|
439
423
|
}
|
|
440
424
|
await endGame(channelId);
|
|
441
425
|
return await sendMessage(session, panel({
|
|
442
|
-
icon: "
|
|
426
|
+
icon: "✅",
|
|
443
427
|
title: "对局已强制结束",
|
|
444
428
|
at: username,
|
|
445
429
|
body: ["棋盘已收,胜负不计。"],
|
|
@@ -596,7 +580,7 @@ function apply(ctx, config) {
|
|
|
596
580
|
}
|
|
597
581
|
if (gameRecord.moveList.length < 1) {
|
|
598
582
|
return await sendMessage(session, panel({
|
|
599
|
-
icon: "
|
|
583
|
+
icon: "⚠️",
|
|
600
584
|
title: "棋局初开",
|
|
601
585
|
at: username,
|
|
602
586
|
body: ["一子未落,无悔可言。"]
|
|
@@ -607,7 +591,7 @@ function apply(ctx, config) {
|
|
|
607
591
|
await undoMove(channelId);
|
|
608
592
|
await undoMove(channelId);
|
|
609
593
|
return await sendMessage(session, panel({
|
|
610
|
-
icon: "
|
|
594
|
+
icon: "✅",
|
|
611
595
|
title: "悔棋成功",
|
|
612
596
|
at: username,
|
|
613
597
|
body: ["棋子已归原位,皮卡鱼宽宏大量。"],
|
|
@@ -616,16 +600,16 @@ function apply(ctx, config) {
|
|
|
616
600
|
}
|
|
617
601
|
if (playerRecord[0].side === sideString) {
|
|
618
602
|
return await sendMessage(session, panel({
|
|
619
|
-
icon: "
|
|
603
|
+
icon: "⚠️",
|
|
620
604
|
title: "此刻不可悔棋",
|
|
621
605
|
at: username,
|
|
622
|
-
body: ["
|
|
606
|
+
body: ["轮到你落子,上一着是对方所走。"],
|
|
623
607
|
tips: ["落子之后,方有悔棋之说"]
|
|
624
608
|
}));
|
|
625
609
|
}
|
|
626
610
|
await ctx.database.set("cchess_game_records", { channelId }, { isRegretRequest: true });
|
|
627
611
|
return await sendMessage(session, panel({
|
|
628
|
-
icon: "
|
|
612
|
+
icon: "⏳",
|
|
629
613
|
title: "悔棋请求已送出",
|
|
630
614
|
at: username,
|
|
631
615
|
body: [field("等待答复", withSideIcon(sideString))],
|
|
@@ -639,11 +623,11 @@ function apply(ctx, config) {
|
|
|
639
623
|
await undoMove(channelId);
|
|
640
624
|
await ctx.database.set("cchess_game_records", { channelId }, { isRegretRequest: false });
|
|
641
625
|
return await sendMessage(session, panel({
|
|
642
|
-
icon: "
|
|
626
|
+
icon: "✅",
|
|
643
627
|
title: "悔棋成功",
|
|
644
628
|
at: username,
|
|
645
|
-
body: ["
|
|
646
|
-
tips: ["
|
|
629
|
+
body: ["已同意悔棋,棋子已归原位。"],
|
|
630
|
+
tips: ["对局继续。"],
|
|
647
631
|
image: await renderBoard(channelId)
|
|
648
632
|
}));
|
|
649
633
|
});
|
|
@@ -653,7 +637,7 @@ function apply(ctx, config) {
|
|
|
653
637
|
if (typeof decision === "string") return await sendMessage(session, decision);
|
|
654
638
|
await ctx.database.set("cchess_game_records", { channelId }, { isRegretRequest: false });
|
|
655
639
|
return await sendMessage(session, panel({
|
|
656
|
-
icon: "
|
|
640
|
+
icon: "⚠️",
|
|
657
641
|
title: "悔棋被拒",
|
|
658
642
|
at: username,
|
|
659
643
|
body: ["落子无悔,棋局继续。"],
|
|
@@ -678,15 +662,15 @@ function apply(ctx, config) {
|
|
|
678
662
|
const sideString = convertTurnToString(turn);
|
|
679
663
|
if (playerRecord[0].side !== sideString) {
|
|
680
664
|
return await sendMessage(session, panel({
|
|
681
|
-
icon: "
|
|
665
|
+
icon: "⚠️",
|
|
682
666
|
title: "此刻不便认输",
|
|
683
667
|
at: username,
|
|
684
|
-
body: [field("
|
|
685
|
-
tips: ["
|
|
668
|
+
body: [field("你的阵营", withSideIcon(playerRecord[0].side)), field("当前轮走", withSideIcon(sideString))],
|
|
669
|
+
tips: ["轮到你走棋时,才可以认输"]
|
|
686
670
|
}));
|
|
687
671
|
}
|
|
688
672
|
const message = await settleVictory(channelId, turn === "w" ? "b" : "w", turn, "拱手认负", {
|
|
689
|
-
icon: "
|
|
673
|
+
icon: "✅",
|
|
690
674
|
at: username,
|
|
691
675
|
extra: [`${withSideIcon(sideString)} 推枰认负,风度翩翩。`]
|
|
692
676
|
});
|
|
@@ -699,7 +683,7 @@ function apply(ctx, config) {
|
|
|
699
683
|
const { username, userId } = session;
|
|
700
684
|
await updateNameInPlayerRecord(userId, username);
|
|
701
685
|
return await sendMessage(session, panel({
|
|
702
|
-
icon: "
|
|
686
|
+
icon: "📋",
|
|
703
687
|
title: "云库残局 · DTM 统计",
|
|
704
688
|
at: username,
|
|
705
689
|
body: ["DTM:距将死的步数统计。", "https://www.chessdb.cn/egtb_info_dtm.html"]
|
|
@@ -709,7 +693,7 @@ function apply(ctx, config) {
|
|
|
709
693
|
const { username, userId } = session;
|
|
710
694
|
await updateNameInPlayerRecord(userId, username);
|
|
711
695
|
return await sendMessage(session, panel({
|
|
712
|
-
icon: "
|
|
696
|
+
icon: "📋",
|
|
713
697
|
title: "云库残局 · DTC 统计",
|
|
714
698
|
at: username,
|
|
715
699
|
body: ["DTC:距吃子的步数统计。", "https://www.chessdb.cn/egtb_info.html"]
|
|
@@ -724,7 +708,7 @@ function apply(ctx, config) {
|
|
|
724
708
|
const gameRecord = await getGameRecord(channelId);
|
|
725
709
|
if (gameRecord.isStarted) {
|
|
726
710
|
return await sendMessage(session, panel({
|
|
727
|
-
icon: "
|
|
711
|
+
icon: "⚠️",
|
|
728
712
|
title: "棋局进行中",
|
|
729
713
|
at: username,
|
|
730
714
|
body: ["对弈期间不可改动棋盘。"],
|
|
@@ -734,7 +718,7 @@ function apply(ctx, config) {
|
|
|
734
718
|
fen = fen?.trim();
|
|
735
719
|
if (!fen || !isValidateFen(fen)) {
|
|
736
720
|
return await sendMessage(session, panel({
|
|
737
|
-
icon: "
|
|
721
|
+
icon: "❌",
|
|
738
722
|
title: "FEN 串无法解析",
|
|
739
723
|
at: username,
|
|
740
724
|
body: ["请检查局面串的格式是否完整。"],
|
|
@@ -760,7 +744,7 @@ function apply(ctx, config) {
|
|
|
760
744
|
await parseFen(channelId, fen);
|
|
761
745
|
const record = await getGameRecord(channelId);
|
|
762
746
|
return await sendMessage(session, panel({
|
|
763
|
-
icon: "
|
|
747
|
+
icon: "✅",
|
|
764
748
|
title: "棋盘摆放完毕",
|
|
765
749
|
at: username,
|
|
766
750
|
body: [field("轮走方", withSideIcon(convertTurnToString(record.turn)))],
|
|
@@ -780,7 +764,7 @@ function apply(ctx, config) {
|
|
|
780
764
|
}
|
|
781
765
|
const fenWithFullMove = await getFenWithFullMove(channelId);
|
|
782
766
|
return await sendMessage(session, panel({
|
|
783
|
-
icon: "
|
|
767
|
+
icon: "📋",
|
|
784
768
|
title: "当前局面 FEN",
|
|
785
769
|
at: username,
|
|
786
770
|
body: [fenWithFullMove],
|
|
@@ -791,7 +775,7 @@ function apply(ctx, config) {
|
|
|
791
775
|
const { username, userId } = session;
|
|
792
776
|
await updateNameInPlayerRecord(userId, username);
|
|
793
777
|
return await sendMessage(session, panel({
|
|
794
|
-
icon: "
|
|
778
|
+
icon: "📋",
|
|
795
779
|
title: "FEN 串使用方法",
|
|
796
780
|
at: username,
|
|
797
781
|
body: ["中国象棋 FEN 格式规范:", "https://www.xqbase.com/protocol/cchess_fen.htm"]
|
|
@@ -860,7 +844,7 @@ function apply(ctx, config) {
|
|
|
860
844
|
});
|
|
861
845
|
function notStartedPanel(username) {
|
|
862
846
|
return panel({
|
|
863
|
-
icon: "
|
|
847
|
+
icon: "⚠️",
|
|
864
848
|
title: "棋局尚未开始",
|
|
865
849
|
at: username,
|
|
866
850
|
body: ["当前频道还没有进行中的对局。"],
|
|
@@ -870,27 +854,27 @@ function apply(ctx, config) {
|
|
|
870
854
|
__name(notStartedPanel, "notStartedPanel");
|
|
871
855
|
function alreadyStartedPanel(username) {
|
|
872
856
|
return panel({
|
|
873
|
-
icon: "
|
|
857
|
+
icon: "⚠️",
|
|
874
858
|
title: "棋局已经开战",
|
|
875
859
|
at: username,
|
|
876
|
-
body: ["
|
|
877
|
-
tips: ["「cchess
|
|
860
|
+
body: ["本局尚未结束,不必重开。"],
|
|
861
|
+
tips: ["「cchess.认输」结束本局", "「cchess.结束」强制清盘"]
|
|
878
862
|
});
|
|
879
863
|
}
|
|
880
864
|
__name(alreadyStartedPanel, "alreadyStartedPanel");
|
|
881
865
|
function notJoinedPanel(username) {
|
|
882
866
|
return panel({
|
|
883
|
-
icon: "
|
|
884
|
-
title: "
|
|
867
|
+
icon: "⚠️",
|
|
868
|
+
title: "你尚未入座",
|
|
885
869
|
at: username,
|
|
886
|
-
body: ["
|
|
870
|
+
body: ["请先加入对局。"],
|
|
887
871
|
tips: ["发送「cchess.加入」加入对局"]
|
|
888
872
|
});
|
|
889
873
|
}
|
|
890
874
|
__name(notJoinedPanel, "notJoinedPanel");
|
|
891
875
|
function analyzingPanel(username) {
|
|
892
876
|
return panel({
|
|
893
|
-
icon: "
|
|
877
|
+
icon: "⏳",
|
|
894
878
|
title: "皮卡鱼正在推演",
|
|
895
879
|
at: username,
|
|
896
880
|
body: ["引擎正在计算局面,请稍候再试。"]
|
|
@@ -899,17 +883,17 @@ function apply(ctx, config) {
|
|
|
899
883
|
__name(analyzingPanel, "analyzingPanel");
|
|
900
884
|
function notYourTurnPanel(username, yourSide, currentSide) {
|
|
901
885
|
return panel({
|
|
902
|
-
icon: "
|
|
903
|
-
title: "
|
|
886
|
+
icon: "⚠️",
|
|
887
|
+
title: "尚未轮到你",
|
|
904
888
|
at: username,
|
|
905
|
-
body: [field("
|
|
906
|
-
tips: ["
|
|
889
|
+
body: [field("你的阵营", withSideIcon(yourSide)), field("当前轮走", withSideIcon(currentSide))],
|
|
890
|
+
tips: ["请等待对方落子。"]
|
|
907
891
|
});
|
|
908
892
|
}
|
|
909
893
|
__name(notYourTurnPanel, "notYourTurnPanel");
|
|
910
894
|
function invalidMovePanel(username, reason) {
|
|
911
895
|
return panel({
|
|
912
|
-
icon: "
|
|
896
|
+
icon: "❌",
|
|
913
897
|
title: reason,
|
|
914
898
|
at: username,
|
|
915
899
|
body: ["请确认着法是否合乎棋规。"],
|
|
@@ -919,7 +903,7 @@ function apply(ctx, config) {
|
|
|
919
903
|
__name(invalidMovePanel, "invalidMovePanel");
|
|
920
904
|
function engineUnavailablePanel(username) {
|
|
921
905
|
return panel({
|
|
922
|
-
icon: "
|
|
906
|
+
icon: "⏳",
|
|
923
907
|
title: "皮卡鱼尚未就绪",
|
|
924
908
|
at: username,
|
|
925
909
|
body: ["引擎启动失败,暂时无法进行人机对战。"],
|
|
@@ -929,10 +913,10 @@ function apply(ctx, config) {
|
|
|
929
913
|
__name(engineUnavailablePanel, "engineUnavailablePanel");
|
|
930
914
|
function invalidLeaderboardSizePanel(username) {
|
|
931
915
|
return panel({
|
|
932
|
-
icon: "
|
|
916
|
+
icon: "⚠️",
|
|
933
917
|
title: "榜单人数有误",
|
|
934
918
|
at: username,
|
|
935
|
-
body: ["
|
|
919
|
+
body: ["请输入不小于 0 的整数。"],
|
|
936
920
|
tips: ["例如:cchess.排行榜.总胜场 10"]
|
|
937
921
|
});
|
|
938
922
|
}
|
|
@@ -942,7 +926,7 @@ function apply(ctx, config) {
|
|
|
942
926
|
}
|
|
943
927
|
__name(renderBoard, "renderBoard");
|
|
944
928
|
async function settleVictory(channelId, winSide, loseSide, title, options = {}) {
|
|
945
|
-
const { icon = "
|
|
929
|
+
const { icon = "✅", at, extra = [], withBoard = false } = options;
|
|
946
930
|
const image = withBoard ? await renderBoard(channelId) : void 0;
|
|
947
931
|
const winners = await ctx.database.get("cchess_gaming_player_records", {
|
|
948
932
|
channelId,
|
|
@@ -972,7 +956,7 @@ function apply(ctx, config) {
|
|
|
972
956
|
if (gameRecord.isAnalyzing || busyChannels.has(channelId)) return analyzingPanel(username);
|
|
973
957
|
if (!gameRecord.isRegretRequest) {
|
|
974
958
|
return panel({
|
|
975
|
-
icon: "
|
|
959
|
+
icon: "⚠️",
|
|
976
960
|
title: "暂无悔棋请求",
|
|
977
961
|
at: username,
|
|
978
962
|
body: [`当前没有待答复的请求,无从${action}。`]
|
|
@@ -983,7 +967,7 @@ function apply(ctx, config) {
|
|
|
983
967
|
const sideString = convertTurnToString(gameRecord.turn);
|
|
984
968
|
if (playerRecord[0].side !== sideString) {
|
|
985
969
|
return panel({
|
|
986
|
-
icon: "
|
|
970
|
+
icon: "⚠️",
|
|
987
971
|
title: "无权表决",
|
|
988
972
|
at: username,
|
|
989
973
|
body: ["悔棋请求正由对方等待答复。", field("应答方", withSideIcon(sideString))]
|
|
@@ -1189,9 +1173,9 @@ function apply(ctx, config) {
|
|
|
1189
1173
|
isHistoryMode = true;
|
|
1190
1174
|
}
|
|
1191
1175
|
let moveId = targetMove.moveId;
|
|
1192
|
-
let idx = originalState.moveList.findIndex((m) => m.moveId == moveId);
|
|
1176
|
+
let idx = originalState.moveList.findIndex(((m) => m.moveId == moveId));
|
|
1193
1177
|
moveList = originalState.moveList.slice(0, idx + 1);
|
|
1194
|
-
idx = originalState.movesAfterLastEat.findIndex((m) => m.moveId == moveId);
|
|
1178
|
+
idx = originalState.movesAfterLastEat.findIndex(((m) => m.moveId == moveId));
|
|
1195
1179
|
if (idx != -1) {
|
|
1196
1180
|
movesAfterLastEat = originalState.movesAfterLastEat.slice(0, idx + 1);
|
|
1197
1181
|
} else {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "koishi-plugin-cchess",
|
|
3
3
|
"description": "Koishi 的中国象棋插件。支持人人/人机对战。",
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.8",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"typings": "lib/index.d.ts",
|
|
7
7
|
"files": [
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"对战"
|
|
47
47
|
],
|
|
48
48
|
"peerDependencies": {
|
|
49
|
-
"koishi": "^4.18.
|
|
49
|
+
"koishi": "^4.18.11"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
52
|
"@koishijs/canvas": "^0.2.0",
|
package/readme.md
CHANGED
|
@@ -1,55 +1,35 @@
|
|
|
1
1
|
koishi-plugin-cchess
|
|
2
2
|
====================
|
|
3
3
|
|
|
4
|
-
[<img alt="github" src="https://img.shields.io/badge/github-araea/
|
|
4
|
+
[<img alt="github" src="https://img.shields.io/badge/github-araea/koishi__plugin__cchess-8da0cb?style=for-the-badge&labelColor=555555&logo=github" height="20">](https://github.com/araea/koishi-plugin-cchess)
|
|
5
5
|
[<img alt="npm" src="https://img.shields.io/npm/v/koishi-plugin-cchess.svg?style=for-the-badge&color=fc8d62&logo=npm" height="20">](https://www.npmjs.com/package/koishi-plugin-cchess)
|
|
6
6
|
|
|
7
|
-
Koishi
|
|
7
|
+
Koishi 的中国象棋插件。
|
|
8
8
|
|
|
9
9
|
## 使用
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
2. 为常用指令设置别名(如「加入」「认输」「悔棋」)。
|
|
11
|
+
`cchess.加入` 入座,`cchess.开始.人人对战` 或 `cchess.开始.人机对战` 开局。着法可直接发送,如炮二平五或 `b2e2`。
|
|
13
12
|
|
|
14
13
|
## 指令
|
|
15
14
|
|
|
16
15
|
| 指令 | 说明 |
|
|
17
16
|
| --- | --- |
|
|
18
|
-
| `cchess.加入 [红/黑]` |
|
|
17
|
+
| `cchess.加入 [红/黑]` | 入座 |
|
|
19
18
|
| `cchess.退出` | 开局前离席 |
|
|
20
|
-
| `cchess.开始.人人对战` |
|
|
21
|
-
| `cchess.开始.人机对战` |
|
|
22
|
-
| `cchess.移动 <着法>` |
|
|
23
|
-
| `cchess.悔棋.请求` |
|
|
24
|
-
| `cchess.认输` |
|
|
19
|
+
| `cchess.开始.人人对战` | 人人对战 |
|
|
20
|
+
| `cchess.开始.人机对战` | 人机对战(皮卡鱼) |
|
|
21
|
+
| `cchess.移动 <着法>` | 落子 |
|
|
22
|
+
| `cchess.悔棋.请求` | 悔棋 |
|
|
23
|
+
| `cchess.认输` | 认输 |
|
|
25
24
|
| `cchess.结束` | 强制清盘 |
|
|
26
|
-
| `cchess.编辑棋盘.导入 <FEN>` |
|
|
27
|
-
| `cchess.编辑棋盘.导出` |
|
|
28
|
-
| `cchess.排行榜.总胜场 [人数]` |
|
|
29
|
-
| `cchess.查询玩家记录 [@某人]` |
|
|
30
|
-
|
|
31
|
-
## Q&A
|
|
32
|
-
|
|
33
|
-
1. 如何移动棋子?
|
|
34
|
-
|
|
35
|
-
- 纵线(炮二平五/炮8平5)或字母坐标(b2e2)。
|
|
36
|
-
- 详见 [中国象棋着法表示](https://www.xqbase.com/protocol/cchess_move.htm)。
|
|
37
|
-
|
|
38
|
-
2. 人机太强 / 太弱?
|
|
39
|
-
|
|
40
|
-
- 调整「引擎思考深度」,深度越高棋力越强,耗时也越长。
|
|
41
|
-
|
|
42
|
-
## 致谢
|
|
43
|
-
|
|
44
|
-
- [Koishi](https://koishi.chat/) - 机器人框架
|
|
45
|
-
- [风满楼]() - 棋盘与棋子素材
|
|
46
|
-
- [皮卡鱼](https://xiangqiai.com/#/) - 中国象棋 AI 引擎
|
|
47
|
-
- [中国象棋云库](https://www.chessdb.cn/query/) - 中国象棋棋谱
|
|
48
|
-
- [中国象棋应用规范](https://www.xqbase.com/protocol/cchess_intro.htm) - 中国象棋标准规范
|
|
25
|
+
| `cchess.编辑棋盘.导入 <FEN>` | 导入局面 |
|
|
26
|
+
| `cchess.编辑棋盘.导出` | 导出局面 |
|
|
27
|
+
| `cchess.排行榜.总胜场 [人数]` | 胜场榜 |
|
|
28
|
+
| `cchess.查询玩家记录 [@某人]` | 查看战绩 |
|
|
49
29
|
|
|
50
30
|
## QQ 群
|
|
51
31
|
|
|
52
|
-
|
|
32
|
+
956758505
|
|
53
33
|
|
|
54
34
|
<br>
|
|
55
35
|
|