From 38e3d248fbaa8594646d2ff7277a41c006d8bd24 Mon Sep 17 00:00:00 2001 From: syuilo Date: Sun, 4 Feb 2024 17:11:42 +0900 Subject: [PATCH] wip --- packages/backend/src/core/MahjongService.ts | 16 ++--- .../api/stream/channels/mahjong-room.ts | 6 +- .../frontend/assets/mahjong/tiles/m5r.png | Bin 0 -> 8011 bytes .../frontend/assets/mahjong/tiles/p5r.png | Bin 0 -> 22697 bytes .../frontend/assets/mahjong/tiles/s5r.png | Bin 0 -> 9050 bytes packages/frontend/src/pages/mahjong/huro.vue | 30 ++++---- .../frontend/src/pages/mahjong/room.game.vue | 68 +++++------------- packages/frontend/src/pages/mahjong/tile.vue | 12 ++-- packages/misskey-mahjong/src/engine.master.ts | 4 +- packages/misskey-mahjong/src/engine.player.ts | 2 +- 10 files changed, 49 insertions(+), 89 deletions(-) create mode 100644 packages/frontend/assets/mahjong/tiles/m5r.png create mode 100644 packages/frontend/assets/mahjong/tiles/p5r.png create mode 100644 packages/frontend/assets/mahjong/tiles/s5r.png diff --git a/packages/backend/src/core/MahjongService.ts b/packages/backend/src/core/MahjongService.ts index e4abbe80769a..9a6422340ea5 100644 --- a/packages/backend/src/core/MahjongService.ts +++ b/packages/backend/src/core/MahjongService.ts @@ -376,7 +376,7 @@ export class MahjongService implements OnApplicationShutdown, OnModuleInit { } @bindThis - private async dahai(room: Room, engine: Mahjong.MasterGameEngine, house: Mahjong.House, tile: Mahjong.Tile, riichi = false) { + private async dahai(room: Room, engine: Mahjong.MasterGameEngine, house: Mahjong.House, tile: Mahjong.TileId, riichi = false) { const res = engine.commit_dahai(house, tile, riichi); room.gameState = engine.state; await this.saveRoom(room); @@ -384,8 +384,6 @@ export class MahjongService implements OnApplicationShutdown, OnModuleInit { 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 (res.asking) { - console.log('asking', res); - const answers: CallingAnswers = { pon: null, cii: null, @@ -478,11 +476,10 @@ export class MahjongService implements OnApplicationShutdown, OnModuleInit { } @bindThis - public async commit_dahai(roomId: MiMahjongGame['id'], user: MiUser, tile: string, riichi = false) { + public async commit_dahai(roomId: MiMahjongGame['id'], user: MiUser, tile: Mahjong.TileId, riichi = false) { const room = await this.getRoom(roomId); if (room == null) return; if (room.gameState == null) return; - if (!Mahjong.isTile(tile)) return; const engine = new Mahjong.MasterGameEngine(room.gameState); const myHouse = getHouseOfUserId(room, engine, user.id); @@ -493,7 +490,7 @@ export class MahjongService implements OnApplicationShutdown, OnModuleInit { } @bindThis - public async commit_ankan(roomId: MiMahjongGame['id'], user: MiUser, tile: string) { + public async commit_ankan(roomId: MiMahjongGame['id'], user: MiUser, tile: Mahjong.TileId) { const room = await this.getRoom(roomId); if (room == null) return; if (room.gameState == null) return; @@ -511,7 +508,7 @@ export class MahjongService implements OnApplicationShutdown, OnModuleInit { } @bindThis - public async commit_kakan(roomId: MiMahjongGame['id'], user: MiUser, tile: string) { + public async commit_kakan(roomId: MiMahjongGame['id'], user: MiUser, tile: Mahjong.TileId) { const room = await this.getRoom(roomId); if (room == null) return; if (room.gameState == null) return; @@ -643,11 +640,10 @@ export class MahjongService implements OnApplicationShutdown, OnModuleInit { if (engine.state.riichis[house]) { // リーチ時はアガリ牌でない限りツモ切り - const handTiles = engine.state.handTiles[house]; - const horaSets = Mahjong.getHoraSets(handTiles); + const horaSets = Mahjong.getHoraSets(engine.handTileTypes[house]); if (horaSets.length === 0) { setTimeout(() => { - this.dahai(room, engine, house, handTiles.at(-1)); + this.dahai(room, engine, house, engine.state.handTiles[house].at(-1)); }, 500); 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 b2e2ccdb921d..de7fc4f467e5 100644 --- a/packages/backend/src/server/api/stream/channels/mahjong-room.ts +++ b/packages/backend/src/server/api/stream/channels/mahjong-room.ts @@ -94,7 +94,7 @@ class MahjongRoomChannel extends Channel { } @bindThis - private async dahai(tile: string, riichi = false) { + private async dahai(tile: number, riichi = false) { if (this.user == null) return; this.mahjongService.commit_dahai(this.roomId!, this.user, tile, riichi); @@ -136,14 +136,14 @@ class MahjongRoomChannel extends Channel { } @bindThis -private async ankan(tile: string) { +private async ankan(tile: number) { if (this.user == null) return; this.mahjongService.commit_ankan(this.roomId!, this.user, tile); } @bindThis - private async kakan(tile: string) { + private async kakan(tile: number) { if (this.user == null) return; this.mahjongService.commit_kakan(this.roomId!, this.user, tile); diff --git a/packages/frontend/assets/mahjong/tiles/m5r.png b/packages/frontend/assets/mahjong/tiles/m5r.png new file mode 100644 index 0000000000000000000000000000000000000000..7347fb14ba670a6e28dcfb5ff9c66dea953d50cc GIT binary patch literal 8011 zcma)hc|4R|`1d^v8hfVf>sUe<`<8vll3lh!wz0*`Fl1+B%aW{7%2tYOAxqY&6cvd) z$U3D&wkbr`_tvxjp7-~D-al^U%=bFq>$=XhoOA9;wlFhbpyi|m0D!^BP|phdPXwQe zBh=vE+1m;V06^95bJjk{-qb|Z9p^9Q>Vb2^NQL_2K^y?oG(+*O?iVpZ{B9U8AFMiR zwXF-q@8hA4vQsdXHpS~=ynPJA12NX&W@p{QFS@IEpfojT)k0N40)I@9D}SiJAC{mR zs*d`_s|tQT{2Gno|0NQ1Q5|J(YQe9I3&ij%NGV83qcmvw)dD>{Rju?+|1lXHsiVAu zg7B(nbVx{uREV4uF3<}tqoSgMmX<}!%1VL~l7uj9kZY(UmLPaY@jHhehTtCPgAek- zVfha^UEOfOLFy>;)lq8#KG8@ zn*L?bzv%z;+TZ_Q_7H;fFM$j9M-cw6GYDtH@EEiehJXtWbjRpl0{s&FwRWI3Roy_0 zYY;{ceAH30(z5cB(z24$a%W{_ROO^qWu#9^t4K@#C2WfG@bL`$AHwoyWfWEA6;$OE zL1EQ@N`vX-;Tq)n|0DlbfK(5qe>VzD<^QKef6vjy`QZXV<3Jzeei{2WWTdNW5s35j z@dGh}m4Obwk-n~?jEbV7q^y+8FWJMmsap7iV*Kp&e88X+z?@V^$;c}I57gnGsG`c> z=r8ToU@?L!ey2Q)t*Vi~s~5)3$0Nx5Z??Yy6Aaet7xD+wFXS*re!+)DVT1JnqbmDL z$uG$MZ%iGfB#ZusB8UG#hh@gE=HadyKP_`w$9!gy;jN;eXN(07Nr`GuzI@B4Tc=<*{G93fwj5u7IBvIg($;Tm;W?LOP_Te9PiaY% zhKtPXRE9(4x5qKnlB}c0A3i!_F8<&;TjBA-nchl~RoW1-3PY1E$Fb^{R0*r5>gPV& zWoO&$D>~3o?Yb;8UlNW9SZ6yaCMhU^zOR`rCEB=?j}GW=IHR2$^-+Bup8q5%RplOK z788%S(Lpcs>S2|4#%jeUbXK;bzGp6qb5Y1Bvq#cb`$3Peh~Bl=hSu^s2hFwNZhnu> zO?`;F$M!6gk2uF8nnypoI41q-giAzXrJuTH2z-{WH1F%V0|Dh`^2gR1{Y`QpS8LJm z71jzv#ej<_2+r#*Z{nNt-cHp&s+tBC1mhJyS7Kcb0P4@}gk>5x2d__)Scfy<#)-fi zIuHPW4te-MfSb420f4Q-NKgB0=&j}3VPo9-H%KumaC&WeW@&1H=OvfzA*LCIqRdbzgMgNf4t*9KvU7GOO_9q^Of^ku3_CE_ZWa zoM;m+gqNk*+%0+SqDrwuwtPABfN36~RbgMIL~W+S86CvMTgSZh5Hab5u^B@WS?0B# zB{@Ks{GgjU9JvhWJ6RjKj7pJlN>DbKL7t^UEsZEhsVw^-x;&(p`yew^8gVrG) z9+zeu1XiH!T%j~C{p+c>Bq<4?3s$_gVO2vhkV~nL+u_PX@D(PNMQ+AjF1+dxe?S$a zhU$%cY=roL982NeX|fY3x|h<#e01)GOb;CE%rW3=5dz7NO{)u#plMQwJ)cujV;XA? zy#O>BiABp%7?8?&8%~wRx4!`V7e5M}28yWOB%gH2oo4k}M`qTjBv+6eMDS&4T{gul z>LjSk>l`<_4288<_aZhSo$;b)vphF|W_||EJM(R}x#P6pqMx}N&_LlK+mYN!G#QCA z=x0$OunTgrJJuz6Rghp-qG0U7>#zxNaxlkh4eBLVXtTr@IbZ#Aqjs43-OB|p$G3nJ zj6Yr^h0~Eb{i`Anlpe*A3mm?WX&)NnuFOAu7YYqM#<5wj0K>wX4CI4dSNb1VH5sp7 zw%<$BPt1RDGwL3~@mA>r*u~TLCe0Yb%ucdI8dx%L*WMP+rw2JOjKfShm`Wx{mm)M;Non<%>8j~p7WjZ0* zV0?`~T#Vy!m`CpPxcHu+p61(>veiqZWiVr#EDU^x0~j;PcDj^xZy-q2N5AY`J+NJ9 z7Ep}o$uz%~(M@}<86lc*4naKljW@??srHJ#8D~=Wt)hjZMjF|{Qz_r&@6|#zVbK;N ztbvuo#z4kO%$*$BJdgF_WX^*knoG^bF>#>~v8S&|WhDLOOB=7wOu@-_a~9FCE|bb` zbD@yrmUYki4c;(&#w8qd6aRAKx{kj{tnI?>qY+rgBZW*gCF{EiX)VQuf1aE$KcrCnp zdi8DEwN7r1WP*yFxcyN&z)U)}fS1s5 z0=WHDyaPh{oa1H=<8mk)&{K?jAt*Ac-$GvpO}TX@l<=)iv z{pkK(m7c{7crlFon!GRT^#W2yR>|b7?ShdWomMHt5E*9-h%3SE%R>0uPBZC^7Un8j z*Q-Gv`lr{wMG}{`6b?4DcpEBAUR<9(w&-*;Z|-xN@Y_Ymc&|fuLBv3^3K-q7Yu<6` zeO=MD#%62!exB}{_bY^Qj{=qJ5wW$;9Xpw1`mUfVf$rdg2H9z*pJz!7FCdyt#`oXL z1SJ?B0n3*_<}8)Oao0z2jplkbHpiIv{d~`{nzTC=6E^^?RSkXF`RtFGZw2hjk|1`1 zFWCFlsJY#sn;|YHCdVt(iA?*&g+z zJ9xd*97dC1QeG;8�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 N002ovPDHLkV1hEmU9JEC literal 0 HcmV?d00001 diff --git a/packages/frontend/assets/mahjong/tiles/s5r.png b/packages/frontend/assets/mahjong/tiles/s5r.png new file mode 100644 index 0000000000000000000000000000000000000000..09b1b884bf246835d66a0ae1c5de0ef604d424ce GIT binary patch literal 9050 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
- - - - + + + +
- - - - + + + +
- - - + + +
- - - + + +
@@ -36,7 +36,7 @@ import XTile from './tile.vue'; const props = defineProps<{ huro: Mahjong.Huro; variation: string; - doras: Mahjong.Tile[]; + doras: Mahjong.TileType[]; }>(); diff --git a/packages/frontend/src/pages/mahjong/room.game.vue b/packages/frontend/src/pages/mahjong/room.game.vue index 99471d50da6a..e1ab9bcff738 100644 --- a/packages/frontend/src/pages/mahjong/room.game.vue +++ b/packages/frontend/src/pages/mahjong/room.game.vue @@ -76,28 +76,28 @@ SPDX-License-Identifier: AGPL-3.0-only
- +
- +
- +
- +
@@ -106,20 +106,20 @@ SPDX-License-Identifier: AGPL-3.0-only
- +
- +
@@ -259,7 +259,7 @@ const canHora = computed(() => { return Mahjong.getHoraSets(engine.value.myHandTiles).length > 0; }); -const selectableTiles = ref(null); +const selectableTiles = ref(null); const ronSerifHouses = reactive>({ e: false, s: false, w: false, n: false }); const ciiSerifHouses = reactive>({ e: false, s: false, w: false, n: false }); const ponSerifHouses = reactive>({ e: false, s: false, w: false, n: false }); @@ -267,43 +267,6 @@ const kanSerifHouses = reactive>({ e: false, s: f const tsumoSerifHouses = reactive>({ e: false, s: false, w: false, n: false }); const riichiSerifHouses = reactive>({ e: false, s: false, w: false, n: false }); -/* -console.log(Mahjong.getTilesForRiichi([ - 'm1', - 'm2', - 'm2', - 'm3', - 'm3', - 'm5', - 'm6', - 'p4', - 'p5', - 'p6', - 's6', - 's7', - 's8', - 'm7', -])); -*/ -/* -console.log(Mahjong.getHoraSets([ - 'm3', - 'm3', - 'm4', - 'm4', - 'm5', - 'm5', - 'p4', - 'p4', - 'p7', - 'p8', - 'p9', - 's4', - 's5', - 's6', -])); -*/ - /* if (room.value.isStarted && !room.value.isEnded) { useInterval(() => { @@ -354,7 +317,7 @@ let ankanSelect = false; let kakanSelect = false; let ciiSelect = false; -function chooseTile(tile: Mahjong.Tile, ev: MouseEvent) { +function chooseTile(tile: Mahjong.TileId, ev: MouseEvent) { if (!isMyTurn.value) return; iTsumoed.value = false; @@ -390,22 +353,22 @@ function riichi() { if (!isMyTurn.value) return; riichiSelect = true; - selectableTiles.value = Mahjong.getTilesForRiichi(engine.value.myHandTiles); - console.log(Mahjong.getTilesForRiichi(engine.value.myHandTiles)); + selectableTiles.value = Mahjong.getTilesForRiichi(engine.value.myHandTileTypes); + console.log(Mahjong.getTilesForRiichi(engine.value.myHandTileTypes)); } function ankan() { if (!isMyTurn.value) return; ankanSelect = true; - selectableTiles.value = engine.value.getAnkanableTiles(); + selectableTiles.value = engine.value.getAnkanableTiles().map(id => Mahjong.findTileByIdOrFail(id).t); } function kakan() { if (!isMyTurn.value) return; kakanSelect = true; - selectableTiles.value = engine.value.getKakanableTiles(); + selectableTiles.value = engine.value.getKakanableTiles().map(id => Mahjong.findTileByIdOrFail(id).t); } function tsumoHora() { @@ -957,7 +920,6 @@ onUnmounted(() => { aspect-ratio: 0.7; transition: translate 0.1s ease; cursor: pointer; - overflow: clip; } .myTile:hover { translate: 0 -10px; @@ -967,6 +929,7 @@ onUnmounted(() => { opacity: 0.7; pointer-events: none; } +/* .myTileDora { &:after { content: ""; @@ -982,6 +945,7 @@ onUnmounted(() => { pointer-events: none; } } +*/ .myTileBg { position: absolute; top: 0; diff --git a/packages/frontend/src/pages/mahjong/tile.vue b/packages/frontend/src/pages/mahjong/tile.vue index bd9911eada8b..ba823414aa14 100644 --- a/packages/frontend/src/pages/mahjong/tile.vue +++ b/packages/frontend/src/pages/mahjong/tile.vue @@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only @@ -15,12 +15,12 @@ import { computed } from 'vue'; import * as Mahjong from 'misskey-mahjong'; const props = defineProps<{ - tile: Mahjong.Tile; + tile: Mahjong.TileInstance; variation: string; - doras: Mahjong.Tile[]; + doras: Mahjong.TileType[]; }>(); -const isDora = computed(() => props.doras.includes(props.tile)); +const isDora = computed(() => props.doras.includes(props.tile.t)); diff --git a/packages/misskey-mahjong/src/engine.master.ts b/packages/misskey-mahjong/src/engine.master.ts index b375296fe38e..d41f1ffbc463 100644 --- a/packages/misskey-mahjong/src/engine.master.ts +++ b/packages/misskey-mahjong/src/engine.master.ts @@ -14,7 +14,7 @@ function $(tileId: TileId): Common.TileInstance { } function $type(tileId: TileId): TileType { - return Common.findTileByIdOrFail(tileId).t; + return $(tileId).t; } //#endregion @@ -148,7 +148,7 @@ export class MasterGameEngine { } public static createInitialState(): MasterState { - const ikasama: TileId[] = [125, 129, 9, 54, 57, 61, 77, 81, 85, 133, 134, 135, 121, 122]; + const ikasama: TileId[] = [125, 129, 9, 56, 57, 61, 77, 81, 85, 133, 134, 135, 121, 122]; const tiles = [...Common.TILE_ID_MAP.keys()]; tiles.sort(() => Math.random() - 0.5); diff --git a/packages/misskey-mahjong/src/engine.player.ts b/packages/misskey-mahjong/src/engine.player.ts index f4a7e8d11957..91ec13642445 100644 --- a/packages/misskey-mahjong/src/engine.player.ts +++ b/packages/misskey-mahjong/src/engine.player.ts @@ -13,7 +13,7 @@ function $(tileId: TileId): Common.TileInstance { } function $type(tileId: TileId): TileType { - return Common.findTileByIdOrFail(tileId).t; + return $(tileId).t; } //#endregion