wip
This commit is contained in:
parent
2dd886e285
commit
586a458c7a
12 changed files with 424 additions and 149 deletions
210
locales/index.d.ts
vendored
210
locales/index.d.ts
vendored
|
@ -9649,6 +9649,216 @@ export interface Locale extends ILocale {
|
||||||
* 北
|
* 北
|
||||||
*/
|
*/
|
||||||
"north": string;
|
"north": string;
|
||||||
|
/**
|
||||||
|
* ドラ
|
||||||
|
*/
|
||||||
|
"dora": string;
|
||||||
|
/**
|
||||||
|
* 赤ドラ
|
||||||
|
*/
|
||||||
|
"redDora": string;
|
||||||
|
/**
|
||||||
|
* 飜
|
||||||
|
*/
|
||||||
|
"fan": string;
|
||||||
|
"_yakus": {
|
||||||
|
/**
|
||||||
|
* 立直
|
||||||
|
*/
|
||||||
|
"riichi": string;
|
||||||
|
/**
|
||||||
|
* 一発
|
||||||
|
*/
|
||||||
|
"ippatsu": string;
|
||||||
|
/**
|
||||||
|
* 門前清自摸和
|
||||||
|
*/
|
||||||
|
"tsumo": string;
|
||||||
|
/**
|
||||||
|
* 断么
|
||||||
|
*/
|
||||||
|
"tanyao": string;
|
||||||
|
/**
|
||||||
|
* 平和
|
||||||
|
*/
|
||||||
|
"pinfu": string;
|
||||||
|
/**
|
||||||
|
* 一盃口
|
||||||
|
*/
|
||||||
|
"iipeko": string;
|
||||||
|
/**
|
||||||
|
* 東
|
||||||
|
*/
|
||||||
|
"field-wind-e": string;
|
||||||
|
/**
|
||||||
|
* 南
|
||||||
|
*/
|
||||||
|
"field-wind-s": string;
|
||||||
|
/**
|
||||||
|
* 東
|
||||||
|
*/
|
||||||
|
"seat-wind-e": string;
|
||||||
|
/**
|
||||||
|
* 南
|
||||||
|
*/
|
||||||
|
"seat-wind-s": string;
|
||||||
|
/**
|
||||||
|
* 西
|
||||||
|
*/
|
||||||
|
"seat-wind-w": string;
|
||||||
|
/**
|
||||||
|
* 北
|
||||||
|
*/
|
||||||
|
"seat-wind-n": string;
|
||||||
|
/**
|
||||||
|
* 白
|
||||||
|
*/
|
||||||
|
"white": string;
|
||||||
|
/**
|
||||||
|
* 發
|
||||||
|
*/
|
||||||
|
"green": string;
|
||||||
|
/**
|
||||||
|
* 中
|
||||||
|
*/
|
||||||
|
"red": string;
|
||||||
|
/**
|
||||||
|
* 嶺上開花
|
||||||
|
*/
|
||||||
|
"rinshan": string;
|
||||||
|
/**
|
||||||
|
* 搶槓
|
||||||
|
*/
|
||||||
|
"chankan": string;
|
||||||
|
/**
|
||||||
|
* 海底摸月
|
||||||
|
*/
|
||||||
|
"haitei": string;
|
||||||
|
/**
|
||||||
|
* 河底撈魚
|
||||||
|
*/
|
||||||
|
"hotei": string;
|
||||||
|
/**
|
||||||
|
* 三色同順
|
||||||
|
*/
|
||||||
|
"sanshoku-dojun": string;
|
||||||
|
/**
|
||||||
|
* 三色同刻
|
||||||
|
*/
|
||||||
|
"sanshoku-doko": string;
|
||||||
|
/**
|
||||||
|
* 一気通貫
|
||||||
|
*/
|
||||||
|
"ittsu": string;
|
||||||
|
/**
|
||||||
|
* 混全帯么九
|
||||||
|
*/
|
||||||
|
"chanta": string;
|
||||||
|
/**
|
||||||
|
* 七対子
|
||||||
|
*/
|
||||||
|
"chitoitsu": string;
|
||||||
|
/**
|
||||||
|
* 対々
|
||||||
|
*/
|
||||||
|
"toitoi": string;
|
||||||
|
/**
|
||||||
|
* 三暗刻
|
||||||
|
*/
|
||||||
|
"sananko": string;
|
||||||
|
/**
|
||||||
|
* 混老頭
|
||||||
|
*/
|
||||||
|
"honroto": string;
|
||||||
|
/**
|
||||||
|
* 三槓子
|
||||||
|
*/
|
||||||
|
"sankantsu": string;
|
||||||
|
/**
|
||||||
|
* 小三元
|
||||||
|
*/
|
||||||
|
"shosangen": string;
|
||||||
|
/**
|
||||||
|
* ダブル立直
|
||||||
|
*/
|
||||||
|
"double-riichi": string;
|
||||||
|
/**
|
||||||
|
* 混一色
|
||||||
|
*/
|
||||||
|
"honitsu": string;
|
||||||
|
/**
|
||||||
|
* 清全帯么九
|
||||||
|
*/
|
||||||
|
"junchan": string;
|
||||||
|
/**
|
||||||
|
* ニ盃口
|
||||||
|
*/
|
||||||
|
"ryampeko": string;
|
||||||
|
/**
|
||||||
|
* 清一色
|
||||||
|
*/
|
||||||
|
"chinitsu": string;
|
||||||
|
/**
|
||||||
|
* 国士無双
|
||||||
|
*/
|
||||||
|
"kokushi": string;
|
||||||
|
/**
|
||||||
|
* 国士無双13面待ち
|
||||||
|
*/
|
||||||
|
"kokushi-13": string;
|
||||||
|
/**
|
||||||
|
* 四暗刻
|
||||||
|
*/
|
||||||
|
"suanko": string;
|
||||||
|
/**
|
||||||
|
* 四暗刻単騎待ち
|
||||||
|
*/
|
||||||
|
"suanko-tanki": string;
|
||||||
|
/**
|
||||||
|
* 大三元
|
||||||
|
*/
|
||||||
|
"daisangen": string;
|
||||||
|
/**
|
||||||
|
* 字一色
|
||||||
|
*/
|
||||||
|
"tsuiso": string;
|
||||||
|
/**
|
||||||
|
* 小四喜
|
||||||
|
*/
|
||||||
|
"shosushi": string;
|
||||||
|
/**
|
||||||
|
* 大四喜
|
||||||
|
*/
|
||||||
|
"daisushi": string;
|
||||||
|
/**
|
||||||
|
* 緑一色
|
||||||
|
*/
|
||||||
|
"ryuiso": string;
|
||||||
|
/**
|
||||||
|
* 清老頭
|
||||||
|
*/
|
||||||
|
"chinroto": string;
|
||||||
|
/**
|
||||||
|
* 四槓子
|
||||||
|
*/
|
||||||
|
"sukantsu": string;
|
||||||
|
/**
|
||||||
|
* 九蓮宝燈
|
||||||
|
*/
|
||||||
|
"churen": string;
|
||||||
|
/**
|
||||||
|
* 純正九連宝灯
|
||||||
|
*/
|
||||||
|
"pure-churen": string;
|
||||||
|
/**
|
||||||
|
* 天和
|
||||||
|
*/
|
||||||
|
"tenho": string;
|
||||||
|
/**
|
||||||
|
* 地和
|
||||||
|
*/
|
||||||
|
"chiho": string;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
"_offlineScreen": {
|
"_offlineScreen": {
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -2571,6 +2571,59 @@ _mahjong:
|
||||||
south: "南"
|
south: "南"
|
||||||
west: "西"
|
west: "西"
|
||||||
north: "北"
|
north: "北"
|
||||||
|
dora: "ドラ"
|
||||||
|
redDora: "赤ドラ"
|
||||||
|
fan: "飜"
|
||||||
|
_yakus:
|
||||||
|
"riichi": "立直"
|
||||||
|
"ippatsu": "一発"
|
||||||
|
"tsumo": "門前清自摸和"
|
||||||
|
"tanyao": "断么"
|
||||||
|
"pinfu": "平和"
|
||||||
|
"iipeko": "一盃口"
|
||||||
|
"field-wind-e": "東"
|
||||||
|
"field-wind-s": "南"
|
||||||
|
"seat-wind-e": "東"
|
||||||
|
"seat-wind-s": "南"
|
||||||
|
"seat-wind-w": "西"
|
||||||
|
"seat-wind-n": "北"
|
||||||
|
"white": "白"
|
||||||
|
"green": "發"
|
||||||
|
"red": "中"
|
||||||
|
"rinshan": "嶺上開花"
|
||||||
|
"chankan": "搶槓"
|
||||||
|
"haitei": "海底摸月"
|
||||||
|
"hotei": "河底撈魚"
|
||||||
|
"sanshoku-dojun": "三色同順"
|
||||||
|
"sanshoku-doko": "三色同刻"
|
||||||
|
"ittsu": "一気通貫"
|
||||||
|
"chanta": "混全帯么九"
|
||||||
|
"chitoitsu": "七対子"
|
||||||
|
"toitoi": "対々"
|
||||||
|
"sananko": "三暗刻"
|
||||||
|
"honroto": "混老頭"
|
||||||
|
"sankantsu": "三槓子"
|
||||||
|
"shosangen": "小三元"
|
||||||
|
"double-riichi": "ダブル立直"
|
||||||
|
"honitsu": "混一色"
|
||||||
|
"junchan": "清全帯么九"
|
||||||
|
"ryampeko": "ニ盃口"
|
||||||
|
"chinitsu": "清一色"
|
||||||
|
"kokushi": "国士無双"
|
||||||
|
"kokushi-13": "国士無双13面待ち"
|
||||||
|
"suanko": "四暗刻"
|
||||||
|
"suanko-tanki": "四暗刻単騎待ち"
|
||||||
|
"daisangen": "大三元"
|
||||||
|
"tsuiso": "字一色"
|
||||||
|
"shosushi": "小四喜"
|
||||||
|
"daisushi": "大四喜"
|
||||||
|
"ryuiso": "緑一色"
|
||||||
|
"chinroto": "清老頭"
|
||||||
|
"sukantsu": "四槓子"
|
||||||
|
"churen": "九蓮宝燈"
|
||||||
|
"pure-churen": "純正九連宝灯"
|
||||||
|
"tenho": "天和"
|
||||||
|
"chiho": "地和"
|
||||||
|
|
||||||
_offlineScreen:
|
_offlineScreen:
|
||||||
title: "オフライン - サーバーに接続できません"
|
title: "オフライン - サーバーに接続できません"
|
||||||
|
|
|
@ -209,30 +209,30 @@ export interface MahjongRoomEventTypes {
|
||||||
room: Packed<'MahjongRoomDetailed'>;
|
room: Packed<'MahjongRoomDetailed'>;
|
||||||
};
|
};
|
||||||
tsumo: {
|
tsumo: {
|
||||||
house: Mahjong.Common.House;
|
house: Mahjong.House;
|
||||||
tile: Mahjong.Common.Tile;
|
tile: Mahjong.Tile;
|
||||||
};
|
};
|
||||||
dahai: {
|
dahai: {
|
||||||
house: Mahjong.Common.House;
|
house: Mahjong.House;
|
||||||
tile: Mahjong.Common.Tile;
|
tile: Mahjong.Tile;
|
||||||
riichi: boolean;
|
riichi: boolean;
|
||||||
};
|
};
|
||||||
dahaiAndTsumo: {
|
dahaiAndTsumo: {
|
||||||
dahaiHouse: Mahjong.Common.House;
|
dahaiHouse: Mahjong.House;
|
||||||
dahaiTile: Mahjong.Common.Tile;
|
dahaiTile: Mahjong.Tile;
|
||||||
tsumoTile: Mahjong.Common.Tile;
|
tsumoTile: Mahjong.Tile;
|
||||||
riichi: boolean;
|
riichi: boolean;
|
||||||
};
|
};
|
||||||
ponned: {
|
ponned: {
|
||||||
caller: Mahjong.Common.House;
|
caller: Mahjong.House;
|
||||||
callee: Mahjong.Common.House;
|
callee: Mahjong.House;
|
||||||
tile: Mahjong.Common.Tile;
|
tile: Mahjong.Tile;
|
||||||
};
|
};
|
||||||
kanned: {
|
kanned: {
|
||||||
caller: Mahjong.Common.House;
|
caller: Mahjong.House;
|
||||||
callee: Mahjong.Common.House;
|
callee: Mahjong.House;
|
||||||
tile: Mahjong.Common.Tile;
|
tile: Mahjong.Tile;
|
||||||
rinsyan: Mahjong.Common.Tile;
|
rinsyan: Mahjong.Tile;
|
||||||
};
|
};
|
||||||
ronned: {
|
ronned: {
|
||||||
};
|
};
|
||||||
|
|
|
@ -77,11 +77,11 @@ type NextKyokuConfirmation = {
|
||||||
user4: boolean;
|
user4: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
function getUserIdOfHouse(room: Room, engine: Mahjong.MasterGameEngine, house: Mahjong.Common.House): MiUser['id'] {
|
function getUserIdOfHouse(room: Room, engine: Mahjong.MasterGameEngine, house: Mahjong.House): MiUser['id'] {
|
||||||
return engine.state.user1House === house ? room.user1Id : engine.state.user2House === house ? room.user2Id : engine.state.user3House === house ? room.user3Id : room.user4Id;
|
return engine.state.user1House === house ? room.user1Id : engine.state.user2House === house ? room.user2Id : engine.state.user3House === house ? room.user3Id : room.user4Id;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getHouseOfUserId(room: Room, engine: Mahjong.MasterGameEngine, userId: MiUser['id']): Mahjong.Common.House {
|
function getHouseOfUserId(room: Room, engine: Mahjong.MasterGameEngine, userId: MiUser['id']): Mahjong.House {
|
||||||
return userId === room.user1Id ? engine.state.user1House : userId === room.user2Id ? engine.state.user2House : userId === room.user3Id ? engine.state.user3House : engine.state.user4House;
|
return userId === room.user1Id ? engine.state.user1House : userId === room.user2Id ? engine.state.user2House : userId === room.user3Id ? engine.state.user3House : engine.state.user4House;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -310,7 +310,7 @@ export class MahjongService implements OnApplicationShutdown, OnModuleInit {
|
||||||
pon: answers.pon ?? false,
|
pon: answers.pon ?? false,
|
||||||
cii: answers.cii ?? false,
|
cii: answers.cii ?? false,
|
||||||
kan: answers.kan ?? false,
|
kan: answers.kan ?? false,
|
||||||
ron: [...(answers.ron.e ? ['e'] : []), ...(answers.ron.s ? ['s'] : []), ...(answers.ron.w ? ['w'] : []), ...(answers.ron.n ? ['n'] : [])] as Mahjong.Common.House[],
|
ron: [...(answers.ron.e ? ['e'] : []), ...(answers.ron.s ? ['s'] : []), ...(answers.ron.w ? ['w'] : []), ...(answers.ron.n ? ['n'] : [])] as Mahjong.House[],
|
||||||
});
|
});
|
||||||
room.gameState = engine.state;
|
room.gameState = engine.state;
|
||||||
await this.saveRoom(room);
|
await this.saveRoom(room);
|
||||||
|
@ -376,7 +376,7 @@ export class MahjongService implements OnApplicationShutdown, OnModuleInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
private async dahai(room: Room, engine: Mahjong.MasterGameEngine, house: Mahjong.Common.House, tile: Mahjong.Common.Tile, riichi = false) {
|
private async dahai(room: Room, engine: Mahjong.MasterGameEngine, house: Mahjong.House, tile: Mahjong.Tile, riichi = false) {
|
||||||
const res = engine.commit_dahai(house, tile, riichi);
|
const res = engine.commit_dahai(house, tile, riichi);
|
||||||
room.gameState = engine.state;
|
room.gameState = engine.state;
|
||||||
await this.saveRoom(room);
|
await this.saveRoom(room);
|
||||||
|
@ -482,7 +482,7 @@ export class MahjongService implements OnApplicationShutdown, OnModuleInit {
|
||||||
const room = await this.getRoom(roomId);
|
const room = await this.getRoom(roomId);
|
||||||
if (room == null) return;
|
if (room == null) return;
|
||||||
if (room.gameState == null) return;
|
if (room.gameState == null) return;
|
||||||
if (!Mahjong.Common.isTile(tile)) return;
|
if (!Mahjong.isTile(tile)) return;
|
||||||
|
|
||||||
const engine = new Mahjong.MasterGameEngine(room.gameState);
|
const engine = new Mahjong.MasterGameEngine(room.gameState);
|
||||||
const myHouse = getHouseOfUserId(room, engine, user.id);
|
const myHouse = getHouseOfUserId(room, engine, user.id);
|
||||||
|
@ -606,13 +606,13 @@ export class MahjongService implements OnApplicationShutdown, OnModuleInit {
|
||||||
* @param engine
|
* @param engine
|
||||||
*/
|
*/
|
||||||
@bindThis
|
@bindThis
|
||||||
private async waitForTurn(room: Room, house: Mahjong.Common.House, engine: Mahjong.MasterGameEngine) {
|
private async waitForTurn(room: Room, house: Mahjong.House, engine: Mahjong.MasterGameEngine) {
|
||||||
const aiHouses = [[1, room.user1Ai], [2, room.user2Ai], [3, room.user3Ai], [4, room.user4Ai]].filter(([id, ai]) => ai).map(([id, ai]) => engine.getHouse(id));
|
const aiHouses = [[1, room.user1Ai], [2, room.user2Ai], [3, room.user3Ai], [4, room.user4Ai]].filter(([id, ai]) => ai).map(([id, ai]) => engine.getHouse(id));
|
||||||
|
|
||||||
if (engine.state.riichis[house]) {
|
if (engine.state.riichis[house]) {
|
||||||
// リーチ時はアガリ牌でない限りツモ切り
|
// リーチ時はアガリ牌でない限りツモ切り
|
||||||
const handTiles = engine.state.handTiles[house];
|
const handTiles = engine.state.handTiles[house];
|
||||||
const horaSets = Mahjong.Common.getHoraSets(handTiles);
|
const horaSets = Mahjong.getHoraSets(handTiles);
|
||||||
if (horaSets.length === 0) {
|
if (horaSets.length === 0) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.dahai(room, engine, house, handTiles.at(-1));
|
this.dahai(room, engine, house, handTiles.at(-1));
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 5.5 KiB |
Binary file not shown.
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 5.5 KiB |
Binary file not shown.
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 5.5 KiB |
|
@ -34,9 +34,9 @@ import * as Mahjong from 'misskey-mahjong';
|
||||||
import XTile from './tile.vue';
|
import XTile from './tile.vue';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
huro: Mahjong.Common.Huro;
|
huro: Mahjong.Huro;
|
||||||
variation: string;
|
variation: string;
|
||||||
doras: Mahjong.Common.Tile[];
|
doras: Mahjong.Tile[];
|
||||||
}>();
|
}>();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -10,20 +10,20 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<div style="text-align: center;">
|
<div style="text-align: center;">
|
||||||
<div :class="$style.centerPanelTickerToi">
|
<div :class="$style.centerPanelTickerToi">
|
||||||
<div style="position: absolute; left: 10px; bottom: 5px;">
|
<div style="position: absolute; left: 10px; bottom: 5px;">
|
||||||
<span :class="$style.centerPanelHouse">{{ Mahjong.Common.prevHouse(Mahjong.Common.prevHouse(engine.myHouse)) === 'e' ? i18n.ts._mahjong.east : Mahjong.Common.prevHouse(Mahjong.Common.prevHouse(engine.myHouse)) === 's' ? i18n.ts._mahjong.south : Mahjong.Common.prevHouse(Mahjong.Common.prevHouse(engine.myHouse)) === 'w' ? i18n.ts._mahjong.west : i18n.ts._mahjong.north }}</span>
|
<span :class="$style.centerPanelHouse">{{ Mahjong.prevHouse(Mahjong.prevHouse(engine.myHouse)) === 'e' ? i18n.ts._mahjong.east : Mahjong.prevHouse(Mahjong.prevHouse(engine.myHouse)) === 's' ? i18n.ts._mahjong.south : Mahjong.prevHouse(Mahjong.prevHouse(engine.myHouse)) === 'w' ? i18n.ts._mahjong.west : i18n.ts._mahjong.north }}</span>
|
||||||
<span :class="$style.centerPanelPoint">{{ engine.state.points[Mahjong.Common.prevHouse(Mahjong.Common.prevHouse(engine.myHouse))] }}</span>
|
<span :class="$style.centerPanelPoint">{{ engine.state.points[Mahjong.prevHouse(Mahjong.prevHouse(engine.myHouse))] }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div :class="$style.centerPanelTickerKami">
|
<div :class="$style.centerPanelTickerKami">
|
||||||
<div style="position: absolute; left: 10px; bottom: 5px;">
|
<div style="position: absolute; left: 10px; bottom: 5px;">
|
||||||
<span :class="$style.centerPanelHouse">{{ Mahjong.Common.prevHouse(engine.myHouse) === 'e' ? i18n.ts._mahjong.east : Mahjong.Common.prevHouse(engine.myHouse) === 's' ? i18n.ts._mahjong.south : Mahjong.Common.prevHouse(engine.myHouse) === 'w' ? i18n.ts._mahjong.west : i18n.ts._mahjong.north }}</span>
|
<span :class="$style.centerPanelHouse">{{ Mahjong.prevHouse(engine.myHouse) === 'e' ? i18n.ts._mahjong.east : Mahjong.prevHouse(engine.myHouse) === 's' ? i18n.ts._mahjong.south : Mahjong.prevHouse(engine.myHouse) === 'w' ? i18n.ts._mahjong.west : i18n.ts._mahjong.north }}</span>
|
||||||
<span :class="$style.centerPanelPoint">{{ engine.state.points[Mahjong.Common.prevHouse(engine.myHouse)] }}</span>
|
<span :class="$style.centerPanelPoint">{{ engine.state.points[Mahjong.prevHouse(engine.myHouse)] }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div :class="$style.centerPanelTickerSimo">
|
<div :class="$style.centerPanelTickerSimo">
|
||||||
<div style="position: absolute; left: 10px; bottom: 5px;">
|
<div style="position: absolute; left: 10px; bottom: 5px;">
|
||||||
<span :class="$style.centerPanelHouse">{{ Mahjong.Common.nextHouse(engine.myHouse) === 'e' ? i18n.ts._mahjong.east : Mahjong.Common.nextHouse(engine.myHouse) === 's' ? i18n.ts._mahjong.south : Mahjong.Common.nextHouse(engine.myHouse) === 'w' ? i18n.ts._mahjong.west : i18n.ts._mahjong.north }}</span>
|
<span :class="$style.centerPanelHouse">{{ Mahjong.nextHouse(engine.myHouse) === 'e' ? i18n.ts._mahjong.east : Mahjong.nextHouse(engine.myHouse) === 's' ? i18n.ts._mahjong.south : Mahjong.nextHouse(engine.myHouse) === 'w' ? i18n.ts._mahjong.west : i18n.ts._mahjong.north }}</span>
|
||||||
<span :class="$style.centerPanelPoint">{{ engine.state.points[Mahjong.Common.nextHouse(engine.myHouse)] }}</span>
|
<span :class="$style.centerPanelPoint">{{ engine.state.points[Mahjong.nextHouse(engine.myHouse)] }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div :class="$style.centerPanelTickerMe">
|
<div :class="$style.centerPanelTickerMe">
|
||||||
|
@ -39,33 +39,33 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div :class="$style.handTilesOfToimen">
|
<div :class="$style.handTilesOfToimen">
|
||||||
<div v-for="tile in engine.state.handTiles[Mahjong.Common.prevHouse(Mahjong.Common.prevHouse(engine.myHouse))]" style="display: inline-block;">
|
<div v-for="tile in engine.state.handTiles[Mahjong.prevHouse(Mahjong.prevHouse(engine.myHouse))]" style="display: inline-block;">
|
||||||
<img :src="`/client-assets/mahjong/tile-back.png`" :class="$style.handTileImgOfToimen"/>
|
<img :src="`/client-assets/mahjong/tile-back.png`" :class="$style.handTileImgOfToimen"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div :class="$style.handTilesOfKamitya">
|
<div :class="$style.handTilesOfKamitya">
|
||||||
<div v-for="tile in engine.state.handTiles[Mahjong.Common.prevHouse(engine.myHouse)]" :class="$style.sideTile">
|
<div v-for="tile in engine.state.handTiles[Mahjong.prevHouse(engine.myHouse)]" :class="$style.sideTile">
|
||||||
<img :src="`/client-assets/mahjong/tile-side.png`" style="display: inline-block; width: 32px;"/>
|
<img :src="`/client-assets/mahjong/tile-side.png`" style="display: inline-block; width: 32px;"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div :class="$style.handTilesOfSimotya">
|
<div :class="$style.handTilesOfSimotya">
|
||||||
<div v-for="tile in engine.state.handTiles[Mahjong.Common.nextHouse(engine.myHouse)]" :class="$style.sideTile">
|
<div v-for="tile in engine.state.handTiles[Mahjong.nextHouse(engine.myHouse)]" :class="$style.sideTile">
|
||||||
<img :src="`/client-assets/mahjong/tile-side.png`" style="display: inline-block; width: 32px; scale: -1 1;"/>
|
<img :src="`/client-assets/mahjong/tile-side.png`" style="display: inline-block; width: 32px; scale: -1 1;"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div :class="$style.huroTilesOfToimen">
|
<div :class="$style.huroTilesOfToimen">
|
||||||
<XHuro v-for="huro in engine.state.huros[Mahjong.Common.prevHouse(Mahjong.Common.prevHouse(engine.myHouse))]" :huro="huro" :variation="1" :doras="engine.doras"/>
|
<XHuro v-for="huro in engine.state.huros[Mahjong.prevHouse(Mahjong.prevHouse(engine.myHouse))]" :huro="huro" :variation="1" :doras="engine.doras"/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div :class="$style.huroTilesOfKamitya">
|
<div :class="$style.huroTilesOfKamitya">
|
||||||
<XHuro v-for="huro in engine.state.huros[Mahjong.Common.prevHouse(engine.myHouse)]" :huro="huro" :variation="1" :doras="engine.doras"/>
|
<XHuro v-for="huro in engine.state.huros[Mahjong.prevHouse(engine.myHouse)]" :huro="huro" :variation="1" :doras="engine.doras"/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div :class="$style.huroTilesOfSimotya">
|
<div :class="$style.huroTilesOfSimotya">
|
||||||
<XHuro v-for="huro in engine.state.huros[Mahjong.Common.nextHouse(engine.myHouse)]" :huro="huro" :variation="1" :doras="engine.doras"/>
|
<XHuro v-for="huro in engine.state.huros[Mahjong.nextHouse(engine.myHouse)]" :huro="huro" :variation="1" :doras="engine.doras"/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div :class="$style.huroTilesOfMe">
|
<div :class="$style.huroTilesOfMe">
|
||||||
|
@ -75,21 +75,21 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<div :class="$style.hoTilesContainer">
|
<div :class="$style.hoTilesContainer">
|
||||||
<div :class="$style.hoTilesContainerOfToimen">
|
<div :class="$style.hoTilesContainerOfToimen">
|
||||||
<div :class="$style.hoTilesOfToimen">
|
<div :class="$style.hoTilesOfToimen">
|
||||||
<div v-for="(tile, i) in engine.state.hoTiles[Mahjong.Common.prevHouse(Mahjong.Common.prevHouse(engine.myHouse))]" :class="$style.hoTile" :style="{ zIndex: engine.state.hoTiles[Mahjong.Common.prevHouse(Mahjong.Common.prevHouse(engine.myHouse))].length - i }">
|
<div v-for="(tile, i) in engine.state.hoTiles[Mahjong.prevHouse(Mahjong.prevHouse(engine.myHouse))]" :class="$style.hoTile" :style="{ zIndex: engine.state.hoTiles[Mahjong.prevHouse(Mahjong.prevHouse(engine.myHouse))].length - i }">
|
||||||
<XTile :tile="tile" variation="2" :doras="engine.doras"/>
|
<XTile :tile="tile" variation="2" :doras="engine.doras"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div :class="$style.hoTilesContainerOfKamitya">
|
<div :class="$style.hoTilesContainerOfKamitya">
|
||||||
<div :class="$style.hoTilesOfKamitya">
|
<div :class="$style.hoTilesOfKamitya">
|
||||||
<div v-for="tile in engine.state.hoTiles[Mahjong.Common.prevHouse(engine.myHouse)]" :class="$style.hoTile">
|
<div v-for="tile in engine.state.hoTiles[Mahjong.prevHouse(engine.myHouse)]" :class="$style.hoTile">
|
||||||
<XTile :tile="tile" variation="4" :doras="engine.doras"/>
|
<XTile :tile="tile" variation="4" :doras="engine.doras"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div :class="$style.hoTilesContainerOfSimotya">
|
<div :class="$style.hoTilesContainerOfSimotya">
|
||||||
<div :class="$style.hoTilesOfSimotya">
|
<div :class="$style.hoTilesOfSimotya">
|
||||||
<div v-for="(tile, i) in engine.state.hoTiles[Mahjong.Common.nextHouse(engine.myHouse)]" :class="$style.hoTile" :style="{ zIndex: engine.state.hoTiles[Mahjong.Common.nextHouse(engine.myHouse)].length - i }">
|
<div v-for="(tile, i) in engine.state.hoTiles[Mahjong.nextHouse(engine.myHouse)]" :class="$style.hoTile" :style="{ zIndex: engine.state.hoTiles[Mahjong.nextHouse(engine.myHouse)].length - i }">
|
||||||
<XTile :tile="tile" variation="5" :doras="engine.doras"/>
|
<XTile :tile="tile" variation="5" :doras="engine.doras"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -105,7 +105,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
<div :class="$style.handTilesOfMe">
|
<div :class="$style.handTilesOfMe">
|
||||||
<div
|
<div
|
||||||
v-for="tile in Mahjong.Common.sortTiles((isMyTurn && iTsumoed) ? engine.myHandTiles.slice(0, engine.myHandTiles.length - 1) : engine.myHandTiles)"
|
v-for="tile in Mahjong.sortTiles((isMyTurn && iTsumoed) ? engine.myHandTiles.slice(0, engine.myHandTiles.length - 1) : engine.myHandTiles)"
|
||||||
:class="[$style.myTile, { [$style.myTileNonSelectable]: selectableTiles != null && !selectableTiles.includes(tile), [$style.myTileDora]: engine.doras.includes(tile) }]"
|
:class="[$style.myTile, { [$style.myTileNonSelectable]: selectableTiles != null && !selectableTiles.includes(tile), [$style.myTileDora]: engine.doras.includes(tile) }]"
|
||||||
@click="chooseTile(tile, $event)"
|
@click="chooseTile(tile, $event)"
|
||||||
>
|
>
|
||||||
|
@ -131,12 +131,12 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
:enterFromClass="$style.transition_serif_enterFrom"
|
:enterFromClass="$style.transition_serif_enterFrom"
|
||||||
:leaveToClass="$style.transition_serif_leaveTo"
|
:leaveToClass="$style.transition_serif_leaveTo"
|
||||||
>
|
>
|
||||||
<img v-if="ronSerifHouses[Mahjong.Common.prevHouse(Mahjong.Common.prevHouse(engine.myHouse))]" :src="`/client-assets/mahjong/ron.png`" style="display: block; width: 100%;"/>
|
<img v-if="ronSerifHouses[Mahjong.prevHouse(Mahjong.prevHouse(engine.myHouse))]" :src="`/client-assets/mahjong/ron.png`" style="display: block; width: 100%;"/>
|
||||||
<img v-else-if="ciiSerifHouses[Mahjong.Common.prevHouse(Mahjong.Common.prevHouse(engine.myHouse))]" :src="`/client-assets/mahjong/cii.png`" style="display: block; width: 100%;"/>
|
<img v-else-if="ciiSerifHouses[Mahjong.prevHouse(Mahjong.prevHouse(engine.myHouse))]" :src="`/client-assets/mahjong/cii.png`" style="display: block; width: 100%;"/>
|
||||||
<img v-else-if="ponSerifHouses[Mahjong.Common.prevHouse(Mahjong.Common.prevHouse(engine.myHouse))]" :src="`/client-assets/mahjong/pon.png`" style="display: block; width: 100%;"/>
|
<img v-else-if="ponSerifHouses[Mahjong.prevHouse(Mahjong.prevHouse(engine.myHouse))]" :src="`/client-assets/mahjong/pon.png`" style="display: block; width: 100%;"/>
|
||||||
<img v-else-if="kanSerifHouses[Mahjong.Common.prevHouse(Mahjong.Common.prevHouse(engine.myHouse))]" :src="`/client-assets/mahjong/kan.png`" style="display: block; width: 100%;"/>
|
<img v-else-if="kanSerifHouses[Mahjong.prevHouse(Mahjong.prevHouse(engine.myHouse))]" :src="`/client-assets/mahjong/kan.png`" style="display: block; width: 100%;"/>
|
||||||
<img v-else-if="tsumoSerifHouses[Mahjong.Common.prevHouse(Mahjong.Common.prevHouse(engine.myHouse))]" :src="`/client-assets/mahjong/tsumo.png`" style="display: block; width: 100%;"/>
|
<img v-else-if="tsumoSerifHouses[Mahjong.prevHouse(Mahjong.prevHouse(engine.myHouse))]" :src="`/client-assets/mahjong/tsumo.png`" style="display: block; width: 100%;"/>
|
||||||
<img v-else-if="riichiSerifHouses[Mahjong.Common.prevHouse(Mahjong.Common.prevHouse(engine.myHouse))]" :src="`/client-assets/mahjong/riichi.png`" style="display: block; width: 100%;"/>
|
<img v-else-if="riichiSerifHouses[Mahjong.prevHouse(Mahjong.prevHouse(engine.myHouse))]" :src="`/client-assets/mahjong/riichi.png`" style="display: block; width: 100%;"/>
|
||||||
</Transition>
|
</Transition>
|
||||||
</div>
|
</div>
|
||||||
<div :class="$style.serifContainerOfKamitya">
|
<div :class="$style.serifContainerOfKamitya">
|
||||||
|
@ -146,12 +146,12 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
:enterFromClass="$style.transition_serif_enterFrom"
|
:enterFromClass="$style.transition_serif_enterFrom"
|
||||||
:leaveToClass="$style.transition_serif_leaveTo"
|
:leaveToClass="$style.transition_serif_leaveTo"
|
||||||
>
|
>
|
||||||
<img v-if="ronSerifHouses[Mahjong.Common.prevHouse(engine.myHouse)]" :src="`/client-assets/mahjong/ron.png`" style="display: block; width: 100%;"/>
|
<img v-if="ronSerifHouses[Mahjong.prevHouse(engine.myHouse)]" :src="`/client-assets/mahjong/ron.png`" style="display: block; width: 100%;"/>
|
||||||
<img v-else-if="ciiSerifHouses[Mahjong.Common.prevHouse(engine.myHouse)]" :src="`/client-assets/mahjong/cii.png`" style="display: block; width: 100%;"/>
|
<img v-else-if="ciiSerifHouses[Mahjong.prevHouse(engine.myHouse)]" :src="`/client-assets/mahjong/cii.png`" style="display: block; width: 100%;"/>
|
||||||
<img v-else-if="ponSerifHouses[Mahjong.Common.prevHouse(engine.myHouse)]" :src="`/client-assets/mahjong/pon.png`" style="display: block; width: 100%;"/>
|
<img v-else-if="ponSerifHouses[Mahjong.prevHouse(engine.myHouse)]" :src="`/client-assets/mahjong/pon.png`" style="display: block; width: 100%;"/>
|
||||||
<img v-else-if="kanSerifHouses[Mahjong.Common.prevHouse(engine.myHouse)]" :src="`/client-assets/mahjong/kan.png`" style="display: block; width: 100%;"/>
|
<img v-else-if="kanSerifHouses[Mahjong.prevHouse(engine.myHouse)]" :src="`/client-assets/mahjong/kan.png`" style="display: block; width: 100%;"/>
|
||||||
<img v-else-if="tsumoSerifHouses[Mahjong.Common.prevHouse(engine.myHouse)]" :src="`/client-assets/mahjong/tsumo.png`" style="display: block; width: 100%;"/>
|
<img v-else-if="tsumoSerifHouses[Mahjong.prevHouse(engine.myHouse)]" :src="`/client-assets/mahjong/tsumo.png`" style="display: block; width: 100%;"/>
|
||||||
<img v-else-if="riichiSerifHouses[Mahjong.Common.prevHouse(engine.myHouse)]" :src="`/client-assets/mahjong/riichi.png`" style="display: block; width: 100%;"/>
|
<img v-else-if="riichiSerifHouses[Mahjong.prevHouse(engine.myHouse)]" :src="`/client-assets/mahjong/riichi.png`" style="display: block; width: 100%;"/>
|
||||||
</Transition>
|
</Transition>
|
||||||
</div>
|
</div>
|
||||||
<div :class="$style.serifContainerOfSimotya">
|
<div :class="$style.serifContainerOfSimotya">
|
||||||
|
@ -161,12 +161,12 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
:enterFromClass="$style.transition_serif_enterFrom"
|
:enterFromClass="$style.transition_serif_enterFrom"
|
||||||
:leaveToClass="$style.transition_serif_leaveTo"
|
:leaveToClass="$style.transition_serif_leaveTo"
|
||||||
>
|
>
|
||||||
<img v-if="ronSerifHouses[Mahjong.Common.nextHouse(engine.myHouse)]" :src="`/client-assets/mahjong/ron.png`" style="display: block; width: 100%;"/>
|
<img v-if="ronSerifHouses[Mahjong.nextHouse(engine.myHouse)]" :src="`/client-assets/mahjong/ron.png`" style="display: block; width: 100%;"/>
|
||||||
<img v-else-if="ciiSerifHouses[Mahjong.Common.nextHouse(engine.myHouse)]" :src="`/client-assets/mahjong/cii.png`" style="display: block; width: 100%;"/>
|
<img v-else-if="ciiSerifHouses[Mahjong.nextHouse(engine.myHouse)]" :src="`/client-assets/mahjong/cii.png`" style="display: block; width: 100%;"/>
|
||||||
<img v-else-if="ponSerifHouses[Mahjong.Common.nextHouse(engine.myHouse)]" :src="`/client-assets/mahjong/pon.png`" style="display: block; width: 100%;"/>
|
<img v-else-if="ponSerifHouses[Mahjong.nextHouse(engine.myHouse)]" :src="`/client-assets/mahjong/pon.png`" style="display: block; width: 100%;"/>
|
||||||
<img v-else-if="kanSerifHouses[Mahjong.Common.nextHouse(engine.myHouse)]" :src="`/client-assets/mahjong/kan.png`" style="display: block; width: 100%;"/>
|
<img v-else-if="kanSerifHouses[Mahjong.nextHouse(engine.myHouse)]" :src="`/client-assets/mahjong/kan.png`" style="display: block; width: 100%;"/>
|
||||||
<img v-else-if="tsumoSerifHouses[Mahjong.Common.nextHouse(engine.myHouse)]" :src="`/client-assets/mahjong/tsumo.png`" style="display: block; width: 100%;"/>
|
<img v-else-if="tsumoSerifHouses[Mahjong.nextHouse(engine.myHouse)]" :src="`/client-assets/mahjong/tsumo.png`" style="display: block; width: 100%;"/>
|
||||||
<img v-else-if="riichiSerifHouses[Mahjong.Common.nextHouse(engine.myHouse)]" :src="`/client-assets/mahjong/riichi.png`" style="display: block; width: 100%;"/>
|
<img v-else-if="riichiSerifHouses[Mahjong.nextHouse(engine.myHouse)]" :src="`/client-assets/mahjong/riichi.png`" style="display: block; width: 100%;"/>
|
||||||
</Transition>
|
</Transition>
|
||||||
</div>
|
</div>
|
||||||
<div :class="$style.serifContainerOfMe">
|
<div :class="$style.serifContainerOfMe">
|
||||||
|
@ -194,14 +194,14 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<MkButton v-if="isMyTurn && engine.canRiichi()" primary @click="riichi">Riichi</MkButton>
|
<MkButton v-if="isMyTurn && engine.canRiichi()" primary @click="riichi">Riichi</MkButton>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="kyokuEnded" :class="$style.kyokuResult">
|
<div v-if="showKyokuResults" :class="$style.kyokuResult">
|
||||||
<div v-for="(res, house) in kyokuResults" :key="house">
|
<div v-for="(res, house) in kyokuResults" :key="house">
|
||||||
<div v-if="res != null">
|
<div v-if="res != null">
|
||||||
<div>{{ house === 'e' ? i18n.ts._mahjong.east : house === 's' ? i18n.ts._mahjong.south : house === 'w' ? i18n.ts._mahjong.west : i18n.ts._mahjong.north }}</div>
|
<div>{{ house === 'e' ? i18n.ts._mahjong.east : house === 's' ? i18n.ts._mahjong.south : house === 'w' ? i18n.ts._mahjong.west : i18n.ts._mahjong.north }}</div>
|
||||||
<div v-for="yaku in res.yakus">
|
<div v-for="yaku in res.yakus">
|
||||||
<div>{{ yaku.name }} ({{ yaku.fan }})</div>
|
<div>{{ i18n.ts._mahjong._yakus[yaku.name] }} {{ yaku.fan }}{{ i18n.ts._mahjong.fan }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div>{{ res.doraCount }} dora</div>
|
<div>{{ i18n.ts._mahjong.dora }} {{ res.doraCount }}{{ i18n.ts._mahjong.fan }}</div>
|
||||||
<div>{{ res.pointDeltas.e }} / {{ res.pointDeltas.s }} / {{ res.pointDeltas.w }} / {{ res.pointDeltas.n }}</div>
|
<div>{{ res.pointDeltas.e }} / {{ res.pointDeltas.s }} / {{ res.pointDeltas.w }} / {{ res.pointDeltas.n }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -244,19 +244,19 @@ const isMyTurn = computed(() => {
|
||||||
});
|
});
|
||||||
|
|
||||||
const canHora = computed(() => {
|
const canHora = computed(() => {
|
||||||
return Mahjong.Common.getHoraSets(engine.value.myHandTiles).length > 0;
|
return Mahjong.getHoraSets(engine.value.myHandTiles).length > 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
const selectableTiles = ref<Mahjong.Common.Tile[] | null>(null);
|
const selectableTiles = ref<Mahjong.Tile[] | null>(null);
|
||||||
const ronSerifHouses = reactive<Record<Mahjong.Common.House, boolean>>({ e: false, s: false, w: false, n: false });
|
const ronSerifHouses = reactive<Record<Mahjong.House, boolean>>({ e: false, s: false, w: false, n: false });
|
||||||
const ciiSerifHouses = reactive<Record<Mahjong.Common.House, boolean>>({ e: false, s: false, w: false, n: false });
|
const ciiSerifHouses = reactive<Record<Mahjong.House, boolean>>({ e: false, s: false, w: false, n: false });
|
||||||
const ponSerifHouses = reactive<Record<Mahjong.Common.House, boolean>>({ e: false, s: false, w: false, n: false });
|
const ponSerifHouses = reactive<Record<Mahjong.House, boolean>>({ e: false, s: false, w: false, n: false });
|
||||||
const kanSerifHouses = reactive<Record<Mahjong.Common.House, boolean>>({ e: false, s: false, w: false, n: false });
|
const kanSerifHouses = reactive<Record<Mahjong.House, boolean>>({ e: false, s: false, w: false, n: false });
|
||||||
const tsumoSerifHouses = reactive<Record<Mahjong.Common.House, boolean>>({ e: false, s: false, w: false, n: false });
|
const tsumoSerifHouses = reactive<Record<Mahjong.House, boolean>>({ e: false, s: false, w: false, n: false });
|
||||||
const riichiSerifHouses = reactive<Record<Mahjong.Common.House, boolean>>({ e: false, s: false, w: false, n: false });
|
const riichiSerifHouses = reactive<Record<Mahjong.House, boolean>>({ e: false, s: false, w: false, n: false });
|
||||||
|
|
||||||
/*
|
/*
|
||||||
console.log(Mahjong.Common.getTilesForRiichi([
|
console.log(Mahjong.getTilesForRiichi([
|
||||||
'm1',
|
'm1',
|
||||||
'm2',
|
'm2',
|
||||||
'm2',
|
'm2',
|
||||||
|
@ -274,7 +274,7 @@ console.log(Mahjong.Common.getTilesForRiichi([
|
||||||
]));
|
]));
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
console.log(Mahjong.Common.getHoraSets([
|
console.log(Mahjong.getHoraSets([
|
||||||
'm3',
|
'm3',
|
||||||
'm3',
|
'm3',
|
||||||
'm4',
|
'm4',
|
||||||
|
@ -335,7 +335,7 @@ if (!props.room.isEnded) {
|
||||||
|
|
||||||
let riichiSelect = false;
|
let riichiSelect = false;
|
||||||
|
|
||||||
function chooseTile(tile: Mahjong.Common.Tile, ev: MouseEvent) {
|
function chooseTile(tile: Mahjong.Tile, ev: MouseEvent) {
|
||||||
if (!isMyTurn.value) return;
|
if (!isMyTurn.value) return;
|
||||||
|
|
||||||
iTsumoed.value = false;
|
iTsumoed.value = false;
|
||||||
|
@ -353,8 +353,8 @@ function riichi() {
|
||||||
if (!isMyTurn.value) return;
|
if (!isMyTurn.value) return;
|
||||||
|
|
||||||
riichiSelect = true;
|
riichiSelect = true;
|
||||||
selectableTiles.value = Mahjong.Common.getTilesForRiichi(engine.value.myHandTiles);
|
selectableTiles.value = Mahjong.getTilesForRiichi(engine.value.myHandTiles);
|
||||||
console.log(Mahjong.Common.getTilesForRiichi(engine.value.myHandTiles));
|
console.log(Mahjong.getTilesForRiichi(engine.value.myHandTiles));
|
||||||
}
|
}
|
||||||
|
|
||||||
function kakan() {
|
function kakan() {
|
||||||
|
@ -389,14 +389,14 @@ function skip() {
|
||||||
}
|
}
|
||||||
|
|
||||||
const iTsumoed = ref(false);
|
const iTsumoed = ref(false);
|
||||||
const kyokuEnded = ref(false);
|
const showKyokuResults = ref(false);
|
||||||
const kyokuResults = ref<Record<Mahjong.Common.House, {
|
const kyokuResults = ref<Record<Mahjong.House, {
|
||||||
yakus: {
|
yakus: {
|
||||||
name: string;
|
name: string;
|
||||||
fan: number;
|
fan: number;
|
||||||
}[];
|
}[];
|
||||||
doraCount: number;
|
doraCount: number;
|
||||||
pointDeltas: Record<Mahjong.Common.House, number>;
|
pointDeltas: Record<Mahjong.House, number>;
|
||||||
} | null>>({
|
} | null>>({
|
||||||
e: null,
|
e: null,
|
||||||
s: null,
|
s: null,
|
||||||
|
@ -405,7 +405,7 @@ const kyokuResults = ref<Record<Mahjong.Common.House, {
|
||||||
});
|
});
|
||||||
|
|
||||||
function kyokuEnd() {
|
function kyokuEnd() {
|
||||||
kyokuEnded.value = true;
|
showKyokuResults.value = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function onStreamDahai(log) {
|
function onStreamDahai(log) {
|
||||||
|
@ -481,10 +481,10 @@ function onStreamDahaiAndTsumo(log) {
|
||||||
}, 2000);
|
}, 2000);
|
||||||
|
|
||||||
window.setTimeout(() => {
|
window.setTimeout(() => {
|
||||||
engine.value.commit_tsumo(Mahjong.Common.nextHouse(log.dahaiHouse), log.tsumoTile);
|
engine.value.commit_tsumo(Mahjong.nextHouse(log.dahaiHouse), log.tsumoTile);
|
||||||
triggerRef(engine);
|
triggerRef(engine);
|
||||||
|
|
||||||
if (Mahjong.Common.nextHouse(log.dahaiHouse) === engine.value.myHouse) {
|
if (Mahjong.nextHouse(log.dahaiHouse) === engine.value.myHouse) {
|
||||||
iTsumoed.value = true;
|
iTsumoed.value = true;
|
||||||
}
|
}
|
||||||
}, 100);
|
}, 100);
|
||||||
|
@ -521,7 +521,10 @@ function onStreamRonned(log) {
|
||||||
triggerRef(engine);
|
triggerRef(engine);
|
||||||
|
|
||||||
kyokuResults.value = res;
|
kyokuResults.value = res;
|
||||||
kyokuEnded.value = true;
|
|
||||||
|
window.setTimeout(() => {
|
||||||
|
showKyokuResults.value = true;
|
||||||
|
}, 1500);
|
||||||
|
|
||||||
for (const caller of log.callers) {
|
for (const caller of log.callers) {
|
||||||
ronSerifHouses[caller] = true;
|
ronSerifHouses[caller] = true;
|
||||||
|
@ -537,7 +540,10 @@ function onStreamTsumoHora(log) {
|
||||||
triggerRef(engine);
|
triggerRef(engine);
|
||||||
|
|
||||||
kyokuResults.value[log.house] = res;
|
kyokuResults.value[log.house] = res;
|
||||||
kyokuEnded.value = true;
|
|
||||||
|
window.setTimeout(() => {
|
||||||
|
showKyokuResults.value = true;
|
||||||
|
}, 1500);
|
||||||
|
|
||||||
tsumoSerifHouses[log.house] = true;
|
tsumoSerifHouses[log.house] = true;
|
||||||
|
|
||||||
|
|
|
@ -15,9 +15,9 @@ import { computed } from 'vue';
|
||||||
import * as Mahjong from 'misskey-mahjong';
|
import * as Mahjong from 'misskey-mahjong';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
tile: Mahjong.Common.Tile;
|
tile: Mahjong.Tile;
|
||||||
variation: string;
|
variation: string;
|
||||||
doras: Mahjong.Common.Tile[];
|
doras: Mahjong.Tile[];
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const isDora = computed(() => props.doras.includes(props.tile));
|
const isDora = computed(() => props.doras.includes(props.tile));
|
||||||
|
|
|
@ -101,59 +101,6 @@ export const NEXT_TILE_FOR_DORA_MAP: Record<Tile, Tile> = {
|
||||||
chun: 'haku',
|
chun: 'haku',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const yakuNames = [
|
|
||||||
'riichi',
|
|
||||||
'ippatsu',
|
|
||||||
'tsumo',
|
|
||||||
'tanyao',
|
|
||||||
'pinfu',
|
|
||||||
'iipeko',
|
|
||||||
'field-wind',
|
|
||||||
'seat-wind',
|
|
||||||
'white',
|
|
||||||
'green',
|
|
||||||
'red',
|
|
||||||
'rinshan',
|
|
||||||
'chankan',
|
|
||||||
'haitei',
|
|
||||||
'hotei',
|
|
||||||
'sanshoku-dojun',
|
|
||||||
'sanshoku-doko',
|
|
||||||
'ittsu',
|
|
||||||
'chanta',
|
|
||||||
'chitoitsu',
|
|
||||||
'toitoi',
|
|
||||||
'sananko',
|
|
||||||
'honroto',
|
|
||||||
'sankantsu',
|
|
||||||
'shosangen',
|
|
||||||
'double-riichi',
|
|
||||||
'honitsu',
|
|
||||||
'junchan',
|
|
||||||
'ryampeko',
|
|
||||||
'chinitsu',
|
|
||||||
'dora',
|
|
||||||
'red-dora',
|
|
||||||
] as const;
|
|
||||||
|
|
||||||
export const yakumanNames = [
|
|
||||||
'kokushi',
|
|
||||||
'kokushi-13',
|
|
||||||
'suanko',
|
|
||||||
'suanko-tanki',
|
|
||||||
'daisangen',
|
|
||||||
'tsuiso',
|
|
||||||
'shosushi',
|
|
||||||
'daisushi',
|
|
||||||
'ryuiso',
|
|
||||||
'chinroto',
|
|
||||||
'sukantsu',
|
|
||||||
'churen',
|
|
||||||
'pure-churen',
|
|
||||||
'tenho',
|
|
||||||
'chiho',
|
|
||||||
] as const;
|
|
||||||
|
|
||||||
type EnvForCalcYaku = {
|
type EnvForCalcYaku = {
|
||||||
house: House;
|
house: House;
|
||||||
|
|
||||||
|
@ -260,15 +207,80 @@ export const YAKU_DEFINITIONS = [{
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
}, {
|
}, {
|
||||||
name: 'seat-wind',
|
name: 'field-wind-e',
|
||||||
fan: 1,
|
fan: 1,
|
||||||
calc: (state: EnvForCalcYaku) => {
|
calc: (state: EnvForCalcYaku) => {
|
||||||
return (
|
return state.fieldWind === 'e' && (
|
||||||
(state.handTiles.filter(t => t === state.house).length >= 3) ||
|
(state.handTiles.filter(t => t === 'e').length >= 3) ||
|
||||||
(state.huros.filter(huro =>
|
(state.huros.filter(huro =>
|
||||||
huro.type === 'pon' ? huro.tile === state.house :
|
huro.type === 'pon' ? huro.tile === 'e' :
|
||||||
huro.type === 'ankan' ? huro.tile === state.house :
|
huro.type === 'ankan' ? huro.tile === 'e' :
|
||||||
huro.type === 'minkan' ? huro.tile === state.house :
|
huro.type === 'minkan' ? huro.tile === 'e' :
|
||||||
|
false).length >= 3)
|
||||||
|
);
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
name: 'field-wind-s',
|
||||||
|
fan: 1,
|
||||||
|
calc: (state: EnvForCalcYaku) => {
|
||||||
|
return state.fieldWind === 's' && (
|
||||||
|
(state.handTiles.filter(t => t === 's').length >= 3) ||
|
||||||
|
(state.huros.filter(huro =>
|
||||||
|
huro.type === 'pon' ? huro.tile === 's' :
|
||||||
|
huro.type === 'ankan' ? huro.tile === 's' :
|
||||||
|
huro.type === 'minkan' ? huro.tile === 's' :
|
||||||
|
false).length >= 3)
|
||||||
|
);
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
name: 'seat-wind-e',
|
||||||
|
fan: 1,
|
||||||
|
calc: (state: EnvForCalcYaku) => {
|
||||||
|
return state.house === 'e' && (
|
||||||
|
(state.handTiles.filter(t => t === 'e').length >= 3) ||
|
||||||
|
(state.huros.filter(huro =>
|
||||||
|
huro.type === 'pon' ? huro.tile === 'e' :
|
||||||
|
huro.type === 'ankan' ? huro.tile === 'e' :
|
||||||
|
huro.type === 'minkan' ? huro.tile === 'e' :
|
||||||
|
false).length >= 3)
|
||||||
|
);
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
name: 'seat-wind-s',
|
||||||
|
fan: 1,
|
||||||
|
calc: (state: EnvForCalcYaku) => {
|
||||||
|
return state.house === 's' && (
|
||||||
|
(state.handTiles.filter(t => t === 's').length >= 3) ||
|
||||||
|
(state.huros.filter(huro =>
|
||||||
|
huro.type === 'pon' ? huro.tile === 's' :
|
||||||
|
huro.type === 'ankan' ? huro.tile === 's' :
|
||||||
|
huro.type === 'minkan' ? huro.tile === 's' :
|
||||||
|
false).length >= 3)
|
||||||
|
);
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
name: 'seat-wind-w',
|
||||||
|
fan: 1,
|
||||||
|
calc: (state: EnvForCalcYaku) => {
|
||||||
|
return state.house === 'w' && (
|
||||||
|
(state.handTiles.filter(t => t === 'w').length >= 3) ||
|
||||||
|
(state.huros.filter(huro =>
|
||||||
|
huro.type === 'pon' ? huro.tile === 'w' :
|
||||||
|
huro.type === 'ankan' ? huro.tile === 'w' :
|
||||||
|
huro.type === 'minkan' ? huro.tile === 'w' :
|
||||||
|
false).length >= 3)
|
||||||
|
);
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
name: 'seat-wind-n',
|
||||||
|
fan: 1,
|
||||||
|
calc: (state: EnvForCalcYaku) => {
|
||||||
|
return state.house === 'n' && (
|
||||||
|
(state.handTiles.filter(t => t === 'n').length >= 3) ||
|
||||||
|
(state.huros.filter(huro =>
|
||||||
|
huro.type === 'pon' ? huro.tile === 'n' :
|
||||||
|
huro.type === 'ankan' ? huro.tile === 'n' :
|
||||||
|
huro.type === 'minkan' ? huro.tile === 'n' :
|
||||||
false).length >= 3)
|
false).length >= 3)
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
@ -450,12 +462,6 @@ export const SHUNTU_PATTERNS: [Tile, Tile, Tile][] = [
|
||||||
['s7', 's8', 's9'],
|
['s7', 's8', 's9'],
|
||||||
];
|
];
|
||||||
|
|
||||||
export type KyokuResult = {
|
|
||||||
yakus: { name: string; fan: number; }[];
|
|
||||||
doraCount: number;
|
|
||||||
pointDeltas: { e: number; s: number; w: number; n: number; };
|
|
||||||
};
|
|
||||||
|
|
||||||
function extractShuntsus(tiles: Tile[]): [Tile, Tile, Tile][] {
|
function extractShuntsus(tiles: Tile[]): [Tile, Tile, Tile][] {
|
||||||
const tempTiles = [...tiles];
|
const tempTiles = [...tiles];
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export * as Serializer from './serializer.js';
|
export * as Serializer from './serializer.js';
|
||||||
export * as Common from './common.js';
|
export * from './common.js';
|
||||||
|
|
||||||
export { MasterGameEngine } from './engine.master.js';
|
export { MasterGameEngine } from './engine.master.js';
|
||||||
export type { MasterState } from './engine.master.js';
|
export type { MasterState } from './engine.master.js';
|
||||||
|
|
Loading…
Reference in a new issue