From c964c49c587cc3f795060cc9074c5a1eec2f7eec Mon Sep 17 00:00:00 2001 From: syuilo Date: Thu, 1 Feb 2024 20:34:05 +0900 Subject: [PATCH] wip --- packages/backend/src/core/MahjongService.ts | 22 +++++++++- packages/misskey-mahjong/src/engine.master.ts | 42 +++++++++++++++++-- packages/misskey-mahjong/src/utils.ts | 2 +- 3 files changed, 59 insertions(+), 7 deletions(-) diff --git a/packages/backend/src/core/MahjongService.ts b/packages/backend/src/core/MahjongService.ts index a1264b7e29..fd7e5c0c48 100644 --- a/packages/backend/src/core/MahjongService.ts +++ b/packages/backend/src/core/MahjongService.ts @@ -511,6 +511,24 @@ export class MahjongService implements OnApplicationShutdown, OnModuleInit { await this.dahai(room, engine, myHouse, tile, riichi); } + @bindThis + public async commit_ankan(roomId: MiMahjongGame['id'], user: MiUser, tile: string) { + const room = await this.getRoom(roomId); + if (room == null) return; + if (room.gameState == null) return; + + const engine = new Mahjong.MasterGameEngine(room.gameState); + const myHouse = getHouseOfUserId(room, engine, user.id); + + await this.clearTurnWaitingTimer(room.id); + + const res = engine.commit_ankan(myHouse, tile); + + this.globalEventService.publishMahjongRoomStream(room.id, 'ankanned', { }); + + this.waitForTurn(room, myHouse, engine); + } + @bindThis public async commit_kakan(roomId: MiMahjongGame['id'], user: MiUser) { const room = await this.getRoom(roomId); @@ -599,7 +617,7 @@ export class MahjongService implements OnApplicationShutdown, OnModuleInit { } /** - * プレイヤーの行動(打牌、加槓、ツモ和了)を待つ + * プレイヤーの行動(打牌、加槓、暗槓、ツモ和了)を待つ * 制限時間が過ぎたらツモ切り * NOTE: 時間切れチェックが行われたときにタイミングによっては次のwaitingが始まっている場合があることを考慮し、Setに一意のIDを格納する構造としている * @param room @@ -642,7 +660,7 @@ export class MahjongService implements OnApplicationShutdown, OnModuleInit { } /** - * プレイヤーが行動(打牌、加槓、ツモ和了)したら呼ぶ + * プレイヤーが行動(打牌、加槓、暗槓、ツモ和了)したら呼ぶ * @param roomId */ @bindThis diff --git a/packages/misskey-mahjong/src/engine.master.ts b/packages/misskey-mahjong/src/engine.master.ts index d86a4d7f28..8f331a1f3d 100644 --- a/packages/misskey-mahjong/src/engine.master.ts +++ b/packages/misskey-mahjong/src/engine.master.ts @@ -213,6 +213,10 @@ export class MasterGameEngine { return this.state.handTiles[house].filter(t => t === tile).length === 2; } + private canCii(house: House, tile: Tile): boolean { + // TODO + } + public getHouse(index: 1 | 2 | 3 | 4): House { switch (index) { case 1: return this.state.user1House; @@ -376,7 +380,35 @@ export class MasterGameEngine { }; } - public commit_kakan(house: House) { + public commit_kakan(house: House, tile: Tile) { + const pon = this.state.huros[house].find(h => h.type === 'pon' && h.tile === tile); + if (pon == null) throw new Error('No such pon'); + this.state.handTiles[house].splice(this.state.handTiles[house].indexOf(tile), 1); + this.state.huros[house].push({ type: 'minkan', tile, from: pon.from }); + + this.state.activatedDorasCount++; + + const rinsyan = this.tsumo(); + + return { + rinsyan, + }; + } + + public commit_ankan(house: House, tile: Tile) { + this.state.handTiles[house].splice(this.state.handTiles[house].indexOf(tile), 1); + this.state.handTiles[house].splice(this.state.handTiles[house].indexOf(tile), 1); + this.state.handTiles[house].splice(this.state.handTiles[house].indexOf(tile), 1); + this.state.handTiles[house].splice(this.state.handTiles[house].indexOf(tile), 1); + this.state.huros[house].push({ type: 'ankan', tile }); + + this.state.activatedDorasCount++; + + const rinsyan = this.tsumo(); + + return { + rinsyan, + }; } /** @@ -408,7 +440,7 @@ export class MasterGameEngine { public commit_resolveCallAndRonInterruption(answers: { pon: boolean; - cii: boolean; + cii: false | [Tile, Tile]; kan: boolean; ron: House[]; }) { @@ -467,14 +499,16 @@ export class MasterGameEngine { }; } else if (cii != null && answers.cii) { const tile = this.state.hoTiles[cii.callee].pop()!; - this.state.huros[cii.caller].push({ type: 'cii', tile, from: cii.callee }); + this.state.handTiles[cii.caller].splice(this.state.handTiles[cii.caller].indexOf(answers.cii[0]), 1); + this.state.handTiles[cii.caller].splice(this.state.handTiles[cii.caller].indexOf(answers.cii[1]), 1); + this.state.huros[cii.caller].push({ type: 'cii', tiles: [tile, answers.cii[0], answers.cii[1]], from: cii.callee }); this.state.turn = cii.caller; return { type: 'ciied' as const, caller: cii.caller, callee: cii.callee, - tile, + tiles: [tile, answers.cii[0], answers.cii[1]], turn: this.state.turn, }; } else if (this.state.tiles.length === 0) { diff --git a/packages/misskey-mahjong/src/utils.ts b/packages/misskey-mahjong/src/utils.ts index 54af6937e5..5e356b06fd 100644 --- a/packages/misskey-mahjong/src/utils.ts +++ b/packages/misskey-mahjong/src/utils.ts @@ -43,7 +43,7 @@ type HoraSet = { mentsus: [Tile, Tile, Tile][]; }; -const SHUNTU_PATTERNS: [Tile, Tile, Tile][] = [ +export const SHUNTU_PATTERNS: [Tile, Tile, Tile][] = [ ['m1', 'm2', 'm3'], ['m2', 'm3', 'm4'], ['m3', 'm4', 'm5'],