exemples de mains dans chap 2
This commit is contained in:
parent
c471c84239
commit
d23d6a24f7
10 changed files with 571 additions and 2 deletions
|
|
@ -2,6 +2,8 @@ from flask import Flask, jsonify, request
|
||||||
from flask_cors import CORS
|
from flask_cors import CORS
|
||||||
|
|
||||||
from game.tile import *
|
from game.tile import *
|
||||||
|
from game.hand import *
|
||||||
|
from game.game import *
|
||||||
from game.error import *
|
from game.error import *
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
|
|
@ -38,6 +40,46 @@ def get_tile(tile_id):
|
||||||
'svg': svg
|
'svg': svg
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@app.route('/api/random_hand', methods=['GET'])
|
||||||
|
def get_random_hand():
|
||||||
|
"""Récupère une main aléatoire de 13 tuiles"""
|
||||||
|
hand = Hand.random()
|
||||||
|
hand_data = [
|
||||||
|
{
|
||||||
|
'id': tile.id,
|
||||||
|
'family': str(tile.family),
|
||||||
|
'value': str(tile.value),
|
||||||
|
'svg': tile.get_img()
|
||||||
|
}
|
||||||
|
for tile in hand.tiles
|
||||||
|
]
|
||||||
|
return jsonify({'hand': hand_data})
|
||||||
|
|
||||||
|
@app.route('/api/hand_with_draw', methods=['GET'])
|
||||||
|
def get_hand_with_draw():
|
||||||
|
"""Crée une partie et retourne le hand_player avec une tuile piochée"""
|
||||||
|
game = Game()
|
||||||
|
game.draw_tile(game.hand_player)
|
||||||
|
|
||||||
|
hand_data = [
|
||||||
|
{
|
||||||
|
'id': tile.id,
|
||||||
|
'family': str(tile.family),
|
||||||
|
'value': str(tile.value),
|
||||||
|
'svg': tile.get_img()
|
||||||
|
}
|
||||||
|
for tile in game.hand_player.tiles
|
||||||
|
]
|
||||||
|
|
||||||
|
draw_data = {
|
||||||
|
'id': game.hand_player.draw.id,
|
||||||
|
'family': str(game.hand_player.draw.family),
|
||||||
|
'value': str(game.hand_player.draw.value),
|
||||||
|
'svg': game.hand_player.draw.get_img()
|
||||||
|
} if game.hand_player.draw else None
|
||||||
|
|
||||||
|
return jsonify({'hand': hand_data, 'draw': draw_data})
|
||||||
|
|
||||||
# ============== POST ================
|
# ============== POST ================
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
|
||||||
19
backend/src/game/game.py
Normal file
19
backend/src/game/game.py
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
from .hand import *
|
||||||
|
from .wall import *
|
||||||
|
|
||||||
|
import random as rd
|
||||||
|
|
||||||
|
class Game:
|
||||||
|
def __init__(self):
|
||||||
|
self.wall = Wall()
|
||||||
|
|
||||||
|
self.hand_player = self.wall.draw_hand()
|
||||||
|
self.bot_hands = [self.wall.draw_hand() for _ in range(3)]
|
||||||
|
|
||||||
|
def draw_tile(self, hand: Hand):
|
||||||
|
tile = self.wall.draw()
|
||||||
|
hand.draw_tile(tile)
|
||||||
|
|
||||||
|
def put_tile(self, hand: Hand, id: int):
|
||||||
|
self.wall.tiles.append(hand.discard_tile(id))
|
||||||
|
self.wall.shuffle()
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
from .tile import *
|
||||||
|
|
||||||
|
import random as rd
|
||||||
|
|
||||||
|
class Hand:
|
||||||
|
def __init__(self, tiles: list[Tile], draw: Tile|None = None):
|
||||||
|
self.tiles: list[Tile] = tiles
|
||||||
|
self.draw: Tile|None = draw
|
||||||
|
|
||||||
|
def sort(self) -> None:
|
||||||
|
self.tiles.sort()
|
||||||
|
|
||||||
|
def fold(self) -> None:
|
||||||
|
if self.draw is not None:
|
||||||
|
self.tiles.append(self.draw)
|
||||||
|
self.draw = None
|
||||||
|
self.sort()
|
||||||
|
|
||||||
|
def draw_tile(self, tile: Tile) -> None:
|
||||||
|
self.draw = tile
|
||||||
|
|
||||||
|
def discard_tile(self, id: int) -> Tile|None:
|
||||||
|
if self.draw is not None and self.draw.id == id:
|
||||||
|
draw = self.draw
|
||||||
|
self.draw = None
|
||||||
|
return draw
|
||||||
|
for i, tile in enumerate(self.tiles):
|
||||||
|
if tile.id == id:
|
||||||
|
return self.tiles.pop(i)
|
||||||
|
return None
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def random() -> Hand:
|
||||||
|
tiles = Tile.generateAll()
|
||||||
|
rd.shuffle(tiles)
|
||||||
|
hand = Hand(tiles[:13])
|
||||||
|
hand.sort()
|
||||||
|
return hand
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
from game.error import *
|
from game.error import *
|
||||||
from game.value import *
|
from game.value import *
|
||||||
|
from functools import total_ordering
|
||||||
|
|
||||||
|
@total_ordering
|
||||||
class Tile:
|
class Tile:
|
||||||
def __init__(self, family, value, id):
|
def __init__(self, family, value, id):
|
||||||
self.family = family
|
self.family = family
|
||||||
|
|
@ -74,7 +76,11 @@ class Tile:
|
||||||
return self.value == other.value and self.family == other.family
|
return self.value == other.value and self.family == other.family
|
||||||
|
|
||||||
def __lt__(self, other: Tile):
|
def __lt__(self, other: Tile):
|
||||||
return (self.family < other.family) or (self.family == other.family and self.value < other.value)
|
if self.family.value != other.family.value:
|
||||||
|
return self.family.value < other.family.value
|
||||||
|
if hasattr(self.value, 'value'):
|
||||||
|
return self.value.value < other.value.value
|
||||||
|
return self.value < other.value
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def generateAll():
|
def generateAll():
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
from .tile import *
|
||||||
|
from .hand import *
|
||||||
|
|
||||||
|
import random as rd
|
||||||
|
|
||||||
|
class Wall:
|
||||||
|
def __init__(self):
|
||||||
|
self.tiles = Tile.generateAll()
|
||||||
|
self.shuffle()
|
||||||
|
|
||||||
|
def shuffle(self):
|
||||||
|
rd.shuffle(self.tiles)
|
||||||
|
|
||||||
|
def draw(self) -> Tile:
|
||||||
|
if len(self.tiles) == 0:
|
||||||
|
raise Exception("No more tiles in the wall")
|
||||||
|
return self.tiles.pop()
|
||||||
|
|
||||||
|
def draw_hand(self) -> Hand:
|
||||||
|
hand_tiles = [self.draw() for _ in range(13)]
|
||||||
|
hand_tiles.sort()
|
||||||
|
return Hand(hand_tiles)
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
<a href="#">Riichi</a>
|
<a href="#">Riichi</a>
|
||||||
<ul class="submenu">
|
<ul class="submenu">
|
||||||
<li><a href="/frontend/pages/chap1.html">Chapitre 1 : Les tuiles</a></li>
|
<li><a href="/frontend/pages/chap1.html">Chapitre 1 : Les tuiles</a></li>
|
||||||
<li><a href="">Chapitre 2 : La main</a></li>
|
<li><a href="/frontend/pages/chap2.html">Chapitre 2 : La main</a></li>
|
||||||
<li><a href="">Chapitre 3 : Les groupes</a></li>
|
<li><a href="">Chapitre 3 : Les groupes</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
|
|
|
||||||
102
frontend/css/hand.css
Normal file
102
frontend/css/hand.css
Normal file
|
|
@ -0,0 +1,102 @@
|
||||||
|
/* Hand Display Styles */
|
||||||
|
|
||||||
|
.hand-display {
|
||||||
|
margin-bottom: 30px;
|
||||||
|
grid-column: 1 / -1;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 100px 1fr;
|
||||||
|
gap: 30px;
|
||||||
|
align-items: start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hand-label {
|
||||||
|
color: #ffffff;
|
||||||
|
margin: 0;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hand-tiles {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(13, minmax(0, 1fr));
|
||||||
|
gap: 3px;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hand-tile-item {
|
||||||
|
padding: 0;
|
||||||
|
text-align: center;
|
||||||
|
border-radius: 4px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hand container - gère l'affichage des tuiles et du draw */
|
||||||
|
.hand-container {
|
||||||
|
display: flex;
|
||||||
|
gap: 20px;
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hand-tile-item.draw-tile {
|
||||||
|
/* Le draw s'affiche simplement à droite grâce à flex */
|
||||||
|
flex: 0 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Orientation variations */
|
||||||
|
.hand-display.vertical {
|
||||||
|
grid-template-columns: 100px 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hand-display.horizontal {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hand-display.horizontal .hand-label {
|
||||||
|
grid-column: 1;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hand-display.horizontal .hand-tiles {
|
||||||
|
grid-column: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Position variations */
|
||||||
|
.hand-display.left-label {
|
||||||
|
grid-template-columns: 100px 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hand-display.top-label {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hand-display.top-label .hand-label {
|
||||||
|
grid-column: 1;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hand-display.top-label .hand-tiles {
|
||||||
|
grid-column: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tilt variations */
|
||||||
|
.hand-display.tilt-left {
|
||||||
|
transform: rotate(90deg);
|
||||||
|
transform-origin: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hand-display.tilt-right {
|
||||||
|
transform: rotate(-90deg);
|
||||||
|
transform-origin: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hand-display.tilt-upside-down {
|
||||||
|
transform: rotate(180deg);
|
||||||
|
transform-origin: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hand-display.tilt-none {
|
||||||
|
transform: rotate(0deg);
|
||||||
|
transform-origin: center;
|
||||||
|
}
|
||||||
|
|
@ -32,6 +32,19 @@ const texts = {
|
||||||
<br>
|
<br>
|
||||||
Les vents et dragons quant à eux n'ont pas de numéro. On les appelle<br>
|
Les vents et dragons quant à eux n'ont pas de numéro. On les appelle<br>
|
||||||
les honneurs, et ne sont caractérisés que par leur nom.
|
les honneurs, et ne sont caractérisés que par leur nom.
|
||||||
|
`,
|
||||||
|
chap2:`
|
||||||
|
Les joueurs ne se contentent pas de regarder les tuiles. Ils<br>
|
||||||
|
constituent une main composée de 13 tuiles.<br>
|
||||||
|
<br>
|
||||||
|
Au début de leur tour, ils commencent par récupérer une<br>
|
||||||
|
tuile, soit du mur (la pioche), soit de la défausse d'un<br>
|
||||||
|
adversaire (nous verrons les détails plus tard).<br>
|
||||||
|
<br>
|
||||||
|
Après avoir récupéré une tuile, le joueur doit se défausser<br>
|
||||||
|
d'une tuile de sa main, pour revenir à 13 tuiles. C'est à ce<br>
|
||||||
|
moment que les autres joueurs peuvent réagir à la tuile<br>
|
||||||
|
défaussée, en la récupérant pour compléter leur propre main.
|
||||||
`
|
`
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
64
frontend/js/hand.js
Normal file
64
frontend/js/hand.js
Normal file
|
|
@ -0,0 +1,64 @@
|
||||||
|
/**
|
||||||
|
* Hand Display Object
|
||||||
|
* Affiche une main de Riichi avec options de position et orientation
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Hand {
|
||||||
|
constructor(options = {}) {
|
||||||
|
this.label = options.label || 'Main';
|
||||||
|
this.position = options.position || 'left-label'; // 'left-label' or 'top-label'
|
||||||
|
this.tilt = options.tilt || 'none'; // 'none', 'left' (90deg), 'right' (-90deg), 'upside-down' (180deg)
|
||||||
|
this.containerId = options.containerId || 'tiles-display';
|
||||||
|
this.apiUrl = options.apiUrl || 'http://localhost:5000/api/random_hand';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Récupère une main aléatoire et l'affiche
|
||||||
|
*/
|
||||||
|
async render() {
|
||||||
|
try {
|
||||||
|
const response = await fetch(this.apiUrl);
|
||||||
|
const data = await response.json();
|
||||||
|
this.displayHand(data.hand);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Erreur lors de la récupération de la main:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Affiche la main dans le DOM
|
||||||
|
* @param {Array} tiles - Tableau des tuiles à afficher
|
||||||
|
*/
|
||||||
|
displayHand(tiles) {
|
||||||
|
const container = document.getElementById(this.containerId);
|
||||||
|
|
||||||
|
// Créer la section de la main
|
||||||
|
const handDiv = document.createElement('div');
|
||||||
|
const classNames = `hand-display ${this.position}`;
|
||||||
|
if (this.tilt !== 'none') {
|
||||||
|
handDiv.className = `${classNames} tilt-${this.tilt}`;
|
||||||
|
} else {
|
||||||
|
handDiv.className = classNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Créer le label
|
||||||
|
const label = document.createElement('div');
|
||||||
|
label.className = 'hand-label';
|
||||||
|
label.textContent = this.label;
|
||||||
|
handDiv.appendChild(label);
|
||||||
|
|
||||||
|
// Créer la grille de tuiles
|
||||||
|
const handTiles = document.createElement('div');
|
||||||
|
handTiles.className = 'hand-tiles';
|
||||||
|
|
||||||
|
tiles.forEach(tile => {
|
||||||
|
const tileDiv = document.createElement('div');
|
||||||
|
tileDiv.className = 'hand-tile-item';
|
||||||
|
tileDiv.innerHTML = tile.svg;
|
||||||
|
handTiles.appendChild(tileDiv);
|
||||||
|
});
|
||||||
|
|
||||||
|
handDiv.appendChild(handTiles);
|
||||||
|
container.appendChild(handDiv);
|
||||||
|
}
|
||||||
|
}
|
||||||
263
frontend/pages/chap2.html
Normal file
263
frontend/pages/chap2.html
Normal file
|
|
@ -0,0 +1,263 @@
|
||||||
|
<!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/speech-bubble.css">
|
||||||
|
<link rel="stylesheet" href="../../frontend/css/hand.css">
|
||||||
|
<style>
|
||||||
|
#menu {
|
||||||
|
position: relative;
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
#mascotte {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0px;
|
||||||
|
right: 160px;
|
||||||
|
z-index: 999;
|
||||||
|
transform: scaleX(-1);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
#mascotte img {
|
||||||
|
width: 250px;
|
||||||
|
height: auto;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.speech-bubble {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 320px;
|
||||||
|
right: 170px;
|
||||||
|
z-index: 998;
|
||||||
|
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>
|
||||||
|
<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/hand.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/speaking.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/explaining.png" alt="Tilineau">';
|
||||||
|
} else {
|
||||||
|
mascolteEl.innerHTML = '<img src="../../img/tilineau/speaking.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);
|
||||||
|
|
||||||
|
// Créer et afficher trois mains aléatoires
|
||||||
|
for (let i = 0; i < 3; i++) {
|
||||||
|
const hand = new Hand({
|
||||||
|
label: `Main ${i + 1}`,
|
||||||
|
position: 'top-label',
|
||||||
|
tilt: 'none',
|
||||||
|
containerId: 'tiles-display'
|
||||||
|
});
|
||||||
|
|
||||||
|
// Modifier temporairement le containerId pour ajouter à handsContainer
|
||||||
|
hand.containerId = null;
|
||||||
|
|
||||||
|
fetch(hand.apiUrl)
|
||||||
|
.then(r => r.json())
|
||||||
|
.then(data => {
|
||||||
|
const handDiv = document.createElement('div');
|
||||||
|
handDiv.className = `hand-display ${hand.position} tilt-${hand.tilt}`;
|
||||||
|
|
||||||
|
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';
|
||||||
|
|
||||||
|
data.hand.forEach(tile => {
|
||||||
|
const tileDiv = document.createElement('div');
|
||||||
|
tileDiv.className = 'hand-tile-item';
|
||||||
|
tileDiv.innerHTML = tile.svg;
|
||||||
|
handTiles.appendChild(tileDiv);
|
||||||
|
});
|
||||||
|
|
||||||
|
container.appendChild(handTiles);
|
||||||
|
handDiv.appendChild(container);
|
||||||
|
handsContainer.appendChild(handDiv);
|
||||||
|
})
|
||||||
|
.catch(error => console.error('Erreur:', error));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Créer le titre pour la main interactive
|
||||||
|
const interactiveTitle = document.createElement('div');
|
||||||
|
interactiveTitle.className = 'section-title';
|
||||||
|
interactiveTitle.textContent = 'Main interactive';
|
||||||
|
tilesDisplay.appendChild(interactiveTitle);
|
||||||
|
|
||||||
|
// Créer et afficher la main interactive avec une tuile piochée
|
||||||
|
fetch('http://localhost:5000/api/hand_with_draw')
|
||||||
|
.then(r => r.json())
|
||||||
|
.then(data => {
|
||||||
|
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);
|
||||||
|
|
||||||
|
// Conteneur qui gère l'affichage avec flex (gère auto le draw si présent)
|
||||||
|
const container = document.createElement('div');
|
||||||
|
container.className = 'hand-container';
|
||||||
|
|
||||||
|
// Créer le grid des 13 tuiles
|
||||||
|
const handTiles = document.createElement('div');
|
||||||
|
handTiles.className = 'hand-tiles';
|
||||||
|
handTiles.id = 'interactive-tiles';
|
||||||
|
|
||||||
|
data.hand.forEach(tile => {
|
||||||
|
const tileDiv = document.createElement('div');
|
||||||
|
tileDiv.className = 'hand-tile-item';
|
||||||
|
tileDiv.innerHTML = tile.svg;
|
||||||
|
handTiles.appendChild(tileDiv);
|
||||||
|
});
|
||||||
|
|
||||||
|
container.appendChild(handTiles);
|
||||||
|
|
||||||
|
const drawTileDiv = document.createElement('div');
|
||||||
|
drawTileDiv.className = 'hand-tile-item draw-tile';
|
||||||
|
drawTileDiv.innerHTML = data.draw.svg;
|
||||||
|
container.appendChild(drawTileDiv);
|
||||||
|
|
||||||
|
handDiv.appendChild(container);
|
||||||
|
tilesDisplay.appendChild(handDiv);
|
||||||
|
})
|
||||||
|
.catch(error => console.error('Erreur:', error));
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Loading…
Reference in a new issue