fixed spam click

This commit is contained in:
Didictateur 2026-03-14 12:06:24 +01:00
parent 8d04e99a85
commit bf3f3a2879
2 changed files with 148 additions and 5 deletions

View file

@ -192,14 +192,19 @@ class Game {
const hand = this.hands[player];
dir = (player - this.turn) % 4;
console.assert(dir == 1);
this.hands[player].makeGroup(tiles, this.discards[player].beingStollen(), dir);
this.hands[player].makeGroup(tiles, this.discards[this.turn].beeingStollen(), 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);
this.hands[player].makeGroup(tiles, this.discards[this.turn].beeingStollen(), dir);
}
canPon(player) {
const lastTile = this.discards[this.turn].tiles[this.discards[this.turn].tiles.length - 1];
return this.hands[player].tiles.filter(t => t.equals(lastTile)).length >= 2;
}
botPlay() {

View file

@ -296,6 +296,63 @@
left: 37%;
width: 250px;
}
#call-panel {
position: fixed;
bottom: 20px;
left: 50%;
transform: translateX(-50%);
display: none;
gap: 10px;
z-index: 100;
}
.call-button {
padding: 16px 32px;
font-size: 1.3em;
font-weight: bold;
border: none;
border-radius: 8px;
cursor: pointer;
color: white;
transition: all 0.3s ease;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
}
.call-button:hover {
transform: scale(1.05);
box-shadow: 0 6px 12px rgba(0, 0, 0, 0.3);
}
.call-button:active {
transform: scale(0.95);
}
/* Code couleur pour les 6 appels */
#pon-button {
background-color: #FF6B6B; /* Rouge */
}
#chii-button {
background-color: #4ECDC4; /* Turquoise */
}
#kan-button {
background-color: #95E1D3; /* Menthe */
}
#tsumo-button {
background-color: #FFD700; /* Or */
color: #333;
}
#ron-button {
background-color: #9B59B6; /* Violet */
}
#skip-button {
background-color: #808080; /* Gris */
}
</style>
</head>
<body>
@ -330,6 +387,15 @@
</div>
</div>
<div id="call-panel">
<button id="pon-button" class="call-button">Pon</button>
<button id="chii-button" class="call-button" style="display: none;">Chii</button>
<button id="kan-button" class="call-button" style="display: none;">Kan</button>
<button id="tsumo-button" class="call-button" style="display: none;">Tsumo</button>
<button id="ron-button" class="call-button" style="display: none;">Ron</button>
<button id="skip-button" class="call-button">Skip</button>
</div>
<script src="/frontend/js/fr/texts.js"></script>
<script src="/frontend/js/tile.js"></script>
<script type="module">
@ -353,6 +419,7 @@
// Déclarer les variables et fonctions ici pour qu'elles soient accessibles partout
let game;
let isDistributing = false;
let canPlayerAct = false;
// Charger le menu
fetch('/components/menu.html')
.then(r => r.text())
@ -485,6 +552,7 @@
renderHands();
updateTurnIndicator();
isDistributing = false;
canPlayerAct = true;
}
function renderHands() {
@ -511,12 +579,13 @@
const handleClick = (() => {
const tileToDiscard = tile;
return () => {
// Ne rien faire pendant la distribution
if (isDistributing) return;
// Ne rien faire pendant la distribution ou si ce n'est pas son tour
if (isDistributing || !canPlayerAct) return;
// Trouver l'index actuel de la tuile
const currentIdx = game.hands[0].tiles.findIndex(t => t === tileToDiscard);
if (currentIdx !== -1) {
canPlayerAct = false;
game.discard(0, currentIdx);
game.nextTurn();
updateTurnIndicator();
@ -549,7 +618,11 @@
const drawnTile = game.hands[i].drawn;
const handleDrawnClick = (() => {
return () => {
// Ne rien faire si ce n'est pas son tour ou pendant la distribution
if (isDistributing || !canPlayerAct) return;
// Défausser la tuile piochée (index === tiles.length)
canPlayerAct = false;
game.discard(0, game.hands[0].tiles.length);
game.nextTurn();
updateTurnIndicator();
@ -598,6 +671,9 @@
}
async function playBotsSequentially() {
// Le joueur ne peut plus agir pendant que les bots jouent
canPlayerAct = false;
// Les bots jouent après le joueur humain
while (game.turn !== 0) {
await new Promise(resolve => setTimeout(resolve, 500));
@ -612,9 +688,12 @@
renderHands();
renderDiscards();
}
// C'est au tour du joueur - il pioche d'abord
await new Promise(resolve => setTimeout(resolve, 500));
game.draw(0);
renderHands();
renderDiscards();
canPlayerAct = true;
showCallPanel();
}
function updateTurnIndicator() {
@ -627,6 +706,65 @@
}
}
}
function hideCallPanel() {
document.getElementById('call-panel').style.display = 'none';
}
function showCallPanel() {
const callPanel = document.getElementById('call-panel');
// Ne pas afficher les appels si c'est le joueur qui vient de défausser
if (game.turn === 0) {
callPanel.style.display = 'none';
return;
}
// Le joueur peut agir
canPlayerAct = true;
// Vérifier les appels possibles pour le joueur
const canPon = game.canPon(0);
// Pour l'instant, on implémente seulement Pon
document.getElementById('pon-button').style.display = canPon ? 'block' : 'none';
// Cacher les autres appels pour l'instant
document.getElementById('chii-button').style.display = 'none';
document.getElementById('kan-button').style.display = 'none';
document.getElementById('tsumo-button').style.display = 'none';
document.getElementById('ron-button').style.display = 'none';
// Afficher le panel si au moins un appel est possible
if (canPon) {
callPanel.style.display = 'flex';
} else {
callPanel.style.display = 'none';
}
}
// Gestionnaires des boutons d'appels
document.getElementById('pon-button').addEventListener('click', () => {
if (!canPlayerAct) return;
canPlayerAct = false;
const lastTile = game.discards[game.turn].tiles[game.discards[game.turn].tiles.length - 1];
const tiles = game.hands[0].tiles.filter(t => t.equals(lastTile)).slice(0, 2);
game.pon(0, tiles, (0 - game.turn) % 4);
game.discards[game.turn].beeingStollen();
game.nextTurn();
hideCallPanel();
updateTurnIndicator();
renderHands();
renderDiscards();
playBotsSequentially();
});
document.getElementById('skip-button').addEventListener('click', () => {
if (!canPlayerAct) return;
canPlayerAct = false;
hideCallPanel();
playBotsSequentially();
});
renderHands();
updateTurnIndicator();