@konoui/mjimage 0.0.1 → 0.0.2
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/README.md +2 -2
- package/dist/mjs/cmd/index.d.ts +1 -0
- package/dist/mjs/cmd/index.js +49 -0
- package/dist/mjs/index.d.ts +1 -1
- package/dist/mjs/index.js +1 -1
- package/dist/mjs/lib/calculator/index.d.ts +284 -0
- package/dist/mjs/lib/calculator/index.js +1390 -0
- package/dist/mjs/lib/constants.d.ts +22 -2
- package/dist/mjs/lib/constants.js +28 -9
- package/dist/mjs/lib/controller/controller.d.ts +223 -0
- package/dist/mjs/lib/controller/controller.js +862 -0
- package/dist/mjs/lib/controller/efficiency.d.ts +36 -0
- package/dist/mjs/lib/controller/efficiency.js +217 -0
- package/dist/mjs/lib/controller/events.d.ts +172 -0
- package/dist/mjs/lib/controller/events.js +102 -0
- package/dist/mjs/lib/controller/game.d.ts +5 -0
- package/dist/mjs/lib/controller/game.js +29 -0
- package/dist/mjs/lib/controller/index.d.ts +10 -0
- package/dist/mjs/lib/controller/index.js +26 -0
- package/dist/mjs/lib/controller/managers.d.ts +89 -0
- package/dist/mjs/lib/controller/managers.js +212 -0
- package/dist/mjs/lib/controller/player.d.ts +12 -0
- package/dist/mjs/lib/controller/player.js +88 -0
- package/dist/mjs/lib/controller/replay.d.ts +10 -0
- package/dist/mjs/lib/controller/replay.js +34 -0
- package/dist/mjs/lib/controller/river.d.ts +19 -0
- package/dist/mjs/lib/controller/river.js +55 -0
- package/dist/mjs/lib/controller/state-machine.d.ts +116 -0
- package/dist/mjs/lib/controller/state-machine.js +733 -0
- package/dist/mjs/lib/controller/wall.d.ts +30 -0
- package/dist/mjs/lib/controller/wall.js +115 -0
- package/dist/mjs/lib/image.d.ts +3 -2
- package/dist/mjs/lib/image.js +78 -17
- package/dist/mjs/lib/lexer.d.ts +2 -1
- package/dist/mjs/lib/lexer.js +7 -0
- package/dist/mjs/lib/measure-text.d.ts +19 -0
- package/dist/mjs/lib/measure-text.js +52 -0
- package/dist/mjs/lib/mjai/event.d.ts +117 -0
- package/dist/mjs/lib/mjai/event.js +348 -0
- package/dist/mjs/lib/mjimage.js +3 -5
- package/dist/mjs/lib/parser.d.ts +51 -7
- package/dist/mjs/lib/parser.js +276 -42
- package/dist/mjs/lib/table-parser.d.ts +8 -6
- package/dist/mjs/lib/table-parser.js +12 -11
- package/dist/mjs/lib/table.d.ts +1 -1
- package/package.json +16 -8
- package/dist/index.html +0 -17763
- package/dist/mjs/lib/context.d.ts +0 -12
- package/dist/mjs/lib/context.js +0 -33
- package/dist/svg/_0.svg +0 -1
- package/dist/svg/m0.svg +0 -1
- package/dist/svg/m1.svg +0 -1
- package/dist/svg/m2.svg +0 -1
- package/dist/svg/m3.svg +0 -1
- package/dist/svg/m4.svg +0 -1
- package/dist/svg/m5.svg +0 -1
- package/dist/svg/m6.svg +0 -1
- package/dist/svg/m7.svg +0 -1
- package/dist/svg/m8.svg +0 -1
- package/dist/svg/m9.svg +0 -1
- package/dist/svg/p0.svg +0 -1
- package/dist/svg/p1.svg +0 -1
- package/dist/svg/p2.svg +0 -1
- package/dist/svg/p3.svg +0 -1
- package/dist/svg/p4.svg +0 -1
- package/dist/svg/p5.svg +0 -1
- package/dist/svg/p6.svg +0 -1
- package/dist/svg/p7.svg +0 -1
- package/dist/svg/p8.svg +0 -1
- package/dist/svg/p9.svg +0 -1
- package/dist/svg/s0.svg +0 -1
- package/dist/svg/s1.svg +0 -1
- package/dist/svg/s2.svg +0 -1
- package/dist/svg/s3.svg +0 -1
- package/dist/svg/s4.svg +0 -1
- package/dist/svg/s5.svg +0 -1
- package/dist/svg/s6.svg +0 -1
- package/dist/svg/s7.svg +0 -1
- package/dist/svg/s8.svg +0 -1
- package/dist/svg/s9.svg +0 -1
- package/dist/svg/stick100.svg +0 -1
- package/dist/svg/stick1000.svg +0 -1
- package/dist/svg/z1.svg +0 -1
- package/dist/svg/z2.svg +0 -1
- package/dist/svg/z3.svg +0 -1
- package/dist/svg/z4.svg +0 -1
- package/dist/svg/z5.svg +0 -1
- package/dist/svg/z6.svg +0 -1
- package/dist/svg/z7.svg +0 -1
- package/dist/tiles.1417fc37.svg +0 -1
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { Wind } from "../constants";
|
|
2
|
+
import { Tile } from "../parser";
|
|
3
|
+
import { Hand } from "../calculator";
|
|
4
|
+
import { Counter } from "./managers";
|
|
5
|
+
export interface Candidate {
|
|
6
|
+
tile: Tile;
|
|
7
|
+
candidates: Tile[];
|
|
8
|
+
shanten: number;
|
|
9
|
+
}
|
|
10
|
+
export declare class Efficiency {
|
|
11
|
+
static calcCandidates(hand: Hand, choices: Tile[]): Candidate[];
|
|
12
|
+
static candidateTiles(hand: Hand): {
|
|
13
|
+
shanten: number;
|
|
14
|
+
candidates: Tile[];
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
export interface PlayerCandidate {
|
|
18
|
+
tile: Tile;
|
|
19
|
+
sum: number;
|
|
20
|
+
candidates: {
|
|
21
|
+
tile: Tile;
|
|
22
|
+
n: number;
|
|
23
|
+
}[];
|
|
24
|
+
shanten: number;
|
|
25
|
+
}
|
|
26
|
+
export declare class PlayerEfficiency {
|
|
27
|
+
static calcPlayerCandidates(counter: Counter, candidates: Candidate[]): PlayerCandidate[];
|
|
28
|
+
static selectMinPriority(c: Counter, playerCandidates: PlayerCandidate[], doras: Tile[]): PlayerCandidate;
|
|
29
|
+
private static calcPriority;
|
|
30
|
+
}
|
|
31
|
+
export declare class RiskRank {
|
|
32
|
+
static selectTile(c: Counter, targetUsers: Wind[], tiles: Tile[]): Tile;
|
|
33
|
+
static rank(c: Counter, targetUsers: Wind[], t: Tile): number;
|
|
34
|
+
static rankZ(c: Counter, targetUser: Wind, t: Tile): number;
|
|
35
|
+
static rankN(c: Counter, targetUser: Wind, t: Tile): 0 | 3 | 4 | 8 | 5 | 6 | 12;
|
|
36
|
+
}
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.RiskRank = exports.PlayerEfficiency = exports.Efficiency = void 0;
|
|
7
|
+
var assert_1 = __importDefault(require("assert"));
|
|
8
|
+
var constants_1 = require("../constants");
|
|
9
|
+
var parser_1 = require("../parser");
|
|
10
|
+
var calculator_1 = require("../calculator");
|
|
11
|
+
var Efficiency = (function () {
|
|
12
|
+
function Efficiency() {
|
|
13
|
+
}
|
|
14
|
+
Efficiency.calcCandidates = function (hand, choices) {
|
|
15
|
+
(0, assert_1.default)(choices.length > 0, "choices to discard is zero");
|
|
16
|
+
var ret = [];
|
|
17
|
+
for (var _i = 0, choices_1 = choices; _i < choices_1.length; _i++) {
|
|
18
|
+
var t = choices_1[_i];
|
|
19
|
+
var tiles = hand.dec([t]);
|
|
20
|
+
var c = Efficiency.candidateTiles(hand);
|
|
21
|
+
hand.inc(tiles);
|
|
22
|
+
if (ret.length == 0 || c.shanten < ret[0].shanten) {
|
|
23
|
+
ret = [
|
|
24
|
+
{
|
|
25
|
+
shanten: c.shanten,
|
|
26
|
+
candidates: c.candidates,
|
|
27
|
+
tile: t,
|
|
28
|
+
},
|
|
29
|
+
];
|
|
30
|
+
}
|
|
31
|
+
else if (c.shanten == ret[0].shanten) {
|
|
32
|
+
ret.push({
|
|
33
|
+
candidates: c.candidates,
|
|
34
|
+
shanten: c.shanten,
|
|
35
|
+
tile: t,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return ret;
|
|
40
|
+
};
|
|
41
|
+
Efficiency.candidateTiles = function (hand) {
|
|
42
|
+
var r = Number.POSITIVE_INFINITY;
|
|
43
|
+
var candidates = [];
|
|
44
|
+
for (var _i = 0, _a = Object.values(constants_1.KIND); _i < _a.length; _i++) {
|
|
45
|
+
var k = _a[_i];
|
|
46
|
+
if (k == constants_1.KIND.BACK)
|
|
47
|
+
continue;
|
|
48
|
+
for (var n = 1; n < hand.getArrayLen(k); n++) {
|
|
49
|
+
if (hand.get(k, n) >= 4)
|
|
50
|
+
continue;
|
|
51
|
+
var t = new parser_1.Tile(k, n);
|
|
52
|
+
var tiles = hand.inc([t]);
|
|
53
|
+
var s = new calculator_1.ShantenCalculator(hand).calc();
|
|
54
|
+
hand.dec(tiles);
|
|
55
|
+
if (s < r) {
|
|
56
|
+
r = s;
|
|
57
|
+
candidates = [t];
|
|
58
|
+
}
|
|
59
|
+
else if (s == r)
|
|
60
|
+
candidates.push(t);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return {
|
|
64
|
+
shanten: r,
|
|
65
|
+
candidates: candidates,
|
|
66
|
+
};
|
|
67
|
+
};
|
|
68
|
+
return Efficiency;
|
|
69
|
+
}());
|
|
70
|
+
exports.Efficiency = Efficiency;
|
|
71
|
+
var weight = function (t, doras) {
|
|
72
|
+
var base = 1;
|
|
73
|
+
var v = base;
|
|
74
|
+
for (var _i = 0, doras_1 = doras; _i < doras_1.length; _i++) {
|
|
75
|
+
var d = doras_1[_i];
|
|
76
|
+
if (d.equals(t, true))
|
|
77
|
+
v *= 2;
|
|
78
|
+
}
|
|
79
|
+
return v;
|
|
80
|
+
};
|
|
81
|
+
var PlayerEfficiency = (function () {
|
|
82
|
+
function PlayerEfficiency() {
|
|
83
|
+
}
|
|
84
|
+
PlayerEfficiency.calcPlayerCandidates = function (counter, candidates) {
|
|
85
|
+
var playerCandidates = [];
|
|
86
|
+
for (var _i = 0, candidates_1 = candidates; _i < candidates_1.length; _i++) {
|
|
87
|
+
var s = candidates_1[_i];
|
|
88
|
+
var sum = 0;
|
|
89
|
+
var pairs = [];
|
|
90
|
+
for (var _a = 0, _b = s.candidates; _a < _b.length; _a++) {
|
|
91
|
+
var c = _b[_a];
|
|
92
|
+
pairs.push({
|
|
93
|
+
tile: c.clone(),
|
|
94
|
+
n: counter.get(c),
|
|
95
|
+
});
|
|
96
|
+
sum += counter.get(c);
|
|
97
|
+
}
|
|
98
|
+
playerCandidates.push({
|
|
99
|
+
sum: sum,
|
|
100
|
+
tile: s.tile,
|
|
101
|
+
candidates: pairs,
|
|
102
|
+
shanten: s.shanten,
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
return playerCandidates;
|
|
106
|
+
};
|
|
107
|
+
PlayerEfficiency.selectMinPriority = function (c, playerCandidates, doras) {
|
|
108
|
+
(0, assert_1.default)(playerCandidates.length > 0);
|
|
109
|
+
var min = 0;
|
|
110
|
+
var idx = 0;
|
|
111
|
+
for (var i = 0; i < playerCandidates.length; i++) {
|
|
112
|
+
var p = PlayerEfficiency.calcPriority(c, playerCandidates[i], doras);
|
|
113
|
+
if (p < min) {
|
|
114
|
+
min = p;
|
|
115
|
+
idx = i;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return playerCandidates[idx];
|
|
119
|
+
};
|
|
120
|
+
PlayerEfficiency.calcPriority = function (c, playerCandidate, doras) {
|
|
121
|
+
var tile = playerCandidate.tile;
|
|
122
|
+
var v = 0;
|
|
123
|
+
if (tile.k == constants_1.KIND.Z) {
|
|
124
|
+
v = c.get(tile);
|
|
125
|
+
if (tile.n == 5 || tile.n == 6 || tile.n == 7)
|
|
126
|
+
v *= 2;
|
|
127
|
+
return v * weight(tile, doras);
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
var same = c.get(tile);
|
|
131
|
+
v += same * weight(tile, doras);
|
|
132
|
+
var np1 = c.get(new parser_1.Tile(tile.k, tile.n + 1)), np2 = c.get(new parser_1.Tile(tile.k, tile.n + 2));
|
|
133
|
+
var nm1 = c.get(new parser_1.Tile(tile.k, tile.n - 1)), nm2 = c.get(new parser_1.Tile(tile.k, tile.n - 2));
|
|
134
|
+
var left = tile.n - 2 > 0 ? Math.min(nm1, nm2) : 0;
|
|
135
|
+
var right = tile.n + 2 <= 9 ? Math.min(np1, np2) : 0;
|
|
136
|
+
var cc = tile.n - 1 >= 1 && tile.n + 1 <= 9 ? Math.min(np1, nm1) : 0;
|
|
137
|
+
var centerLeft = Math.max(left, cc);
|
|
138
|
+
var centerRight = Math.max(cc, right);
|
|
139
|
+
v += same * weight(tile, doras);
|
|
140
|
+
v += left * weight(new parser_1.Tile(tile.k, tile.n - 2), doras);
|
|
141
|
+
v += right * weight(new parser_1.Tile(tile.k, tile.n + 2), doras);
|
|
142
|
+
v += centerLeft * weight(new parser_1.Tile(tile.k, tile.n - 1), doras);
|
|
143
|
+
v += centerRight * weight(new parser_1.Tile(tile.k, tile.n + 1), doras);
|
|
144
|
+
if (tile.n == 0)
|
|
145
|
+
v * 2;
|
|
146
|
+
return v;
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
return PlayerEfficiency;
|
|
150
|
+
}());
|
|
151
|
+
exports.PlayerEfficiency = PlayerEfficiency;
|
|
152
|
+
var RiskRank = (function () {
|
|
153
|
+
function RiskRank() {
|
|
154
|
+
}
|
|
155
|
+
RiskRank.selectTile = function (c, targetUsers, tiles) {
|
|
156
|
+
(0, assert_1.default)(targetUsers.length > 0 && tiles.length > 0);
|
|
157
|
+
var ret = tiles[0];
|
|
158
|
+
var min = Number.POSITIVE_INFINITY;
|
|
159
|
+
for (var _i = 0, tiles_1 = tiles; _i < tiles_1.length; _i++) {
|
|
160
|
+
var t = tiles_1[_i];
|
|
161
|
+
var v = RiskRank.rank(c, targetUsers, t);
|
|
162
|
+
if (v < min) {
|
|
163
|
+
ret = t;
|
|
164
|
+
min = v;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return ret;
|
|
168
|
+
};
|
|
169
|
+
RiskRank.rank = function (c, targetUsers, t) {
|
|
170
|
+
var max = 0;
|
|
171
|
+
var f = t.isNum() ? RiskRank.rankN : RiskRank.rankZ;
|
|
172
|
+
for (var _i = 0, targetUsers_1 = targetUsers; _i < targetUsers_1.length; _i++) {
|
|
173
|
+
var targetUser = targetUsers_1[_i];
|
|
174
|
+
var v = f(c, targetUser, t);
|
|
175
|
+
if (max < v)
|
|
176
|
+
max = v;
|
|
177
|
+
}
|
|
178
|
+
return max;
|
|
179
|
+
};
|
|
180
|
+
RiskRank.rankZ = function (c, targetUser, t) {
|
|
181
|
+
if (t.k != constants_1.KIND.Z)
|
|
182
|
+
throw new Error("expected KIND.Z but ".concat(t.toString()));
|
|
183
|
+
if (c.isSafeTile(t.k, t.n, targetUser))
|
|
184
|
+
return 0;
|
|
185
|
+
var remaining = c.get(t);
|
|
186
|
+
return Math.min(remaining, 3);
|
|
187
|
+
};
|
|
188
|
+
RiskRank.rankN = function (c, targetUser, t) {
|
|
189
|
+
if (!t.isNum())
|
|
190
|
+
throw new Error("expected KIND.NUMBER but ".concat(t.toString()));
|
|
191
|
+
var n = t.n;
|
|
192
|
+
var k = t.k;
|
|
193
|
+
if (c.isSafeTile(k, n, targetUser))
|
|
194
|
+
return 0;
|
|
195
|
+
if (n == 1)
|
|
196
|
+
return c.isSafeTile(k, 4, targetUser) ? 3 : 6;
|
|
197
|
+
if (n == 9)
|
|
198
|
+
return c.isSafeTile(k, 6, targetUser) ? 3 : 6;
|
|
199
|
+
if (n == 2)
|
|
200
|
+
return c.isSafeTile(k, 5, targetUser) ? 4 : 8;
|
|
201
|
+
if (n == 8)
|
|
202
|
+
return c.isSafeTile(k, 5, targetUser) ? 4 : 8;
|
|
203
|
+
if (n == 3)
|
|
204
|
+
return c.isSafeTile(k, 6, targetUser) ? 5 : 8;
|
|
205
|
+
if (n == 7)
|
|
206
|
+
return c.isSafeTile(k, 4, targetUser) ? 5 : 8;
|
|
207
|
+
var left = c.isSafeTile(k, n - 3, targetUser);
|
|
208
|
+
var right = c.isSafeTile(k, n + 3, targetUser);
|
|
209
|
+
if (left && right)
|
|
210
|
+
return 4;
|
|
211
|
+
if (left || right)
|
|
212
|
+
return 8;
|
|
213
|
+
return 12;
|
|
214
|
+
};
|
|
215
|
+
return RiskRank;
|
|
216
|
+
}());
|
|
217
|
+
exports.RiskRank = RiskRank;
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import { Wind, Round } from "../constants";
|
|
2
|
+
import { BlockAnKan, BlockChi, BlockDaiKan, BlockPon, BlockShoKan, Tile } from "../parser";
|
|
3
|
+
import { Candidate } from "./";
|
|
4
|
+
import { WinResult } from "../calculator";
|
|
5
|
+
type Event = CallEvent | "DRAW" | "CHOICE_AFTER_DRAWN" | "CHOICE_AFTER_DISCARDED" | "CHOICE_AFTER_CALLED" | "CHOICE_FOR_CHAN_KAN" | "DISTRIBUTE" | "NEW_DORA" | "END_GAME";
|
|
6
|
+
type ChoiceEvent = "PON" | "CHI" | "RON" | "DISCARD" | "TSUMO" | "REACH" | "AN_KAN" | "SHO_KAN" | "DAI_KAN" | "DRAWN_GAME_BY_NINE_TILES";
|
|
7
|
+
export interface DistributeEvent {
|
|
8
|
+
id: string;
|
|
9
|
+
type: Extract<Event, "DISTRIBUTE">;
|
|
10
|
+
hands: {
|
|
11
|
+
[key in Wind]: string;
|
|
12
|
+
};
|
|
13
|
+
wind: Wind;
|
|
14
|
+
doraMarker: Tile;
|
|
15
|
+
players: string[];
|
|
16
|
+
places: {
|
|
17
|
+
[key: string]: Wind;
|
|
18
|
+
};
|
|
19
|
+
sticks: {
|
|
20
|
+
reach: number;
|
|
21
|
+
dead: number;
|
|
22
|
+
};
|
|
23
|
+
round: Round;
|
|
24
|
+
scores: {
|
|
25
|
+
[key: string]: number;
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
export interface EndEvent {
|
|
29
|
+
id: string;
|
|
30
|
+
type: Extract<Event, "END_GAME">;
|
|
31
|
+
subType: "WIN_GAME" | "DRAWN_GAME" | "FOUR_KAN" | "FOUR_WIND" | "NINE_TILES";
|
|
32
|
+
wind: Wind;
|
|
33
|
+
scores: {
|
|
34
|
+
[key: string]: number;
|
|
35
|
+
};
|
|
36
|
+
sticks: {
|
|
37
|
+
reach: number;
|
|
38
|
+
dead: number;
|
|
39
|
+
};
|
|
40
|
+
deltas: {
|
|
41
|
+
[key in Wind]: number;
|
|
42
|
+
};
|
|
43
|
+
hands: {
|
|
44
|
+
[key in Wind]: string;
|
|
45
|
+
};
|
|
46
|
+
shouldContinue: boolean;
|
|
47
|
+
}
|
|
48
|
+
export interface CallEvent {
|
|
49
|
+
id: string;
|
|
50
|
+
type: Extract<ChoiceEvent, "PON" | "CHI" | "AN_KAN" | "SHO_KAN" | "DAI_KAN">;
|
|
51
|
+
iam: Wind;
|
|
52
|
+
wind: Wind;
|
|
53
|
+
block: BlockPon | BlockChi | BlockAnKan | BlockShoKan | BlockDaiKan;
|
|
54
|
+
}
|
|
55
|
+
export interface RonEvent {
|
|
56
|
+
id: string;
|
|
57
|
+
type: Extract<ChoiceEvent, "RON">;
|
|
58
|
+
iam: Wind;
|
|
59
|
+
wind: Wind;
|
|
60
|
+
ret: WinResult;
|
|
61
|
+
targetInfo: {
|
|
62
|
+
wind: Wind;
|
|
63
|
+
tile: Tile;
|
|
64
|
+
};
|
|
65
|
+
pushBackReachStick: boolean;
|
|
66
|
+
}
|
|
67
|
+
export interface TsumoEvent {
|
|
68
|
+
id: string;
|
|
69
|
+
type: Extract<ChoiceEvent, "TSUMO">;
|
|
70
|
+
iam: Wind;
|
|
71
|
+
wind: Wind;
|
|
72
|
+
lastTile: Tile;
|
|
73
|
+
ret: WinResult;
|
|
74
|
+
}
|
|
75
|
+
export interface DiscardEvent {
|
|
76
|
+
id: string;
|
|
77
|
+
type: Extract<ChoiceEvent, "DISCARD">;
|
|
78
|
+
iam: Wind;
|
|
79
|
+
wind: Wind;
|
|
80
|
+
tile: Tile;
|
|
81
|
+
}
|
|
82
|
+
export interface DrawEvent {
|
|
83
|
+
id: string;
|
|
84
|
+
type: Extract<Event, "DRAW">;
|
|
85
|
+
subtype?: "kan";
|
|
86
|
+
iam: Wind;
|
|
87
|
+
wind: Wind;
|
|
88
|
+
tile: Tile;
|
|
89
|
+
}
|
|
90
|
+
export interface ReachEvent {
|
|
91
|
+
id: string;
|
|
92
|
+
type: Extract<ChoiceEvent, "REACH">;
|
|
93
|
+
tile: Tile;
|
|
94
|
+
iam: Wind;
|
|
95
|
+
wind: Wind;
|
|
96
|
+
}
|
|
97
|
+
export interface NewDoraEvent {
|
|
98
|
+
id: string;
|
|
99
|
+
type: Extract<Event, "NEW_DORA">;
|
|
100
|
+
doraMarker: Tile;
|
|
101
|
+
wind: Wind;
|
|
102
|
+
}
|
|
103
|
+
export interface ChoiceAfterDrawnEvent {
|
|
104
|
+
id: string;
|
|
105
|
+
type: Extract<Event, "CHOICE_AFTER_DRAWN">;
|
|
106
|
+
wind: Wind;
|
|
107
|
+
tileInfo: {
|
|
108
|
+
wind: Wind;
|
|
109
|
+
tile: Tile;
|
|
110
|
+
};
|
|
111
|
+
choices: DrawnChoice;
|
|
112
|
+
}
|
|
113
|
+
export interface ChoiceAfterDiscardedEvent {
|
|
114
|
+
id: string;
|
|
115
|
+
type: Extract<Event, "CHOICE_AFTER_DISCARDED">;
|
|
116
|
+
wind: Wind;
|
|
117
|
+
tileInfo: {
|
|
118
|
+
wind: Wind;
|
|
119
|
+
tile: Tile;
|
|
120
|
+
};
|
|
121
|
+
choices: DiscardedChoice;
|
|
122
|
+
}
|
|
123
|
+
export interface ChoiceAfterCalled {
|
|
124
|
+
id: string;
|
|
125
|
+
type: Extract<Event, "CHOICE_AFTER_CALLED">;
|
|
126
|
+
wind: Wind;
|
|
127
|
+
choices: Pick<DrawnChoice, "DISCARD">;
|
|
128
|
+
}
|
|
129
|
+
export interface ChoiceForChanKan {
|
|
130
|
+
id: string;
|
|
131
|
+
type: Extract<Event, "CHOICE_FOR_CHAN_KAN">;
|
|
132
|
+
wind: Wind;
|
|
133
|
+
tileInfo: {
|
|
134
|
+
wind: Wind;
|
|
135
|
+
tile: Tile;
|
|
136
|
+
};
|
|
137
|
+
choices: Pick<DiscardedChoice, "RON">;
|
|
138
|
+
}
|
|
139
|
+
export type PlayerEvent = DistributeEvent | EndEvent | CallEvent | RonEvent | TsumoEvent | DiscardEvent | DrawEvent | ReachEvent | NewDoraEvent | ChoiceAfterDrawnEvent | ChoiceAfterDiscardedEvent | ChoiceAfterCalled | ChoiceForChanKan;
|
|
140
|
+
interface DiscardedChoice {
|
|
141
|
+
RON: false | WinResult;
|
|
142
|
+
PON: false | BlockPon[];
|
|
143
|
+
CHI: false | BlockChi[];
|
|
144
|
+
DAI_KAN: false | BlockDaiKan;
|
|
145
|
+
}
|
|
146
|
+
interface DrawnChoice {
|
|
147
|
+
TSUMO: false | WinResult;
|
|
148
|
+
REACH: false | Candidate[];
|
|
149
|
+
AN_KAN: false | BlockAnKan[];
|
|
150
|
+
SHO_KAN: false | BlockShoKan[];
|
|
151
|
+
DISCARD: false | Tile[];
|
|
152
|
+
DRAWN_GAME_BY_NINE_TILES: boolean;
|
|
153
|
+
}
|
|
154
|
+
export declare function prioritizeDiscardedEvents(events: ChoiceAfterDiscardedEvent[]): {
|
|
155
|
+
events: ChoiceAfterDiscardedEvent[];
|
|
156
|
+
type: boolean | keyof DiscardedChoice;
|
|
157
|
+
};
|
|
158
|
+
export declare function prioritizeDrawnEvents(events: ChoiceAfterDrawnEvent[]): {
|
|
159
|
+
events: ChoiceAfterDrawnEvent[];
|
|
160
|
+
type: boolean | keyof DrawnChoice;
|
|
161
|
+
};
|
|
162
|
+
export interface EventHandler {
|
|
163
|
+
emit(e: PlayerEvent): void;
|
|
164
|
+
on(handler: EventHandlerFunc): void;
|
|
165
|
+
}
|
|
166
|
+
export type EventHandlerFunc = (e: PlayerEvent) => void;
|
|
167
|
+
export declare const createEventPipe: () => [EventHandler, EventHandler];
|
|
168
|
+
export declare const createEventEmitter: () => {
|
|
169
|
+
emit: (e: PlayerEvent) => void;
|
|
170
|
+
on: (h: EventHandlerFunc) => void;
|
|
171
|
+
};
|
|
172
|
+
export {};
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createEventEmitter = exports.createEventPipe = exports.prioritizeDrawnEvents = exports.prioritizeDiscardedEvents = void 0;
|
|
4
|
+
var eventmit_1 = require("eventmit");
|
|
5
|
+
function prioritizeDiscardedEvents(events) {
|
|
6
|
+
var _a;
|
|
7
|
+
var order = ["RON", "DAI_KAN", "PON", "CHI"];
|
|
8
|
+
var choices = events.map(function (e) { return e.choices; });
|
|
9
|
+
var indexes = prioritizeEvents(choices, order);
|
|
10
|
+
var selected = indexes.map(function (idx) { return events[idx]; });
|
|
11
|
+
return {
|
|
12
|
+
events: selected,
|
|
13
|
+
type: priorityIndex(order, (_a = selected[0]) === null || _a === void 0 ? void 0 : _a.choices),
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
exports.prioritizeDiscardedEvents = prioritizeDiscardedEvents;
|
|
17
|
+
function prioritizeDrawnEvents(events) {
|
|
18
|
+
var _a;
|
|
19
|
+
var order = [
|
|
20
|
+
"TSUMO",
|
|
21
|
+
"REACH",
|
|
22
|
+
"AN_KAN",
|
|
23
|
+
"SHO_KAN",
|
|
24
|
+
"DRAWN_GAME_BY_NINE_TILES",
|
|
25
|
+
"DISCARD",
|
|
26
|
+
];
|
|
27
|
+
var choices = events.map(function (e) { return e.choices; });
|
|
28
|
+
var indexes = prioritizeEvents(choices, order);
|
|
29
|
+
var selected = indexes.map(function (idx) { return events[idx]; });
|
|
30
|
+
return {
|
|
31
|
+
events: selected,
|
|
32
|
+
type: priorityIndex(order, (_a = selected[0]) === null || _a === void 0 ? void 0 : _a.choices),
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
exports.prioritizeDrawnEvents = prioritizeDrawnEvents;
|
|
36
|
+
function prioritizeEvents(choices, order) {
|
|
37
|
+
var highestPriorityIndices = [];
|
|
38
|
+
var highestPriority = Number.POSITIVE_INFINITY;
|
|
39
|
+
for (var i = 0; i < choices.length; i++) {
|
|
40
|
+
var choice = choices[i];
|
|
41
|
+
if (hasChoices(choice, order)) {
|
|
42
|
+
var priority = calculatePriority(order, choice);
|
|
43
|
+
if (priority < highestPriority) {
|
|
44
|
+
highestPriority = priority;
|
|
45
|
+
highestPriorityIndices = [i];
|
|
46
|
+
}
|
|
47
|
+
else if (priority === highestPriority) {
|
|
48
|
+
highestPriorityIndices.push(i);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return highestPriorityIndices;
|
|
53
|
+
}
|
|
54
|
+
function hasChoices(choice, order) {
|
|
55
|
+
return order.some(function (v) { return !!choice[v]; });
|
|
56
|
+
}
|
|
57
|
+
function calculatePriority(order, choice) {
|
|
58
|
+
for (var i = 0; i < order.length; i++) {
|
|
59
|
+
var key = order[i];
|
|
60
|
+
if (!!choice[key])
|
|
61
|
+
return i;
|
|
62
|
+
}
|
|
63
|
+
return Number.POSITIVE_INFINITY;
|
|
64
|
+
}
|
|
65
|
+
function priorityIndex(order, choice) {
|
|
66
|
+
if (choice == null)
|
|
67
|
+
return false;
|
|
68
|
+
for (var _i = 0, order_1 = order; _i < order_1.length; _i++) {
|
|
69
|
+
var key = order_1[_i];
|
|
70
|
+
if (!!choice[key])
|
|
71
|
+
return key;
|
|
72
|
+
}
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
var createEventPipe = function () {
|
|
76
|
+
var e1 = (0, eventmit_1.eventmit)();
|
|
77
|
+
var e2 = (0, eventmit_1.eventmit)();
|
|
78
|
+
var p1 = {
|
|
79
|
+
emit: e1.emit,
|
|
80
|
+
on: function (h) { return e2.on(h); },
|
|
81
|
+
};
|
|
82
|
+
var p2 = {
|
|
83
|
+
emit: e2.emit,
|
|
84
|
+
on: function (h) { return e1.on(h); },
|
|
85
|
+
};
|
|
86
|
+
return [p1, p2];
|
|
87
|
+
};
|
|
88
|
+
exports.createEventPipe = createEventPipe;
|
|
89
|
+
var createEventEmitter = function () {
|
|
90
|
+
var emitter = (0, eventmit_1.eventmit)();
|
|
91
|
+
var emit = function (e) {
|
|
92
|
+
emitter.emit(e);
|
|
93
|
+
};
|
|
94
|
+
var on = function (h) {
|
|
95
|
+
emitter.on(h);
|
|
96
|
+
};
|
|
97
|
+
return {
|
|
98
|
+
emit: emit,
|
|
99
|
+
on: on,
|
|
100
|
+
};
|
|
101
|
+
};
|
|
102
|
+
exports.createEventEmitter = createEventEmitter;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createLocalGame = void 0;
|
|
4
|
+
var controller_1 = require("../controller");
|
|
5
|
+
var createLocalGame = function (params) {
|
|
6
|
+
var _a;
|
|
7
|
+
var _b = (0, controller_1.createEventPipe)(), ce1 = _b[0], pe1 = _b[1];
|
|
8
|
+
var _c = (0, controller_1.createEventPipe)(), ce2 = _c[0], pe2 = _c[1];
|
|
9
|
+
var _d = (0, controller_1.createEventPipe)(), ce3 = _d[0], pe3 = _d[1];
|
|
10
|
+
var _e = (0, controller_1.createEventPipe)(), ce4 = _e[0], pe4 = _e[1];
|
|
11
|
+
var playerIDs = (_a = params === null || params === void 0 ? void 0 : params.playerIDs) !== null && _a !== void 0 ? _a : [
|
|
12
|
+
"player-1",
|
|
13
|
+
"player-2",
|
|
14
|
+
"player-3",
|
|
15
|
+
"player-4",
|
|
16
|
+
];
|
|
17
|
+
new controller_1.Player(playerIDs[0], pe1);
|
|
18
|
+
new controller_1.Player(playerIDs[1], pe2);
|
|
19
|
+
new controller_1.Player(playerIDs[2], pe3);
|
|
20
|
+
new controller_1.Player(playerIDs[3], pe4);
|
|
21
|
+
var players = [
|
|
22
|
+
{ handler: ce1, id: playerIDs[0] },
|
|
23
|
+
{ handler: ce2, id: playerIDs[1] },
|
|
24
|
+
{ handler: ce3, id: playerIDs[2] },
|
|
25
|
+
{ handler: ce4, id: playerIDs[3] },
|
|
26
|
+
];
|
|
27
|
+
return new controller_1.Controller(players, { debug: params === null || params === void 0 ? void 0 : params.debug });
|
|
28
|
+
};
|
|
29
|
+
exports.createLocalGame = createLocalGame;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export * from "./events";
|
|
2
|
+
export * from "./managers";
|
|
3
|
+
export * from "./river";
|
|
4
|
+
export * from "./state-machine";
|
|
5
|
+
export * from "./wall";
|
|
6
|
+
export * from "./controller";
|
|
7
|
+
export * from "./player";
|
|
8
|
+
export * from "./replay";
|
|
9
|
+
export * from "./game";
|
|
10
|
+
export * from "./efficiency";
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./events"), exports);
|
|
18
|
+
__exportStar(require("./managers"), exports);
|
|
19
|
+
__exportStar(require("./river"), exports);
|
|
20
|
+
__exportStar(require("./state-machine"), exports);
|
|
21
|
+
__exportStar(require("./wall"), exports);
|
|
22
|
+
__exportStar(require("./controller"), exports);
|
|
23
|
+
__exportStar(require("./player"), exports);
|
|
24
|
+
__exportStar(require("./replay"), exports);
|
|
25
|
+
__exportStar(require("./game"), exports);
|
|
26
|
+
__exportStar(require("./efficiency"), exports);
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { Wind, Round } from "../constants";
|
|
2
|
+
import { Kind, Tile } from "../parser";
|
|
3
|
+
export declare class ScoreManager {
|
|
4
|
+
private reachValue;
|
|
5
|
+
private m;
|
|
6
|
+
constructor(initial: {
|
|
7
|
+
[key: string]: number;
|
|
8
|
+
});
|
|
9
|
+
get summary(): {
|
|
10
|
+
[key: string]: number;
|
|
11
|
+
};
|
|
12
|
+
reach(id: string): void;
|
|
13
|
+
restoreReachStick(id: string): void;
|
|
14
|
+
update(result: {
|
|
15
|
+
"1w": number;
|
|
16
|
+
"2w": number;
|
|
17
|
+
"3w": number;
|
|
18
|
+
"4w": number;
|
|
19
|
+
}, windMap: {
|
|
20
|
+
[key: string]: Wind;
|
|
21
|
+
}): void;
|
|
22
|
+
}
|
|
23
|
+
export declare class PlaceManager {
|
|
24
|
+
private pToW;
|
|
25
|
+
private wToP;
|
|
26
|
+
round: Round;
|
|
27
|
+
sticks: {
|
|
28
|
+
reach: number;
|
|
29
|
+
dead: number;
|
|
30
|
+
};
|
|
31
|
+
constructor(initial: {
|
|
32
|
+
[key: string]: Wind;
|
|
33
|
+
}, params?: {
|
|
34
|
+
round: Round;
|
|
35
|
+
sticks: {
|
|
36
|
+
reach: number;
|
|
37
|
+
dead: number;
|
|
38
|
+
};
|
|
39
|
+
});
|
|
40
|
+
private update;
|
|
41
|
+
incrementDeadStick(): void;
|
|
42
|
+
incrementReachStick(): void;
|
|
43
|
+
nextRound(): void;
|
|
44
|
+
decrementReachStick(): void;
|
|
45
|
+
resetDeadStick(): void;
|
|
46
|
+
resetReachStick(): void;
|
|
47
|
+
is(r: Round): boolean;
|
|
48
|
+
wind(id: string): "1w" | "2w" | "3w" | "4w";
|
|
49
|
+
playerID(w: Wind): string;
|
|
50
|
+
get playerMap(): {
|
|
51
|
+
[key: string]: "1w" | "2w" | "3w" | "4w";
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
export declare const nextRound: (r: Round) => "1w1" | "1w2" | "1w3" | "1w4" | "2w1" | "2w2" | "2w3" | "2w4" | "3w1" | "3w2" | "3w3" | "3w4" | "4w1" | "4w2" | "4w3" | "4w4";
|
|
55
|
+
export declare const prevRound: (r: Round) => "1w1" | "1w2" | "1w3" | "1w4" | "2w1" | "2w2" | "2w3" | "2w4" | "3w1" | "3w2" | "3w3" | "3w4" | "4w1" | "4w2" | "4w3" | "4w4";
|
|
56
|
+
export declare const nextWind: (w: Wind) => Wind;
|
|
57
|
+
export declare const prevWind: (w: Wind) => Wind;
|
|
58
|
+
export declare function createWindMap<T>(initial: T, clone?: boolean): {
|
|
59
|
+
"1w": T;
|
|
60
|
+
"2w": T;
|
|
61
|
+
"3w": T;
|
|
62
|
+
"4w": T;
|
|
63
|
+
};
|
|
64
|
+
export declare function shuffle<T>(array: T[]): T[];
|
|
65
|
+
export declare class Counter {
|
|
66
|
+
disable: boolean;
|
|
67
|
+
private c;
|
|
68
|
+
safeMap: {
|
|
69
|
+
"1w": {
|
|
70
|
+
[name: string]: boolean;
|
|
71
|
+
};
|
|
72
|
+
"2w": {
|
|
73
|
+
[name: string]: boolean;
|
|
74
|
+
};
|
|
75
|
+
"3w": {
|
|
76
|
+
[name: string]: boolean;
|
|
77
|
+
};
|
|
78
|
+
"4w": {
|
|
79
|
+
[name: string]: boolean;
|
|
80
|
+
};
|
|
81
|
+
};
|
|
82
|
+
constructor(disable?: boolean);
|
|
83
|
+
get(t: Tile): number;
|
|
84
|
+
dec(...tiles: Tile[]): void;
|
|
85
|
+
addTileToSafeMap(t: Tile, targetUser: Wind): void;
|
|
86
|
+
isSafeTile(k: Kind, n: number, targetUser: Wind): boolean;
|
|
87
|
+
private key;
|
|
88
|
+
reset(): void;
|
|
89
|
+
}
|