import "./tile.js"; class Group { constructor(tiles, stollenTile = null, dir = null) { this.tiles = tiles; this.stollenTile = stollenTile; this.dir = dir; // 1 for left, 2 for middle, 3 for right } } class Hand { constructor(tiles = []) { this.tiles = tiles; this.groups = []; this.drawn= null; } drawTile(tile) { this.drawn = tile; } discard(k) { if (k === this.tiles.length) { const tile = this.drawn; this.drawn = null; return tile; } else { const tile = this.tiles[k]; this.tiles.splice(k, 1); return tile; } } sort() { this.tiles.sort((a, b) => { if (a.lessThan(b)) return -1; if (b.lessThan(a)) return 1; return 0; }); } flatten() { if (this.drawn) { this.tiles.push(this.drawn); } this.drawn = null; this.sort(); } makeGroup(tiles, stollenTile = null, dir = null) { const group = new Group(tiles, stollenTile, dir); this.groups.push(group); for (let tile of tiles) { const index = this.tiles.findIndex(t => t.equals(tile)); if (index !== -1) { this.tiles.splice(index, 1); } } this.flatten(); } } class Draw { constructor() { this.tiles = Tile.generateAll(); this.shuffle(); } shuffle() { for (let i = this.tiles.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [this.tiles[i], this.tiles[j]] = [this.tiles[j], this.tiles[i]]; } } drawTile() { return this.tiles.pop(); } drawHand() { const handTiles = []; for (let i = 0; i < 13; i++) { handTiles.push(this.drawTile()); } return new Hand(handTiles); } } class Discard { constructor() { this.tiles = []; this.hiddenTiles = []; } add(tile) { this.tiles.push(tile); } beeingStollen() { this.hiddenTiles.push(this.tiles.pop()); return this.hiddenTiles[this.hiddenTiles.length - 1]; } isIn(tile) { return this.tiles.some(t => t.equals(tile)) || this.hiddenTiles.some(t => t.equals(tile)); } } class Game { constructor() { this.discards = [ new Discard(), new Discard(), new Discard(), new Discard() ]; this.wall = new Draw(); this.hands = [ this.wall.drawHand(), this.wall.drawHand(), this.wall.drawHand(), this.wall.drawHand() ]; for (let hand of this.hands) { hand.sort(); } this.firstDealer = Math.floor(Math.random() * 4) * 0; this.turn = this.firstDealer; this.repeat = 0; this.draw(this.turn); } newDeal(hasRepeat = false) { this.discards = [ new Discard(), new Discard(), new Discard(), new Discard() ]; this.wall = new Draw(); this.hands = [ this.wall.drawHand(), this.wall.drawHand(), this.wall.drawHand(), this.wall.drawHand() ]; if (!hasRepeat) { this.turn = (this.firstDealer + 1) % 4; } else { this.repeat++; } } nextTurn() { this.turn = (this.turn + 1) % 4; } draw(player) { this.hands[player].drawTile(this.wall.drawTile()); } discard(player, k) { if (player === this.turn) { const tile = this.hands[player].discard(k); this.discards[player].add(tile); this.hands[player].flatten(); } } chii(player, tiles, dir) { const hand = this.hands[player]; dir = (player - this.turn) % 4; console.assert(dir == 1); this.hands[player].makeGroup(tiles, this.discards[player].beingStollen(), dir); } pon(player, tiles, dir) { const hand = this.hands[player]; dir = (player - this.turn) % 4; console.assert(dir == 1); this.hands[player].makeGroup(tiles, this.discards[player].beingStollen(), dir); } botPlay() { // Le bot défausse une tuile au hasard (supposant qu'il a déjà pioché) const hand = this.hands[this.turn]; const randomIndex = Math.floor(Math.random() * (hand.tiles.length + (hand.drawn ? 1 : 0))); this.discard(this.turn, randomIndex); } } export { Discard, Draw, Game, Group, Hand };