can now ron and tsumo
This commit is contained in:
parent
d557418a2e
commit
7c4fe72178
1 changed files with 70 additions and 5 deletions
73
src/game.ts
73
src/game.ts
|
|
@ -147,14 +147,31 @@ export class Game {
|
|||
return;
|
||||
}
|
||||
|
||||
// Determine if Ron/Tsumo should be available for player 0
|
||||
const canTsumo = this.hasPicked && this.hasWin(0);
|
||||
let canRon = false;
|
||||
if (this.lastDiscard !== undefined && this.lastDiscard !== 0) {
|
||||
const d = this.discards[this.lastDiscard];
|
||||
if (d && d.length > 0) {
|
||||
const last = d[d.length - 1];
|
||||
const sim = new Hand();
|
||||
for (const t of this.hands[0].getTiles()) {
|
||||
sim.push(new Tile(t.getFamily(), t.getValue(), t.isRed()));
|
||||
}
|
||||
sim.push(new Tile(last.getFamily(), last.getValue(), last.isRed()));
|
||||
sim.sort();
|
||||
canRon = sim.toGroup() !== undefined;
|
||||
}
|
||||
}
|
||||
|
||||
const action = clickAction(
|
||||
mp.x - rect.x,
|
||||
mp.y - rect.y,
|
||||
this.canDoAChii().length > 0,
|
||||
this.canDoAPon(),
|
||||
false && this.level > 1,
|
||||
false && this.level > 0,
|
||||
false && this.level > 0
|
||||
canRon,
|
||||
canTsumo
|
||||
);
|
||||
|
||||
if (this.canCall && action !== -1) {
|
||||
|
|
@ -292,6 +309,14 @@ export class Game {
|
|||
}
|
||||
|
||||
if (!this.end) {
|
||||
// If any player (including player 0) can Ron on this discard, open the call window
|
||||
const anyRon = this.canAnyPlayerRon(this.turn);
|
||||
if (anyRon) {
|
||||
this.canCall = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise proceed with normal automatic pon/chii resolution
|
||||
this.checkPon();
|
||||
this.checkForChii();
|
||||
this.canCall = this.canDoAChii().length > 0 || this.canDoAPon();
|
||||
|
|
@ -299,6 +324,29 @@ export class Game {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if any other player can Ron on the last discard performed by discardPlayer.
|
||||
* This builds a simulated hand for each candidate player to avoid mutating state.
|
||||
*/
|
||||
private canAnyPlayerRon(discardPlayer: number): boolean {
|
||||
const d = this.discards[discardPlayer];
|
||||
if (!d || d.length === 0) return false;
|
||||
const last = d[d.length - 1];
|
||||
|
||||
for (let p = 0; p < GAME_CONSTANTS.PLAYERS; p++) {
|
||||
if (p === discardPlayer) continue;
|
||||
const sim = new Hand();
|
||||
for (const t of this.hands[p].getTiles()) {
|
||||
sim.push(new Tile(t.getFamily(), t.getValue(), t.isRed()));
|
||||
}
|
||||
sim.push(new Tile(last.getFamily(), last.getValue(), last.isRed()));
|
||||
sim.sort();
|
||||
if (sim.toGroup() !== undefined) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private checkForChii(): void {
|
||||
if (this.turn === 3) return;
|
||||
|
||||
|
|
@ -519,13 +567,30 @@ export class Game {
|
|||
if (this.chooseChii) {
|
||||
drawChiis(this.staticCtx, this.getChii(0));
|
||||
} else {
|
||||
// Compute availability of ron/tsumo for player 0
|
||||
const canTsumoLocal = this.hasPicked && this.hasWin(0);
|
||||
let canRonLocal = false;
|
||||
if (this.lastDiscard !== undefined && this.lastDiscard !== 0) {
|
||||
const d = this.discards[this.lastDiscard];
|
||||
if (d && d.length > 0) {
|
||||
const last = d[d.length - 1];
|
||||
const sim = new Hand();
|
||||
for (const t of this.hands[0].getTiles()) {
|
||||
sim.push(new Tile(t.getFamily(), t.getValue(), t.isRed()));
|
||||
}
|
||||
sim.push(new Tile(last.getFamily(), last.getValue(), last.isRed()));
|
||||
sim.sort();
|
||||
canRonLocal = sim.toGroup() !== undefined;
|
||||
}
|
||||
}
|
||||
|
||||
drawButtons(
|
||||
this.staticCtx,
|
||||
this.canDoAChii().length > 0,
|
||||
this.canDoAPon(),
|
||||
false && this.level > 1,
|
||||
false && this.level > 0,
|
||||
false && this.level > 0
|
||||
canRonLocal,
|
||||
canTsumoLocal
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue