misskey/packages/misskey-mahjong/src/common.fu.ts

64 lines
1.9 KiB
TypeScript

/*
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { FourMentsuOneJyantou, mentsuEquals, TILE_NUMBER_MAP, TileType } from './common.js';
export type Shape = 'fourMentsuOneJyantou' | 'chitoitsu' | 'kokushi';
/**
* 4面子1雀頭と待ちに関わる部分
*/
export type FourMentsuOneJyantouWithWait = FourMentsuOneJyantou & {
agariTile: TileType;
} & ({
waitedFor: 'head';
} | {
waitedFor: 'mentsu';
waitedTaatsu: [TileType, TileType];
});
export function calcWaitPatterns(fourMentsuOneJyantou: FourMentsuOneJyantou | null, agariTile: TileType): FourMentsuOneJyantouWithWait[] | [null] {
if (fourMentsuOneJyantou == null) return [null];
const result: FourMentsuOneJyantouWithWait[] = [];
if (fourMentsuOneJyantou.head === agariTile) {
result.push({
head: fourMentsuOneJyantou.head,
mentsus: fourMentsuOneJyantou.mentsus,
waitedFor: 'head',
agariTile,
});
}
const checkedMentsus: [TileType, TileType, TileType][] = [];
for (const mentsu of fourMentsuOneJyantou.mentsus) {
if (checkedMentsus.some(checkedMentsu => mentsuEquals(mentsu, checkedMentsu))) continue;
const agariTileIndex = mentsu.indexOf(agariTile);
if (agariTileIndex < 0) continue;
result.push({
head: fourMentsuOneJyantou.head,
mentsus: fourMentsuOneJyantou.mentsus,
waitedFor: 'mentsu',
agariTile,
waitedTaatsu: mentsu.toSpliced(agariTileIndex, 1) as [TileType, TileType],
});
checkedMentsus.push(mentsu);
}
return result;
}
export function isRyanmen(taatsu: [TileType, TileType]): boolean {
const number1 = TILE_NUMBER_MAP[taatsu[0]];
const number2 = TILE_NUMBER_MAP[taatsu[1]];
if (number1 == null || number2 == null) return false;
return number1 !== 1 && number2 !== 9 && number1 + 1 === number2;
}
export function isToitsu(taatsu: [TileType, TileType]): boolean {
return taatsu[0] === taatsu[1];
}