This commit is contained in:
syuilo 2024-01-29 14:14:00 +09:00
parent 11404e545e
commit 668bf9a226
6 changed files with 114 additions and 11 deletions

View File

@ -226,6 +226,8 @@ export interface MahjongRoomEventTypes {
target: Mahjong.Common.House;
tile: Mahjong.Common.Tile;
};
endKyoku: {
};
}
//#endregion

View File

@ -300,7 +300,7 @@ export class MahjongService implements OnApplicationShutdown, OnModuleInit {
this.waitForTurn(room, userId, engine);
} else if (res.type === 'kanned') {
// TODO
} else if (res.type === 'ronned') {
} else if (res.type === 'endKyoku') {
// TODO
}
}
@ -415,7 +415,7 @@ export class MahjongService implements OnApplicationShutdown, OnModuleInit {
this.answer(room, engine, currentAnswers);
return;
}
}, 2000);
}, 1000);
this.globalEventService.publishMahjongRoomStream(room.id, 'dahai', { house: house, tile });
} else {
@ -445,6 +445,38 @@ export class MahjongService implements OnApplicationShutdown, OnModuleInit {
await this.dahai(room, engine, myHouse, tile);
}
@bindThis
public async commit_kakan(roomId: MiMahjongGame['id'], user: MiUser) {
const room = await this.getRoom(roomId);
if (room == null) return;
if (room.gameState == null) return;
const engine = new Mahjong.MasterGameEngine(room.gameState);
const myHouse = user.id === room.user1Id ? engine.state.user1House : user.id === room.user2Id ? engine.state.user2House : user.id === room.user3Id ? engine.state.user3House : engine.state.user4House;
await this.clearTurnWaitingTimer(room.id);
const res = engine.commit_kakan(myHouse);
this.globalEventService.publishMahjongRoomStream(room.id, 'kakanned', { });
}
@bindThis
public async commit_hora(roomId: MiMahjongGame['id'], user: MiUser) {
const room = await this.getRoom(roomId);
if (room == null) return;
if (room.gameState == null) return;
const engine = new Mahjong.MasterGameEngine(room.gameState);
const myHouse = user.id === room.user1Id ? engine.state.user1House : user.id === room.user2Id ? engine.state.user2House : user.id === room.user3Id ? engine.state.user3House : engine.state.user4House;
await this.clearTurnWaitingTimer(room.id);
const res = engine.commit_hora(myHouse);
this.globalEventService.publishMahjongRoomStream(room.id, 'horad', { });
}
@bindThis
public async commit_ron(roomId: MiMahjongGame['id'], user: MiUser) {
const room = await this.getRoom(roomId);
@ -504,7 +536,7 @@ export class MahjongService implements OnApplicationShutdown, OnModuleInit {
}
/**
* ()
* ()
*
* NOTE: 時間切れチェックが行われたときにタイミングによっては次のwaitingが始まっている場合があることを考慮しSetに一意のIDを格納する構造としている
* @param room
@ -536,7 +568,7 @@ export class MahjongService implements OnApplicationShutdown, OnModuleInit {
}
/**
*
* ()
* @param roomId
*/
@bindThis

View File

@ -39,6 +39,7 @@ class MahjongRoomChannel extends Channel {
case 'updateSettings': this.updateSettings(body.key, body.value); break;
case 'addAi': this.addAi(); break;
case 'dahai': this.dahai(body.tile, body.riichi); break;
case 'hora': this.hora(); break;
case 'ron': this.ron(); break;
case 'pon': this.pon(); break;
case 'nop': this.nop(); break;
@ -74,6 +75,13 @@ class MahjongRoomChannel extends Channel {
this.mahjongService.commit_dahai(this.roomId!, this.user, tile, riichi);
}
@bindThis
private async hora() {
if (this.user == null) return;
this.mahjongService.commit_hora(this.roomId!, this.user);
}
@bindThis
private async ron() {
if (this.user == null) return;

View File

@ -79,7 +79,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkButton v-if="engine.state.canRonSource != null" primary gradate @click="ron">Ron</MkButton>
<MkButton v-if="engine.state.canPonSource != null" primary @click="pon">Pon</MkButton>
<MkButton v-if="engine.state.canRonSource != null || engine.state.canPonSource != null" @click="skip">Skip</MkButton>
<MkButton v-if="isMyTurn && canHora" primary gradate>Tsumo</MkButton>
<MkButton v-if="isMyTurn && canHora" primary gradate @click="hora">Tsumo</MkButton>
<MkButton v-if="isMyTurn && canRiichi" primary @click="riichi">Riichi</MkButton>
</div>
</template>
@ -227,6 +227,26 @@ function riichi() {
});
}
function kakan() {
if (!isMyTurn.value) return;
engine.value.commit_kakan(engine.value.myHouse);
triggerRef(engine);
props.connection!.send('kakan', {
});
}
function hora() {
if (!isMyTurn.value) return;
engine.value.commit_hora(engine.value.myHouse);
triggerRef(engine);
props.connection!.send('hora', {
});
}
function ron() {
engine.value.commit_ron(engine.value.state.canRonSource, engine.value.myHouse);
triggerRef(engine);
@ -236,9 +256,6 @@ function ron() {
}
function pon() {
engine.value.commit_pon(engine.value.state.canPonSource, engine.value.myHouse);
triggerRef(engine);
props.connection!.send('pon', {
});
}
@ -336,8 +353,6 @@ function onStreamPonned(log) {
// return;
//}
if (log.target === engine.value.myHouse) return;
engine.value.commit_pon(log.source, log.target);
triggerRef(engine);

View File

@ -13,6 +13,10 @@ export type MasterState = {
user2House: House;
user3House: House;
user4House: House;
round: 'e' | 's' | 'w' | 'n';
kyoku: number;
tiles: Tile[];
/**
@ -122,6 +126,8 @@ export class MasterGameEngine {
user2House: 's',
user3House: 'w',
user4House: 'n',
round: 'e',
kyoku: 1,
tiles,
handTiles: {
e: eHandTiles,
@ -198,6 +204,12 @@ export class MasterGameEngine {
}
}
private endKyoku() {
const newState = MasterGameEngine.createInitialState();
newState.kyoku = this.state.kyoku + 1;
newState.points = this.state.points;
}
public commit_dahai(house: House, tile: Tile, riichi = false) {
if (this.state.turn !== house) throw new Error('Not your turn');
@ -311,6 +323,21 @@ export class MasterGameEngine {
};
}
public commit_kakan(house: House) {
}
/**
*
* @param house
*/
public commit_hora(house: House) {
if (this.state.turn !== house) throw new Error('Not your turn');
const yakus = Utils.getYakus(this.state.handTiles[house], null);
this.endKyoku();
}
public commit_resolveCallAndRonInterruption(answers: {
pon: boolean;
cii: boolean;
@ -328,7 +355,10 @@ export class MasterGameEngine {
if (this.state.ronAsking != null && answers.ron.length > 0) {
// TODO
return;
this.endKyoku();
return {
type: 'endKyoku',
};
}
if (this.state.kanAsking != null && answers.kan) {
@ -401,6 +431,8 @@ export class MasterGameEngine {
user2House: this.state.user2House,
user3House: this.state.user3House,
user4House: this.state.user4House,
round: this.state.round,
kyoku: this.state.kyoku,
tilesCount: this.state.tiles.length,
handTiles: {
e: house === 'e' ? this.state.handTiles.e : this.state.handTiles.e.map(() => null),

View File

@ -12,6 +12,10 @@ export type PlayerState = {
user2House: House;
user3House: House;
user4House: House;
round: 'e' | 's' | 'w' | 'n';
kyoku: number;
tilesCount: number;
/**
@ -130,6 +134,16 @@ export class PlayerGameEngine {
}
}
public commit_kakan(house: House, tile: Tile) {
console.log('commit_kakan', this.state.turn, house, tile);
if (this.state.turn !== house) throw new PlayerGameEngine.InvalidOperationError();
}
public commit_hora(house: House) {
console.log('commit_hora', this.state.turn, house);
if (this.state.turn !== house) throw new PlayerGameEngine.InvalidOperationError();
}
/**
*
* @param source