From 2b7547ac35b6122fa63fef140bc35e02c2685f7d Mon Sep 17 00:00:00 2001 From: Didictateur Date: Wed, 25 Mar 2026 10:31:07 +0100 Subject: [PATCH] can now display pon correctly !!! --- frontend/js/game.js | 4 +- frontend/pages/riichi/chap5.html | 245 +++++++++++++++++++++++++++++-- 2 files changed, 238 insertions(+), 11 deletions(-) diff --git a/frontend/js/game.js b/frontend/js/game.js index 61613c1..491d465 100644 --- a/frontend/js/game.js +++ b/frontend/js/game.js @@ -197,8 +197,8 @@ class Game { pon(player, tiles, dir) { const hand = this.hands[player]; - dir = (player - this.turn) % 4; - console.assert(dir == 1); + dir = (player - this.turn + 4) % 4; + console.assert(dir == 1 || dir == 2 ||dir == 3, `Invalid direction: ${dir}`); this.hands[player].makeGroup(tiles, this.discards[this.turn].beeingStollen(), dir); } diff --git a/frontend/pages/riichi/chap5.html b/frontend/pages/riichi/chap5.html index 583690c..9712916 100644 --- a/frontend/pages/riichi/chap5.html +++ b/frontend/pages/riichi/chap5.html @@ -54,7 +54,7 @@ #game-center { position: absolute; - top: 0px; + top: -100px; left: 350px; display: none; align-items: center; @@ -115,7 +115,7 @@ transform: scale(0.98); } #game { - position: relatives; + position: relative; width: var(--game_radius); height: var(--game_radius); } @@ -160,6 +160,92 @@ top: 0; display: inline-block; } + .hand-groups { + display: block; + position: absolute; + pointer-events: none; + height: 50px; + } + .hand-group { + display: flex; + flex-direction: row; + gap: 2px; + align-items: center; + position: absolute; + top: 0; + margin-right: 20px; + z-index: 10; + } + .hand-group:nth-child(1) { z-index: 11; } + .hand-group:nth-child(2) { z-index: 10; } + .hand-group:nth-child(3) { z-index: 9; } + .hand-group:nth-child(4) { z-index: 8; } + .hand-group:nth-child(5) { z-index: 7; } + .hand-group svg { + height: 40px; + width: 30px; + } + .stolen-tile { + display: flex; + align-items: center; + justify-content: center; + width: 30px; + margin: 0; + flex-shrink: 0; + } + .stolen-tile svg { + height: 40px; + width: 30px; + transform: rotate(90deg); + } + + /* Augmenter l'écart quand la tuile penchée est à une extrémité */ + .hand-group.stolen-left .stolen-tile { + margin-right: 5px; + } + + .hand-group.stolen-right .stolen-tile { + margin-left: 5px; + } + + /* Gap différent si la tuile volée est au centre */ + .hand-group.stolen-middle { + gap: 8px; + } + + #groups-1 .stolen-tile svg { + transform: rotate(90deg); + } + + #groups-3 .stolen-tile svg { + transform: rotate(-90deg); + } + + #groups-0 { + bottom: -7%; + right: 10%; + transform: translateX(50%); + } + + #groups-1 { + top: 28%; + right: 12%; + transform: translateX(50%) translateY(-50%) rotate(90deg) scaleX(-1) rotateZ(180deg); + transform-origin: center; + } + + #groups-2 { + top: 27%; + left: 11%; + transform: translateX(-50%) rotate(180deg); + } + + #groups-3 { + top: 106%; + right: 88%; + transform: translateX(50%) translateY(-50%) rotate(-90deg) scaleX(-1) rotateZ(180deg); + transform-origin: center; + } #hand-2 { position: absolute; transform: translate(-50%, -400%) rotate(180deg) translate(0%, 450%); @@ -685,6 +771,144 @@ handDiv.appendChild(handWithDraw); } + renderGroups(); + } + + function renderGroups() { + const gameDiv = document.getElementById('game'); + + // Créer les conteneurs de groupes pour chaque joueur s'ils n'existent pas + for (let i = 0; i < 4; i++) { + if (!document.getElementById(`groups-${i}`)) { + const groupsContainer = document.createElement('div'); + groupsContainer.id = `groups-${i}`; + groupsContainer.className = 'hand-groups'; + gameDiv.appendChild(groupsContainer); + } + } + + // Mettre à jour les groupes pour chaque joueur + for (let i = 0; i < 4; i++) { + const groupsContainer = document.getElementById(`groups-${i}`); + const currentGroupDivs = Array.from(groupsContainer.children); + + // Ajouter les nouveaux groupes + for (let groupIndex = game.hands[i].groups.length - 1; groupIndex >= 0; groupIndex--) { + if (groupIndex >= currentGroupDivs.length) { + // Nouveau groupe à ajouter + const group = game.hands[i].groups[groupIndex]; + const groupDiv = createGroupDiv(group); + // Ajouter au début du conteneur (à gauche) + groupsContainer.insertBefore(groupDiv, groupsContainer.firstChild); + } + } + + // Recalculer toutes les positions + const allGroupDivs = Array.from(groupsContainer.children); + + if (i === 0 || i === 2) { + // Joueurs 0 et 2 : ancrage sur right, positions inversées + let rightOffset = 0; + const groupsToPosition = allGroupDivs.slice().reverse(); + + for (let j = 0; j < groupsToPosition.length; j++) { + const groupDiv = groupsToPosition[j]; + const groupWidth = (groupDiv.children.length) * 30; + + groupDiv.style.right = rightOffset + 'px'; + groupDiv.style.left = 'auto'; + + rightOffset += groupWidth + 12; // +12 pour le gap entre les groupes + } + } else { + // Bots 1 et 3 : ancrage sur left, ordre inversé + let offset = 0; + const groupsToPosition = allGroupDivs.slice().reverse(); + + for (let j = 0; j < groupsToPosition.length; j++) { + const groupDiv = groupsToPosition[j]; + const groupWidth = (groupDiv.children.length) * 30; + + groupDiv.style.left = offset + 'px'; + groupDiv.style.right = 'auto'; + + offset += groupWidth + 12; // +12 pour le gap entre les groupes + } + } + } + } + + function createGroupDiv(group) { + const groupDiv = document.createElement('div'); + groupDiv.className = 'hand-group'; + + // Pour un Pon, placer la tuile volée selon la direction (dir: 1=gauche, 2=milieu, 3=droite) + if (group.stollenTile && group.dir) { + if (group.dir === 1) { + // Tuile volée à gauche + groupDiv.classList.add('stolen-left'); + const stolenDiv = document.createElement('div'); + stolenDiv.innerHTML = group.stollenTile.getSVG(); + stolenDiv.className = 'stolen-tile'; + groupDiv.appendChild(stolenDiv); + + for (let j = 0; j < group.tiles.length; j++) { + const tileDiv = document.createElement('div'); + tileDiv.innerHTML = group.tiles[j].getSVG(); + // Ajouter la classe middle-tile à la tuile du milieu + if (j === Math.floor(group.tiles.length / 2)) { + tileDiv.classList.add('middle-tile'); + } + groupDiv.appendChild(tileDiv); + } + } else if (group.dir === 2) { + // Tuile volée au milieu + groupDiv.classList.add('stolen-middle'); + for (let j = 0; j < group.tiles.length; j++) { + if (j === Math.floor(group.tiles.length / 2)) { + const stolenDiv = document.createElement('div'); + stolenDiv.innerHTML = group.stollenTile.getSVG(); + stolenDiv.className = 'stolen-tile stolen-middle'; + groupDiv.appendChild(stolenDiv); + } + const tileDiv = document.createElement('div'); + tileDiv.innerHTML = group.tiles[j].getSVG(); + groupDiv.appendChild(tileDiv); + } + } else if (group.dir === 3) { + // Tuile volée à droite + groupDiv.classList.add('stolen-right'); + for (let j = 0; j < group.tiles.length; j++) { + const tileDiv = document.createElement('div'); + tileDiv.innerHTML = group.tiles[j].getSVG(); + // Ajouter la classe middle-tile à la tuile du milieu + if (j === Math.floor(group.tiles.length / 2)) { + tileDiv.classList.add('middle-tile'); + } + groupDiv.appendChild(tileDiv); + } + + const stolenDiv = document.createElement('div'); + stolenDiv.innerHTML = group.stollenTile.getSVG(); + stolenDiv.className = 'stolen-tile'; + groupDiv.appendChild(stolenDiv); + } + } else { + // Groupe fermé ou non volé : afficher les tuiles normalement + for (let tile of group.tiles) { + const tileDiv = document.createElement('div'); + tileDiv.innerHTML = tile.getSVG(); + groupDiv.appendChild(tileDiv); + } + } + + return groupDiv; + } + + function renderAll() { + renderHands(); + renderGroups(); + renderDiscards(); } function renderDiscards() { @@ -760,17 +984,18 @@ game.botPlay(); renderDiscards(); - // Vérifier si d'autres bots peuvent faire un pon + // Vérifier si d'autres bots peuvent faire un pon (mais pas sur leur propre défausse) let ponMade = false; for (let player = 1; player < 4; player++) { - if (game.canPon(player)) { + if (player !== game.turn && game.canPon(player)) { // Ce bot fait un pon const lastTile = game.discards[game.turn].tiles[game.discards[game.turn].tiles.length - 1]; const tiles = game.hands[player].tiles.filter(t => t.equals(lastTile)).slice(0, 2); game.pon(player, tiles, (player - game.turn) % 4); game.discards[game.turn].beeingStollen(); await showPonAnimation(player); - game.nextTurn(); + // Après un Pon, le tour passe au joueur qui appelle le Pon + game.turn = player; updateTurnIndicator(); renderHands(); renderDiscards(); @@ -819,17 +1044,18 @@ game.botPlay(); renderDiscards(); - // Vérifier si d'autres bots peuvent faire un pon + // Vérifier si d'autres bots peuvent faire un pon (mais pas sur leur propre défausse) let ponMade = false; for (let player = 1; player < 4; player++) { - if (game.canPon(player)) { + if (player !== game.turn && game.canPon(player)) { // Ce bot fait un pon const lastTile = game.discards[game.turn].tiles[game.discards[game.turn].tiles.length - 1]; const tiles = game.hands[player].tiles.filter(t => t.equals(lastTile)).slice(0, 2); game.pon(player, tiles, (player - game.turn) % 4); game.discards[game.turn].beeingStollen(); await showPonAnimation(player); - game.nextTurn(); + // Après un Pon, le tour passe au joueur qui appelle le Pon + game.turn = player; updateTurnIndicator(); renderHands(); renderDiscards(); @@ -930,7 +1156,8 @@ game.pon(0, tiles, (0 - game.turn) % 4); game.discards[game.turn].beeingStollen(); await showPonAnimation(0); - game.nextTurn(); + // Après un Pon, le tour passe au joueur qui appelle le Pon + game.turn = 0; hideCallPanel(); updateTurnIndicator(); renderHands();