Riichi/frontend/pages/riichi/chap2.html
2026-02-26 21:12:56 +01:00

308 lines
No EOL
9.2 KiB
HTML

<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Tuto Riichi</title>
<link rel="stylesheet" href="/frontend/css/style.css">
<link rel="stylesheet" href="/frontend/css/text.css">
<link rel="stylesheet" href="/frontend/css/speech-bubble.css">
<link rel="stylesheet" href="/frontend/css/hand.css">
<style>
#menu {
position: relative;
z-index: 10;
}
#mascotte {
position: absolute;
top: 670px;
right: 100px;
z-index: 999;
transform: scaleX(-1);
cursor: pointer;
}
#mascotte img {
width: 250px;
height: auto;
display: block;
}
.speech-bubble {
position: absolute;
top: 350px;
right: 170px;
z-index: 1;
display: none;
}
.speech-bubble.visible {
display: flex;
}
#tiles-display {
padding: 20px;
max-width: 900px;
margin: 20px auto;
display: grid;
grid-template-columns: 100px 1fr;
gap: 30px;
align-items: start;
}
.section-title {
grid-column: 1 / -1;
color: #ffffff;
font-size: 1.5rem;
margin: 20px 0 10px 0;
font-weight: bold;
}
.hands-container {
grid-column: 1 / -1;
display: flex;
flex-direction: column;
gap: 30px;
justify-content: flex-start;
}
.hands-container .hand-display {
grid-column: auto;
margin-bottom: 0;
width: 100%;
}
.tiles-family {
margin-bottom: 0;
grid-column: 1 / -1;
display: grid;
grid-template-columns: 100px 1fr;
gap: 30px;
align-items: start;
}
.tiles-family h3 {
color: #ffffff;
margin: 0;
font-size: 1.2rem;
white-space: nowrap;
}
.tiles-grid {
display: grid;
grid-template-columns: repeat(9, minmax(0, 1fr));
gap: 3px;
}
.tile-item {
padding: 0;
text-align: center;
border-radius: 4px;
display: flex;
justify-content: center;
align-items: center;
}
.tiles-numbers {
grid-column: 2;
display: grid;
grid-template-columns: repeat(9, minmax(0, 1fr));
gap: 3px;
margin-bottom: 20px;
}
.tiles-numbers div {
text-align: center;
font-weight: bold;
color: #ffffff;
padding: 5px 0;
min-height: 50px;
display: flex;
align-items: center;
justify-content: center;
}
</style>
</head>
<body>
<div id="menu"></div>
<h1>Chapitre 2</h1>
<div id="tile-container"></div>
<div id="tiles-display"></div>
<div class="speech-bubble">
<div class="speech-text" id="speech-text"></div>
</div>
<div id="mascotte"></div>
<script src="/frontend/js/fr/texts.js"></script>
<script src="/frontend/js/tile.js"></script>
<script>
// Charger le menu
fetch('/components/menu.html')
.then(r => r.text())
.then(html => document.getElementById('menu').innerHTML = html);
// Afficher la mascotte
const mascolteEl = document.getElementById('mascotte');
mascolteEl.innerHTML = '<img src="/img/tilineau/idle.png" alt="Tilineau">';
// Afficher le texte de bienvenue
document.getElementById('speech-text').innerHTML = texts.riichi.chap2;
// Toggle bulle de dialogue au clic sur la mascotte
const speechBubble = document.querySelector('.speech-bubble');
mascolteEl.addEventListener('click', () => {
speechBubble.classList.toggle('visible');
if (speechBubble.classList.contains('visible')) {
mascolteEl.innerHTML = '<img class="explaining" src="/img/tilineau/speaking.png" alt="Tilineau">';
} else {
mascolteEl.innerHTML = '<img src="/img/tilineau/idle.png" alt="Tilineau">';
}
});
// Créer le titre de section
const tilesDisplay = document.getElementById('tiles-display');
const title = document.createElement('div');
title.className = 'section-title';
title.textContent = 'Exemples de mains';
tilesDisplay.appendChild(title);
// Créer le conteneur des mains
const handsContainer = document.createElement('div');
handsContainer.className = 'hands-container';
tilesDisplay.appendChild(handsContainer);
// Générer et afficher trois mains aléatoires localement
function shuffle(array) {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
}
const allTiles = Tile.generateAll();
function sortHand(hand) {
// Ordre : caractères < ronds < bambous < vents < dragons
const familyOrder = { 'man': 0, 'pin': 1, 'sou': 2, 'wind': 3, 'dragon': 4 };
return hand.sort((a, b) => {
const famA = familyOrder[a.family] ?? 99;
const famB = familyOrder[b.family] ?? 99;
if (famA !== famB) return famA - famB;
if (a.value !== undefined && b.value !== undefined) return a.value - b.value;
if (a.wind !== undefined && b.wind !== undefined) return a.wind - b.wind;
if (a.dragon !== undefined && b.dragon !== undefined) return a.dragon - b.dragon;
return 0;
});
}
for (let i = 0; i < 3; i++) {
const tiles = allTiles.slice();
shuffle(tiles);
const handTilesArr = tiles.slice(0, 13);
sortHand(handTilesArr);
const handDiv = document.createElement('div');
handDiv.className = `hand-display top-label tilt-none`;
const label = document.createElement('div');
label.className = 'hand-label';
label.textContent = `Main ${i + 1}`;
handDiv.appendChild(label);
const container = document.createElement('div');
container.className = 'hand-container';
const handTiles = document.createElement('div');
handTiles.className = 'hand-tiles';
handTilesArr.forEach(tile => {
const tileDiv = document.createElement('div');
tileDiv.className = 'hand-tile-item';
tileDiv.innerHTML = tile.getSVG();
handTiles.appendChild(tileDiv);
});
container.appendChild(handTiles);
handDiv.appendChild(container);
handsContainer.appendChild(handDiv);
}
// Créer le titre pour la main interactive
const interactiveTitle = document.createElement('div');
interactiveTitle.className = 'section-title';
interactiveTitle.textContent = 'Main interactive';
tilesDisplay.appendChild(interactiveTitle);
// Générer et afficher une main interactive locale avec une tuile piochée
let interactiveTiles = allTiles.slice();
shuffle(interactiveTiles);
let interactiveHand = interactiveTiles.slice(0, 13);
sortHand(interactiveHand);
let drawTile = interactiveTiles[13];
let wall = interactiveTiles.slice(14); // Le reste du paquet pour la pioche
function renderInteractiveHand() {
// Nettoyer l'affichage précédent
let oldDiv = document.getElementById('interactive-hand');
if (oldDiv) oldDiv.remove();
const handDiv = document.createElement('div');
handDiv.className = 'hand-display top-label tilt-none';
handDiv.id = 'interactive-hand';
const label = document.createElement('div');
label.className = 'hand-label';
label.textContent = 'Votre main';
handDiv.appendChild(label);
const container = document.createElement('div');
container.className = 'hand-container';
const handTiles = document.createElement('div');
handTiles.className = 'hand-tiles';
handTiles.id = 'interactive-tiles';
interactiveHand.forEach((tile, idx) => {
const tileDiv = document.createElement('div');
tileDiv.className = 'hand-tile-item';
tileDiv.innerHTML = tile.getSVG();
tileDiv.dataset.tileId = tile.id;
tileDiv.style.cursor = 'pointer';
tileDiv.addEventListener('click', () => discardTile(idx));
handTiles.appendChild(tileDiv);
});
container.appendChild(handTiles);
// Draw tile
if (drawTile) {
const drawTileDiv = document.createElement('div');
drawTileDiv.className = 'hand-tile-item draw-tile';
drawTileDiv.innerHTML = drawTile.getSVG();
drawTileDiv.dataset.tileId = drawTile.id;
drawTileDiv.style.cursor = 'pointer';
drawTileDiv.addEventListener('click', () => discardTile('draw'));
container.appendChild(drawTileDiv);
}
handDiv.appendChild(container);
tilesDisplay.appendChild(handDiv);
}
function discardTile(idx) {
let discarded;
if (idx === 'draw') {
// Défausse la tuile piochée
discarded = drawTile;
drawTile = null;
} else {
// Défausse une tuile de la main
discarded = interactiveHand.splice(idx, 1)[0];
if (drawTile) {
interactiveHand.push(drawTile);
drawTile = null;
}
}
// Remettre la tuile défaussée dans la pioche (wall) et mélanger le mur
if (discarded) {
wall.push(discarded);
shuffle(wall);
}
// Trier la main après modification
sortHand(interactiveHand);
// Nouvelle pioche si possible
if (!drawTile && wall.length > 0) {
drawTile = wall.shift();
}
renderInteractiveHand();
}
// Afficher la main interactive au chargement
renderInteractiveHand();
</script>
</body>
</html>