diff --git a/packages/backend/src/core/GlobalEventService.ts b/packages/backend/src/core/GlobalEventService.ts
index 8a59320a84..b89b0d94c3 100644
--- a/packages/backend/src/core/GlobalEventService.ts
+++ b/packages/backend/src/core/GlobalEventService.ts
@@ -234,7 +234,7 @@ export interface MahjongRoomEventTypes {
};
ronned: {
};
- hora: {
+ tsumoHora: {
};
}
//#endregion
diff --git a/packages/backend/src/core/MahjongService.ts b/packages/backend/src/core/MahjongService.ts
index b862e2404e..a1264b7e29 100644
--- a/packages/backend/src/core/MahjongService.ts
+++ b/packages/backend/src/core/MahjongService.ts
@@ -528,7 +528,7 @@ export class MahjongService implements OnApplicationShutdown, OnModuleInit {
}
@bindThis
- public async commit_hora(roomId: MiMahjongGame['id'], user: MiUser) {
+ public async commit_tsumoHora(roomId: MiMahjongGame['id'], user: MiUser) {
const room = await this.getRoom(roomId);
if (room == null) return;
if (room.gameState == null) return;
@@ -538,13 +538,13 @@ export class MahjongService implements OnApplicationShutdown, OnModuleInit {
await this.clearTurnWaitingTimer(room.id);
- const res = engine.commit_hora(myHouse);
+ const res = engine.commit_tsumoHora(myHouse);
- this.globalEventService.publishMahjongRoomStream(room.id, 'horad', { });
+ this.globalEventService.publishMahjongRoomStream(room.id, 'tsumoHora', { });
}
@bindThis
- public async commit_ron(roomId: MiMahjongGame['id'], user: MiUser) {
+ public async commit_ronHora(roomId: MiMahjongGame['id'], user: MiUser) {
const room = await this.getRoom(roomId);
if (room == null) return;
if (room.gameState == null) return;
diff --git a/packages/backend/src/server/api/stream/channels/mahjong-room.ts b/packages/backend/src/server/api/stream/channels/mahjong-room.ts
index 5ac5862063..23e5b3a3d4 100644
--- a/packages/backend/src/server/api/stream/channels/mahjong-room.ts
+++ b/packages/backend/src/server/api/stream/channels/mahjong-room.ts
@@ -53,8 +53,8 @@ class MahjongRoomChannel extends Channel {
case 'addAi': this.addAi(); break;
case 'confirmNextKyoku': this.confirmNextKyoku(); break;
case 'dahai': this.dahai(body.tile, body.riichi); break;
- case 'hora': this.hora(); break;
- case 'ron': this.ron(); break;
+ case 'tsumoHora': this.tsumoHora(); break;
+ case 'ronHora': this.ronHora(); break;
case 'pon': this.pon(); break;
case 'nop': this.nop(); break;
case 'claimTimeIsUp': this.claimTimeIsUp(); break;
@@ -97,17 +97,17 @@ class MahjongRoomChannel extends Channel {
}
@bindThis
- private async hora() {
+ private async tsumoHora() {
if (this.user == null) return;
- this.mahjongService.commit_hora(this.roomId!, this.user);
+ this.mahjongService.commit_tsumoHora(this.roomId!, this.user);
}
@bindThis
- private async ron() {
+ private async ronHora() {
if (this.user == null) return;
- this.mahjongService.commit_ron(this.roomId!, this.user);
+ this.mahjongService.commit_ronHora(this.roomId!, this.user);
}
@bindThis
diff --git a/packages/frontend/src/pages/mahjong/room.game.vue b/packages/frontend/src/pages/mahjong/room.game.vue
index 55fb295117..6deea07465 100644
--- a/packages/frontend/src/pages/mahjong/room.game.vue
+++ b/packages/frontend/src/pages/mahjong/room.game.vue
@@ -149,7 +149,7 @@ SPDX-License-Identifier: AGPL-3.0-only
Ron
Pon
Skip
- Tsumo
+ Tsumo
Riichi
@@ -309,15 +309,15 @@ function kakan() {
});
}
-function hora() {
+function tsumoHora() {
if (!isMyTurn.value) return;
- props.connection!.send('hora', {
+ props.connection!.send('tsumoHora', {
});
}
function ron() {
- props.connection!.send('ron', {
+ props.connection!.send('ronHora', {
});
}
@@ -439,7 +439,7 @@ function onStreamPonned(log) {
function onStreamRonned(log) {
console.log('onStreamRonned', log);
- engine.value.commit_ron(log.callers, log.callee, log.handTiles);
+ engine.value.commit_ronHora(log.callers, log.callee, log.handTiles);
triggerRef(engine);
for (const caller of log.callers) {
@@ -447,10 +447,13 @@ function onStreamRonned(log) {
}
}
-function onStreamHora(log) {
- console.log('onStreamHora', log);
+function onStreamTsumoHora(log) {
+ console.log('onStreamTsumoHora', log);
tsumoSerifHouses[log.house] = true;
+
+ engine.value.commit_tsumoHora();
+ triggerRef(engine);
}
function restoreRoom(_room) {
@@ -466,7 +469,7 @@ onMounted(() => {
props.connection.on('dahaiAndTsumo', onStreamDahaiAndTsumo);
props.connection.on('ponned', onStreamPonned);
props.connection.on('ronned', onStreamRonned);
- props.connection.on('hora', onStreamHora);
+ props.connection.on('tsumoHora', onStreamTsumoHora);
}
});
@@ -477,7 +480,7 @@ onActivated(() => {
props.connection.on('dahaiAndTsumo', onStreamDahaiAndTsumo);
props.connection.on('ponned', onStreamPonned);
props.connection.on('ronned', onStreamRonned);
- props.connection.on('hora', onStreamHora);
+ props.connection.on('tsumoHora', onStreamTsumoHora);
}
});
@@ -488,7 +491,7 @@ onDeactivated(() => {
props.connection.off('dahaiAndTsumo', onStreamDahaiAndTsumo);
props.connection.off('ponned', onStreamPonned);
props.connection.off('ronned', onStreamRonned);
- props.connection.off('hora', onStreamHora);
+ props.connection.off('tsumoHora', onStreamTsumoHora);
}
});
@@ -499,7 +502,7 @@ onUnmounted(() => {
props.connection.off('dahaiAndTsumo', onStreamDahaiAndTsumo);
props.connection.off('ponned', onStreamPonned);
props.connection.off('ronned', onStreamRonned);
- props.connection.off('hora', onStreamHora);
+ props.connection.off('tsumoHora', onStreamTsumoHora);
}
});
diff --git a/packages/misskey-mahjong/src/common.ts b/packages/misskey-mahjong/src/common.ts
index 5e9ffa2b87..52de43f39b 100644
--- a/packages/misskey-mahjong/src/common.ts
+++ b/packages/misskey-mahjong/src/common.ts
@@ -324,3 +324,39 @@ export function calcOwnedDoraCount(handTiles: Tile[], huros: Huro[], doras: Tile
}
return count;
}
+
+export function calcTsumoHoraPointDeltas(house: House, fans: number): Record {
+ const isParent = house === 'e';
+
+ const deltas: Record = {
+ e: 0,
+ s: 0,
+ w: 0,
+ n: 0,
+ };
+
+ const point = fanToPoint(fans, isParent);
+ deltas[house] = point;
+ if (isParent) {
+ const childPoint = Math.ceil(point / 3);
+ deltas.s = -childPoint;
+ deltas.w = -childPoint;
+ deltas.n = -childPoint;
+ } else {
+ const parentPoint = Math.ceil(point / 2);
+ deltas.e = -parentPoint;
+ const otherPoint = Math.ceil(point / 4);
+ if (house === 's') {
+ deltas.w = -otherPoint;
+ deltas.n = -otherPoint;
+ } else if (house === 'w') {
+ deltas.s = -otherPoint;
+ deltas.n = -otherPoint;
+ } else if (house === 'n') {
+ deltas.s = -otherPoint;
+ deltas.w = -otherPoint;
+ }
+ }
+
+ return deltas;
+}
diff --git a/packages/misskey-mahjong/src/engine.master.ts b/packages/misskey-mahjong/src/engine.master.ts
index 7fbc9bcd69..d86a4d7f28 100644
--- a/packages/misskey-mahjong/src/engine.master.ts
+++ b/packages/misskey-mahjong/src/engine.master.ts
@@ -230,11 +230,11 @@ export class MasterGameEngine {
}
/**
- * ロン
+ * ロン和了
* @param callers ロンする人
* @param callee ロンされる人
*/
- private ron(callers: House[], callee: House) {
+ private ronHora(callers: House[], callee: House) {
for (const house of callers) {
const yakus = YAKU_DEFINITIONS.filter(yaku => yaku.calc({
house: house,
@@ -383,11 +383,9 @@ export class MasterGameEngine {
* ツモ和了
* @param house
*/
- public commit_hora(house: House) {
+ public commit_tsumoHora(house: House) {
if (this.state.turn !== house) throw new Error('Not your turn');
- const isParent = house === 'e';
-
const yakus = YAKU_DEFINITIONS.filter(yaku => yaku.calc({
house: house,
handTiles: this.state.handTiles[house],
@@ -398,29 +396,11 @@ export class MasterGameEngine {
}));
const doraCount = Common.calcOwnedDoraCount(this.state.handTiles[house], this.state.huros[house], this.doras);
const fans = yakus.map(yaku => yaku.fan).reduce((a, b) => a + b, 0) + doraCount;
- const point = Common.fanToPoint(fans, isParent);
- this.state.points[house] += point;
- if (isParent) {
- const childPoint = Math.ceil(point / 3);
- this.state.points.s -= childPoint;
- this.state.points.w -= childPoint;
- this.state.points.n -= childPoint;
- } else {
- const parentPoint = Math.ceil(point / 2);
- this.state.points.e -= parentPoint;
- const otherPoint = Math.ceil(point / 4);
- if (house === 's') {
- this.state.points.w -= otherPoint;
- this.state.points.n -= otherPoint;
- } else if (house === 'w') {
- this.state.points.s -= otherPoint;
- this.state.points.n -= otherPoint;
- } else if (house === 'n') {
- this.state.points.s -= otherPoint;
- this.state.points.w -= otherPoint;
- }
- }
- console.log('fans point', fans, point);
+ const pointDeltas = Common.calcTsumoHoraPointDeltas(house, fans);
+ this.state.points.e += pointDeltas.e;
+ this.state.points.s += pointDeltas.s;
+ this.state.points.w += pointDeltas.w;
+ this.state.points.n += pointDeltas.n;
console.log('yakus', house, yakus);
this.endKyoku();
@@ -445,7 +425,7 @@ export class MasterGameEngine {
this.state.ronAsking = null;
if (ron != null && answers.ron.length > 0) {
- this.ron(answers.ron, ron.callee);
+ this.ronHora(answers.ron, ron.callee);
return {
type: 'ronned' as const,
callers: ron.callers,
diff --git a/packages/misskey-mahjong/src/engine.player.ts b/packages/misskey-mahjong/src/engine.player.ts
index 51babc5832..971fe384b2 100644
--- a/packages/misskey-mahjong/src/engine.player.ts
+++ b/packages/misskey-mahjong/src/engine.player.ts
@@ -146,8 +146,8 @@ export class PlayerGameEngine {
if (this.state.turn !== house) throw new PlayerGameEngine.InvalidOperationError();
}
- public commit_hora(house: House) {
- console.log('commit_hora', this.state.turn, house);
+ public commit_tsumoHora(house: House) {
+ console.log('commit_tsumoHora', this.state.turn, house);
// TODO: ツモした人の手牌情報を貰う必要がある
}
@@ -157,13 +157,13 @@ export class PlayerGameEngine {
* @param callers ロンした人
* @param callee 牌を捨てた人
*/
- public commit_ron(callers: House[], callee: House, handTiles: {
+ public commit_ronHora(callers: House[], callee: House, handTiles: {
e: Tile[];
s: Tile[];
w: Tile[];
n: Tile[];
}) {
- console.log('commit_ron', this.state.turn, callers, callee);
+ console.log('commit_ronHora', this.state.turn, callers, callee);
this.state.canRonSource = null;