koishi-plugin-cchess 0.0.3 → 0.0.5
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 +2 -0
- package/lib/index.js +39 -13
- package/package.json +1 -1
- package/readme.md +9 -7
package/lib/index.d.ts
CHANGED
|
@@ -9,9 +9,11 @@ export interface Config {
|
|
|
9
9
|
boardSkin: string;
|
|
10
10
|
pieceSkin: string;
|
|
11
11
|
defaultEngineThinkingDepth: number;
|
|
12
|
+
allowFreePieceMovementInHumanMachineMode: boolean;
|
|
12
13
|
defaultMaxLeaderboardEntries: number;
|
|
13
14
|
retractDelay: number;
|
|
14
15
|
isChessImageWithOutlineEnabled: boolean;
|
|
16
|
+
imgScale: number;
|
|
15
17
|
imageType: "png" | "jpeg" | "webp";
|
|
16
18
|
isTextToImageConversionEnabled: boolean;
|
|
17
19
|
}
|
package/lib/index.js
CHANGED
|
@@ -59,9 +59,11 @@ const boardSkins = ["棋弈无限红绿棋盘", "一鸣惊人棋盘", "三星堆
|
|
|
59
59
|
exports.Config = koishi_1.Schema.object({
|
|
60
60
|
boardSkin: koishi_1.Schema.union(boardSkins).default('木制棋盘').description(`棋盘皮肤。`),
|
|
61
61
|
pieceSkin: koishi_1.Schema.union(pieceSkins).default('木制棋子').description(`棋子皮肤。`),
|
|
62
|
+
allowFreePieceMovementInHumanMachineMode: koishi_1.Schema.boolean().default(false).description(` 是否允许在人机模式下自由移动棋子,开启后可以不需要加入游戏直接开始玩人机模式。`),
|
|
62
63
|
defaultEngineThinkingDepth: koishi_1.Schema.number().min(0).max(100).default(10).description(`默认引擎思考深度,越高 AI 棋力越强。由于 Nodejs 不支持 SIMD,所以不建议设置过高。`),
|
|
63
64
|
defaultMaxLeaderboardEntries: koishi_1.Schema.number().min(0).default(10).description(`显示排行榜时默认的最大人数。`),
|
|
64
65
|
retractDelay: koishi_1.Schema.number().min(0).default(0).description(`自动撤回等待的时间,单位是秒。值为 0 时不启用自动撤回功能。`),
|
|
66
|
+
imgScale: koishi_1.Schema.number().min(1).default(1).description(`图片分辨率倍率。`),
|
|
65
67
|
imageType: koishi_1.Schema.union(['png', 'jpeg', 'webp']).default('png').description(`发送的图片类型。`),
|
|
66
68
|
isTextToImageConversionEnabled: koishi_1.Schema.boolean().default(false).description(`是否开启将文本转为图片的功能(可选),如需启用,需要启用 \`markdownToImage\` 服务。`),
|
|
67
69
|
isChessImageWithOutlineEnabled: koishi_1.Schema.boolean().default(true).description(`是否为象棋图片添加辅助外框,关闭后可以显著提升图片速度,但无辅助外框,玩起来可能会比较累。`),
|
|
@@ -91,7 +93,7 @@ function apply(ctx, config) {
|
|
|
91
93
|
const ke = 120;
|
|
92
94
|
const weight = 500;
|
|
93
95
|
const height = 550;
|
|
94
|
-
const scale =
|
|
96
|
+
const scale = config.imgScale;
|
|
95
97
|
const isFlipBoard = false;
|
|
96
98
|
const engineSettings = {
|
|
97
99
|
Threads: 1,
|
|
@@ -174,16 +176,28 @@ function apply(ctx, config) {
|
|
|
174
176
|
});
|
|
175
177
|
// zjj*
|
|
176
178
|
ctx.middleware(async (session, next) => {
|
|
177
|
-
let { channelId, content, userId } = session;
|
|
179
|
+
let { channelId, content, userId, username } = session;
|
|
178
180
|
const gameRecord = await getGameRecord(channelId);
|
|
179
181
|
if (!gameRecord.isStarted) {
|
|
180
182
|
return await next();
|
|
181
183
|
}
|
|
182
|
-
|
|
183
|
-
if (playerRecord.length === 0) {
|
|
184
|
-
|
|
184
|
+
let playerRecord = await ctx.database.get('cchess_gaming_player_records', { channelId, userId });
|
|
185
|
+
if (playerRecord.length === 0 && !config.allowFreePieceMovementInHumanMachineMode) {
|
|
186
|
+
if (!(gameRecord.isEnginePlayRed || gameRecord.isEnginePlayBlack)) {
|
|
187
|
+
return await next();
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
if (gameRecord.isEnginePlayRed) {
|
|
191
|
+
await ctx.database.create('cchess_gaming_player_records', { channelId, userId, username, side: '黑方' });
|
|
192
|
+
playerRecord = await ctx.database.get('cchess_gaming_player_records', { channelId, userId });
|
|
193
|
+
}
|
|
194
|
+
else if (gameRecord.isEnginePlayBlack) {
|
|
195
|
+
await ctx.database.create('cchess_gaming_player_records', { channelId, userId, username, side: '红方' });
|
|
196
|
+
playerRecord = await ctx.database.get('cchess_gaming_player_records', { channelId, userId });
|
|
197
|
+
}
|
|
198
|
+
}
|
|
185
199
|
}
|
|
186
|
-
|
|
200
|
+
if (playerRecord.length !== 0) {
|
|
187
201
|
const turn = gameRecord.turn;
|
|
188
202
|
const sideString = turn === 'w' ? '红方' : '黑方';
|
|
189
203
|
if (playerRecord[0].side !== sideString) {
|
|
@@ -349,7 +363,7 @@ function apply(ctx, config) {
|
|
|
349
363
|
let blackPlayers = getPlayerRecords.filter((player) => player.side === '黑方');
|
|
350
364
|
let message = '';
|
|
351
365
|
let AISide = '';
|
|
352
|
-
if (playersNum < 1) {
|
|
366
|
+
if (playersNum < 1 && !config.allowFreePieceMovementInHumanMachineMode) {
|
|
353
367
|
return await sendMessage(session, `【@${username}】\n当前玩家人数不足 1 人,无法开始游戏!`);
|
|
354
368
|
}
|
|
355
369
|
else {
|
|
@@ -462,11 +476,23 @@ function apply(ctx, config) {
|
|
|
462
476
|
}
|
|
463
477
|
const turn = gameRecord.turn;
|
|
464
478
|
const sideString = convertTurnToString(turn);
|
|
465
|
-
|
|
479
|
+
let playerRecord = await ctx.database.get('cchess_gaming_player_records', { channelId, userId });
|
|
466
480
|
if (playerRecord.length === 0) {
|
|
467
|
-
|
|
481
|
+
if (config.allowFreePieceMovementInHumanMachineMode) {
|
|
482
|
+
if (gameRecord.isEnginePlayRed) {
|
|
483
|
+
await ctx.database.create('cchess_gaming_player_records', { channelId, userId, username, side: '黑方' });
|
|
484
|
+
playerRecord = await ctx.database.get('cchess_gaming_player_records', { channelId, userId });
|
|
485
|
+
}
|
|
486
|
+
else if (gameRecord.isEnginePlayBlack) {
|
|
487
|
+
await ctx.database.create('cchess_gaming_player_records', { channelId, userId, username, side: '红方' });
|
|
488
|
+
playerRecord = await ctx.database.get('cchess_gaming_player_records', { channelId, userId });
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
else {
|
|
492
|
+
return await sendMessage(session, `【@${username}】\n您还未加入游戏呢!`);
|
|
493
|
+
}
|
|
468
494
|
}
|
|
469
|
-
|
|
495
|
+
if (playerRecord[0].side !== sideString) {
|
|
470
496
|
return await sendMessage(session, `【@${username}】\n还没轮到${sideString}走棋哦!\n当前走棋方为:【${convertTurnToString(gameRecord.turn)}】`);
|
|
471
497
|
}
|
|
472
498
|
await checkEngine(channelId);
|
|
@@ -1544,12 +1570,12 @@ function apply(ctx, config) {
|
|
|
1544
1570
|
}
|
|
1545
1571
|
}
|
|
1546
1572
|
async function createImage(buffer) {
|
|
1547
|
-
const canvas = await ctx.canvas.createCanvas(
|
|
1573
|
+
const canvas = await ctx.canvas.createCanvas(620 * scale, 780 * scale);
|
|
1548
1574
|
const context = canvas.getContext('2d');
|
|
1549
1575
|
const outerFrame = await ctx.canvas.loadImage(outerFrameImg);
|
|
1550
|
-
context.drawImage(outerFrame, 0, 0,
|
|
1576
|
+
context.drawImage(outerFrame, 0, 0, 620 * scale, 780 * scale);
|
|
1551
1577
|
const boardImg = await ctx.canvas.loadImage(buffer);
|
|
1552
|
-
context.drawImage(boardImg,
|
|
1578
|
+
context.drawImage(boardImg, 36.5 * scale, 90 * scale, 550 * scale, 605 * scale);
|
|
1553
1579
|
return canvas.toBuffer('image/png');
|
|
1554
1580
|
}
|
|
1555
1581
|
function isMoveString(str) {
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -14,17 +14,19 @@
|
|
|
14
14
|
|
|
15
15
|
- 建议自行添加别名,如 `cc` 等更方便的指令。
|
|
16
16
|
- 请安装并启用所需服务,`canvas` 服务可使用 `puppeteer` 提供。
|
|
17
|
-
-
|
|
17
|
+
-
|
|
18
|
+
支持使用中国象棋纵线(炮二平五/炮8平5)和字母坐标(a0a1)进行移动。[了解详情 - 中国象棋着法表示](https://www.xqbase.com/protocol/cchess_move.htm)
|
|
18
19
|
|
|
19
20
|
## ⚙️ 配置项
|
|
20
21
|
|
|
21
|
-
- `boardSkin`: 棋盘皮肤,可选值有:木制棋盘、玉石太极棋盘等数十种精美皮肤。
|
|
22
|
-
- `pieceSkin`: 棋子皮肤,可选值有:红黑棋子、隶书棋子等数十种不同风格。
|
|
23
|
-
- `defaultEngineThinkingDepth`: 默认 AI 思考深度,数值越大棋力越强,但耗费资源也更多。
|
|
24
|
-
- `retractDelay`: 自动撤回等待时间(秒),设为0则不自动撤回。
|
|
25
22
|
- `imageType`: 发送图片类型,可选 `png/jpeg/webp`。
|
|
23
|
+
- `retractDelay`: 自动撤回等待时间(秒),设为0则不自动撤回。
|
|
24
|
+
- `pieceSkin`: 棋子皮肤,可选值有:红黑棋子、隶书棋子等数十种不同风格。
|
|
26
25
|
- `isTextToImageConversionEnabled`: 是否开启文字转图片功能(可选)。
|
|
26
|
+
- `boardSkin`: 棋盘皮肤,可选值有:木制棋盘、玉石太极棋盘等数十种精美皮肤。
|
|
27
|
+
- `defaultEngineThinkingDepth`: 默认 AI 思考深度,数值越大棋力越强,但耗费资源也更多。
|
|
27
28
|
- `isChessImageWithOutlineEnabled`:是否为象棋图片添加辅助外框,关闭后可以显著提升图片速度,但无辅助外框,玩起来可能会比较累。
|
|
29
|
+
- `allowFreePieceMovementInHumanMachineMode`: 是否允许在人机模式下自由移动棋子,开启后可以不需要加入游戏直接开始玩人机模式。
|
|
28
30
|
|
|
29
31
|
## 🌼 指令
|
|
30
32
|
|
|
@@ -43,11 +45,11 @@
|
|
|
43
45
|
|
|
44
46
|
## 🍧 致谢
|
|
45
47
|
|
|
46
|
-
- [Koishi](https://koishi.chat/) - 出色的机器人框架 🤖
|
|
47
48
|
- [风满楼]() - 提供棋盘与棋子素材 🎨
|
|
49
|
+
- [Koishi](https://koishi.chat/) - 出色的机器人框架 🤖
|
|
48
50
|
- [皮卡鱼网页版](https://xiangqiai.com/#/) - 强大的象棋引擎 🐟
|
|
49
|
-
- [中国象棋电脑应用规范](https://www.xqbase.com/protocol/cchess_intro.htm) - 遵循标准规范 📜
|
|
50
51
|
- [中国象棋云库查询](https://www.chessdb.cn/query/) - 囊括海量棋谱 📖
|
|
52
|
+
- [中国象棋电脑应用规范](https://www.xqbase.com/protocol/cchess_intro.htm) - 遵循标准规范 📜
|
|
51
53
|
|
|
52
54
|
## ✨ License
|
|
53
55
|
|