koishi-plugin-satori-ai 1.2.11 → 1.3.0

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.
@@ -15,11 +15,11 @@ export declare abstract class abstractGameSingleGame {
15
15
  protected session: Session;
16
16
  protected disposeListener: () => boolean;
17
17
  constructor(disposeListener: () => boolean, session: Session);
18
- startGame(): string;
19
- endGame(): {
18
+ startGame(): Promise<string>;
19
+ endGame(): Promise<{
20
20
  message: string;
21
21
  gameName: string;
22
- };
22
+ }>;
23
23
  processInput(str: string): Promise<string>;
24
24
  }
25
25
  type Constructor<T> = new (...args: any[]) => T;
@@ -43,10 +43,10 @@ export declare abstract class abstractGame<T extends abstractGameSingleGame> {
43
43
  * @param ctx Koishi 上下文
44
44
  * @param args 启动参数(如难度等级)
45
45
  */
46
- startGame(session: Session, ctx: Context, args: string[]): abstractGameSingleGame | null;
46
+ startGame(session: Session, ctx: Context, args: string[]): Promise<abstractGameSingleGame | null>;
47
47
  /**
48
48
  * 结束游戏实例,触发结果事件
49
49
  */
50
- endGame(session: Session, ctx: Context): string;
50
+ endGame(session: Session, ctx: Context): Promise<string>;
51
51
  }
52
52
  export {};
package/lib/game.d.ts CHANGED
@@ -13,7 +13,7 @@ export declare class Game {
13
13
  private sat;
14
14
  constructor(ctx: Context, cfg: Sat.Config, sat: SAT);
15
15
  private registerCommands;
16
- startGame(session: Session, gameName: string, args: string[]): Promise<"当前频道已经有游戏在进行中" | "没有这个游戏哦">;
16
+ startGame(session: Session, gameName: string, args: string[]): Promise<string>;
17
17
  endGame(session: Session): Promise<string>;
18
18
  private selectGame;
19
19
  private chat;
@@ -1 +1,36 @@
1
+ import { Session } from 'koishi';
2
+ import { abstractGame, abstractGameSingleGame, gameResult } from './abstractGame';
3
+ export declare enum winFlag {
4
+ win = 1,
5
+ lose = 2,
6
+ draw = 3,
7
+ pending = 4
8
+ }
9
+ export interface fencingGameResult extends gameResult {
10
+ win: winFlag;
11
+ }
12
+ declare enum fencingAction {
13
+ attack = 1,
14
+ defence = 2
15
+ }
16
+ declare class fencingSingleGame extends abstractGameSingleGame {
17
+ private winningFlag;
18
+ private playerPosition;
19
+ private enemyPosition;
20
+ private availablePlayerActions;
21
+ static fencingActionHint: Map<fencingAction, string>;
22
+ constructor(disposeListener: () => boolean, session: Session);
23
+ private render;
24
+ startGame: () => Promise<string>;
25
+ endGame: () => Promise<{
26
+ message: string;
27
+ win: winFlag;
28
+ gameName: string;
29
+ }>;
30
+ private enemyDecision;
31
+ processInput(str: string): Promise<string>;
32
+ }
33
+ export declare class fencing extends abstractGame<fencingSingleGame> {
34
+ constructor();
35
+ }
1
36
  export {};
@@ -8,7 +8,7 @@ export declare enum winFlag {
8
8
  }
9
9
  export interface goBangGameResult extends gameResult {
10
10
  win: winFlag;
11
- level: number;
11
+ message: string;
12
12
  }
13
13
  /**
14
14
  * 五子棋单局实现类,继承自 abstractGameSingleGame
@@ -18,27 +18,32 @@ declare class goBangSingleGame extends abstractGameSingleGame {
18
18
  private winningFlag;
19
19
  level: number;
20
20
  private board;
21
+ private lastScore;
22
+ private turnsCount;
21
23
  constructor(disposeListener: () => boolean, session: Session);
22
- startGame: () => string;
23
- endGame: () => {
24
+ startGame: () => Promise<string>;
25
+ endGame: () => Promise<{
24
26
  message: string;
25
27
  win: winFlag;
26
28
  gameName: string;
27
- };
29
+ }>;
28
30
  /**
29
31
  * 处理玩家输入(落子坐标)
30
32
  * @param str 输入内容,格式为 "x y"
31
33
  */
32
34
  processInput(str: string): Promise<string>;
35
+ private getAIMove;
33
36
  private checkWin;
34
37
  private checkDirection;
38
+ private place;
35
39
  private printBoard;
40
+ private generateChat;
36
41
  }
37
42
  /**
38
43
  * 五子棋管理类,继承自 abstractGame
39
44
  */
40
45
  export declare class goBang extends abstractGame<goBangSingleGame> {
41
46
  constructor();
42
- startGame(session: Session, ctx: Context, args: string[]): goBangSingleGame;
47
+ startGame(session: Session, ctx: Context, args: string[]): Promise<goBangSingleGame>;
43
48
  }
44
49
  export {};
Binary file
@@ -1,23 +1,17 @@
1
- // emcc gobang.cpp -O3 -s EXPORTED_FUNCTIONS="['_decideMove', '_malloc', '_free']" -s MODULARIZE=1 -s ENVIRONMENT='node' -o gobang.js
2
-
1
+ // 使用DEV-C++编译器编译
3
2
  #define _CRT_SECURE_NO_WARNINGS
4
3
  #include <stdio.h>
5
4
  #include <stdlib.h>
6
5
  #include <string.h>
7
6
  #include <string>
7
+ #include <iostream>
8
+ #include <sstream>
8
9
  #define BOARD_SIZE 12 // 棋盘大小
9
10
  #define EMPTY 0 // 空位
10
11
  #define BLACK 1 // 黑棋
11
12
  #define WHITE 2 // 白棋
12
13
  #define INF 2147483647 // 正无穷
13
14
  #define _INF -2147483647 // 负无穷
14
- #define DEPTH 5 // 搜索深度
15
- #define START "START" // 开始游戏
16
- #define PLACE "PLACE" // 放置棋子
17
- #define TURN "TURN" // 轮到我方下棋
18
- #define END "END" // 游戏结束
19
- const int BOARD_MIDDLE_1 = (BOARD_SIZE + 1) / 2 - 1;
20
- const int BOARD_MIDDLE_2 = BOARD_SIZE / 2;
21
15
  struct chessType {
22
16
  int win5; // 连五
23
17
  int alive4; // 活4
@@ -29,7 +23,6 @@ struct chessType {
29
23
  int conti2; // 眠2
30
24
  int jump2; // 跳2
31
25
  int alive1; // 活1
32
- int conti1; // 眠1
33
26
  };
34
27
  // 坐标结构体
35
28
  struct coordinate {
@@ -43,31 +36,19 @@ struct coordinate {
43
36
  struct Nude {
44
37
  int board[BOARD_SIZE][BOARD_SIZE] = {{0}}; // 棋盘状态
45
38
  int state = 0; // 棋盘状态标识
46
- Nude() {
47
- // 初始化棋盘,放置初始棋子
48
- board[BOARD_MIDDLE_1][BOARD_MIDDLE_1] = WHITE;
49
- board[BOARD_MIDDLE_2][BOARD_MIDDLE_2] = WHITE;
50
- board[BOARD_MIDDLE_2][BOARD_MIDDLE_1] = BLACK;
51
- board[BOARD_MIDDLE_1][BOARD_MIDDLE_2] = BLACK;
52
- }
53
- void arr_input(int x, int y, int playerround) {
54
- board[x][y] = playerround; // 在指定位置放置棋子
55
- }
39
+ Nude() {}
56
40
  };
57
41
  class Game {
58
42
  public:
59
43
  int myFlag;
60
44
  int enemyFlag;
45
+ int inspireSearchLength;
61
46
  bool draw;
62
47
  Nude MAP;
63
48
  Game() :
64
- myFlag(0), enemyFlag(0), draw(0) {}
49
+ myFlag(0), enemyFlag(0), draw(0) {}
65
50
  };
66
- // Game game;
67
- void debug(const char *str) {
68
- printf("DEBUG %s\n", str);
69
- fflush(stdout);
70
- }
51
+
71
52
  // 判断坐标是否在棋盘范围内
72
53
  bool judgeInRange(coordinate temp) {
73
54
  if (temp.x < 0)
@@ -87,9 +68,10 @@ int getColor(coordinate target, const Game &game) {
87
68
  else
88
69
  return game.enemyFlag;
89
70
  }
71
+
90
72
  // 在指定位置放置棋子
91
73
  void place(coordinate target, int player, Game &game) {
92
- game.MAP.board[target.x][target.y] = player;
74
+ game.MAP.board[target.x][target.y] = player;
93
75
  }
94
76
  // 快速排序函数
95
77
  int partition(coordinate *s, int high, int low) {
@@ -109,6 +91,7 @@ int partition(coordinate *s, int high, int low) {
109
91
  return i;
110
92
  }
111
93
  void quickSort(coordinate *s, int high, int low = 0) {
94
+ if (high < 0) return;
112
95
  if (low < high) {
113
96
  int pi = partition(s, high, low);
114
97
  quickSort(s, pi - 1, low);
@@ -388,8 +371,7 @@ chessType typeAnalysis(coordinate p, int dire, int player, const Game &game) {
388
371
  else if (b[3] == 0)
389
372
  temp.conti2++; // 001012xxx
390
373
  }
391
- } else
392
- temp.conti1++; // xxx012xxx
374
+ }
393
375
  }
394
376
  } else {
395
377
  if (b[4] == 0) {
@@ -414,8 +396,6 @@ chessType typeAnalysis(coordinate p, int dire, int player, const Game &game) {
414
396
  } else if (b[6] == 0) {
415
397
  if (b[7] == player)
416
398
  temp.conti2++; // xxx210001
417
- else if (b[7] == 0)
418
- temp.conti1++; // xxx210000
419
399
  }
420
400
  }
421
401
  }
@@ -426,9 +406,9 @@ chessType typeAnalysis(coordinate p, int dire, int player, const Game &game) {
426
406
  // 单点得分
427
407
  int singleScore(coordinate p, int player, const Game &game) {
428
408
  chessType chesstype = typeAnalysis(p, 0, player, game);
409
+ int score = 0;
429
410
  for (int i = 1; i < 4; i++) {
430
- chessType temp;
431
- temp = typeAnalysis(p, i, player, game);
411
+ chessType temp = typeAnalysis(p, i, player, game);
432
412
  chesstype.win5 += temp.win5;
433
413
  chesstype.alive4 += temp.alive4;
434
414
  chesstype.conti4 += temp.conti4;
@@ -439,16 +419,12 @@ int singleScore(coordinate p, int player, const Game &game) {
439
419
  chesstype.conti2 += temp.conti2;
440
420
  chesstype.jump2 += temp.jump2;
441
421
  chesstype.alive1 += temp.alive1;
442
- chesstype.conti1 += temp.conti1;
443
422
  }
444
- if (chesstype.win5) // 胜
445
- return 1048576;
446
- int score = ((chesstype.conti4 << 12) +
447
- (chesstype.alive3 << 12) + (chesstype.conti3 << 8) + (chesstype.jump3 << 10) +
448
- (chesstype.alive2 << 8) + (chesstype.conti2 << 3) + (chesstype.jump2 << 6) +
449
- (chesstype.alive1 << 3) + chesstype.conti1);
450
- if (chesstype.alive3 >= 2 || (chesstype.conti4 && chesstype.alive3) || chesstype.alive4 || chesstype.conti4 >= 2) // 必胜?
451
- score += 65536;
423
+ score += chesstype.win5 << 20;
424
+ score += ((chesstype.conti4 << 9) + (chesstype.alive3 << 8) + (chesstype.conti3 << 7) +
425
+ (chesstype.jump3 << 6) + (chesstype.alive2 << 5) + (chesstype.jump2 << 3) + chesstype.conti2 + chesstype.alive1);
426
+ if (chesstype.alive3 > 1 || (chesstype.conti4 && chesstype.alive3) || chesstype.alive4 || chesstype.conti4 > 1) // 必胜?
427
+ score += (1 << 12);
452
428
  return score;
453
429
  }
454
430
  // 棋盘整体局面分
@@ -474,10 +450,9 @@ int inspireSearch(coordinate *scoreBoard, int player, Game &game) {
474
450
  for (int j = 0; j < BOARD_SIZE; j++) {
475
451
  if (game.MAP.board[i][j] == 0) {
476
452
  coordinate temp = {i, j, 0};
477
- if (hasNeighbor(temp, 3, game)) {
453
+ if (hasNeighbor(temp, 2, game)) {
478
454
  scoreBoard[length] = temp;
479
- scoreBoard[length].score = singleScore(temp, 3 - player, game);
480
- scoreBoard[length].score += singleScore(temp, player, game);
455
+ scoreBoard[length].score = singleScore(temp, 3 - player, game) + singleScore(temp, player, game);
481
456
  length++;
482
457
  }
483
458
  }
@@ -487,7 +462,7 @@ int inspireSearch(coordinate *scoreBoard, int player, Game &game) {
487
462
  quickSort(scoreBoard, length - 1);
488
463
  // 找到最高分数
489
464
  int maxScore = scoreBoard[0].score;
490
- if (maxScore < 5)
465
+ if (maxScore < 5 || length == 0)
491
466
  game.draw = 1;
492
467
  const int threshold = maxScore / 3;
493
468
  // 找到分界线
@@ -501,8 +476,9 @@ int inspireSearch(coordinate *scoreBoard, int player, Game &game) {
501
476
  // 更新 length 为分界线的位置
502
477
  length = boundary;
503
478
  // 返回 length,最多不超过
504
- return length > 10 ? 10 : length;
479
+ return length > game.inspireSearchLength ? game.inspireSearchLength : length;
505
480
  }
481
+
506
482
  // 负极大极小值搜索
507
483
  coordinate alphaBeta(int depth, int alpha, int beta, int player, coordinate command, coordinate current, Game &game) {
508
484
  coordinate temp = command;
@@ -512,9 +488,7 @@ coordinate alphaBeta(int depth, int alpha, int beta, int player, coordinate comm
512
488
  }
513
489
  coordinate steps[BOARD_SIZE * BOARD_SIZE];
514
490
  int length = inspireSearch(steps, player, game); // 搜索可落子点
515
- if (length > 7 && depth > 1)
516
- depth--;
517
- else if (length > 2)
491
+ if (length > 2)
518
492
  depth--;
519
493
  for (int i = 0; i < length; i++) {
520
494
  place(steps[i], player, game); // 模拟落子
@@ -554,39 +528,29 @@ coordinate entrance(int depth, int alpha, int beta, int player, coordinate comma
554
528
  return best;
555
529
  }
556
530
 
557
- /*
558
- * @param board: 棋盘状态
559
- * @param myFlag: 我方棋子颜色
560
- * @param depth: 搜索深度
561
- * @return: 返回落子位置
562
- * @outX: 落子横坐标指针
563
- * @outY: 落子纵坐标指针
564
- * @outScore: 落子分数指针
565
- * outX: 落子横坐标
566
- * outY: 落子纵坐标
567
- * outScore: 落子分数
568
- * -1: 游戏平局
569
- */
570
- extern "C" void decideMove(const int board[BOARD_SIZE * BOARD_SIZE], int myFlag, int depth, int* outX, int* outY, int* outScore) {
571
- Game localGame;
572
- for (int i = 0; i < BOARD_SIZE; i++) {
573
- for (int j = 0; j < BOARD_SIZE; j++) {
574
- localGame.MAP.board[i][j] = board[i * BOARD_SIZE + j];
575
- }
576
- }
577
- localGame.myFlag = myFlag;
578
- localGame.enemyFlag = 3 - myFlag;
579
- localGame.draw = 0;
531
+ coordinate calculateNextMove(const std::string& boardStr, int playerFlag, int difficulty, int inspireSearchLength) {
532
+ Game game;
533
+ game.myFlag = playerFlag;
534
+ game.enemyFlag = 3 - playerFlag;
535
+ game.inspireSearchLength = inspireSearchLength;
536
+ // 解析棋盘字符串
537
+ std::istringstream iss(boardStr);
538
+ for(int i=0; i<BOARD_SIZE; ++i)
539
+ for(int j=0; j<BOARD_SIZE; ++j)
540
+ iss >> game.MAP.board[i][j];
580
541
 
581
- coordinate cmd, current;
582
- coordinate result = entrance(depth, _INF, INF, localGame.myFlag, cmd, current, localGame);
583
- if (localGame.draw) {
584
- *outX = -1;
585
- *outY = -1;
586
- *outScore = -1;
587
- return;
588
- }
589
- *outX = result.x;
590
- *outY = result.y;
591
- *outScore = result.score;
542
+ int depth = difficulty + 1;
543
+ coordinate best = entrance(depth, _INF, INF, game.myFlag, coordinate(), coordinate(), game);
544
+ if (game.draw) {
545
+ best.x = -1;
546
+ best.y = -1;
547
+ best.score = -1;
548
+ }
549
+ return best;
550
+ }
551
+
552
+ int main(int argc, char* argv[]) {
553
+ coordinate result = calculateNextMove(argv[1], atoi(argv[2]), atoi(argv[3]), atoi(argv[4]));
554
+ std::cout << result.x << " " << result.y << " " << result.score;
555
+ return 0;
592
556
  }
package/lib/index.d.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  import { Context, Session } from 'koishi';
2
2
  import { Sat, User } from './types';
3
+ import Puppeteer from 'koishi-plugin-puppeteer';
4
+ export declare let puppeteer: Puppeteer | null;
3
5
  export declare class SAT extends Sat {
4
6
  config: Sat.Config;
5
7
  private apiClient;