diff --git a/backend/src/api.py b/backend/src/api.py index ba5f1a4..3c8a19b 100644 --- a/backend/src/api.py +++ b/backend/src/api.py @@ -10,6 +10,7 @@ app = Flask(__name__) CORS(app) tiles = Tile.generateAll() +current_game = None # Stockage de la partie actuelle # ============= GET ================ @app.route('/api/tiles', methods=['GET']) @@ -58,8 +59,9 @@ def get_random_hand(): @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) + global current_game + current_game = Game() + current_game.draw_tile(current_game.hand_player) hand_data = [ { @@ -68,15 +70,51 @@ def get_hand_with_draw(): 'value': str(tile.value), 'svg': tile.get_img() } - for tile in game.hand_player.tiles + for tile in current_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 + 'id': current_game.hand_player.draw.id, + 'family': str(current_game.hand_player.draw.family), + 'value': str(current_game.hand_player.draw.value), + 'svg': current_game.hand_player.draw.get_img() + } if current_game.hand_player.draw else None + + return jsonify({'hand': hand_data, 'draw': draw_data}) + +@app.route('/api/discard', methods=['POST']) +def discard_tile(): + """Défausse une tuile de la main du joueur et pioche une nouvelle""" + global current_game + if current_game is None: + return jsonify({'error': 'Aucune partie en cours'}), 400 + + data = request.json + tile_id = data.get('tile_id') + + if tile_id is None: + return jsonify({'error': 'tile_id manquant'}), 400 + + current_game.put_tile(current_game.hand_player, tile_id) + current_game.draw_tile(current_game.hand_player) + + # Retourner la main mise à jour + hand_data = [ + { + 'id': tile.id, + 'family': str(tile.family), + 'value': str(tile.value), + 'svg': tile.get_img() + } + for tile in current_game.hand_player.tiles + ] + + draw_data = { + 'id': current_game.hand_player.draw.id, + 'family': str(current_game.hand_player.draw.family), + 'value': str(current_game.hand_player.draw.value), + 'svg': current_game.hand_player.draw.get_img() + } if current_game.hand_player.draw else None return jsonify({'hand': hand_data, 'draw': draw_data}) diff --git a/backend/src/game/hand.py b/backend/src/game/hand.py index af3bbce..ff90535 100644 --- a/backend/src/game/hand.py +++ b/backend/src/game/hand.py @@ -23,10 +23,16 @@ class Hand: if self.draw is not None and self.draw.id == id: draw = self.draw self.draw = None + self.fold() + self.sort() return draw for i, tile in enumerate(self.tiles): if tile.id == id: - return self.tiles.pop(i) + t = self.tiles.pop(i) + self.fold() + self.sort() + return t + self.sort() return None @staticmethod diff --git a/frontend/pages/chap2.html b/frontend/pages/chap2.html index 5ffa693..46f2900 100644 --- a/frontend/pages/chap2.html +++ b/frontend/pages/chap2.html @@ -244,6 +244,9 @@ const tileDiv = document.createElement('div'); tileDiv.className = 'hand-tile-item'; tileDiv.innerHTML = tile.svg; + tileDiv.dataset.tileId = tile.id; + tileDiv.style.cursor = 'pointer'; + tileDiv.addEventListener('click', () => discardTile(tile.id, tileDiv)); handTiles.appendChild(tileDiv); }); @@ -252,12 +255,79 @@ const drawTileDiv = document.createElement('div'); drawTileDiv.className = 'hand-tile-item draw-tile'; drawTileDiv.innerHTML = data.draw.svg; + drawTileDiv.dataset.tileId = data.draw.id; + drawTileDiv.style.cursor = 'pointer'; + drawTileDiv.addEventListener('click', () => discardTile(data.draw.id, drawTileDiv)); container.appendChild(drawTileDiv); handDiv.appendChild(container); tilesDisplay.appendChild(handDiv); }) .catch(error => console.error('Erreur:', error)); + + // Fonction pour défausser une tuile + async function discardTile(tileId, tileElement) { + try { + const response = await fetch('http://localhost:5000/api/discard', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ tile_id: tileId }) + }); + + if (!response.ok) { + console.error('Erreur lors de la défausse'); + return; + } + + const data = await response.json(); + + // Ajouter une animation de suppression + tileElement.style.opacity = '0'; + tileElement.style.transition = 'opacity 0.3s ease'; + + setTimeout(() => { + // Mettre à jour la main interactive avec la nouvelle main + updateInteractiveHand(data.hand, data.draw); + }, 300); + } catch (error) { + console.error('Erreur:', error); + } + } + + // Fonction pour mettre à jour la main interactive + function updateInteractiveHand(handData, drawData) { + const handTiles = document.getElementById('interactive-tiles'); + handTiles.innerHTML = ''; + + handData.forEach(tile => { + const tileDiv = document.createElement('div'); + tileDiv.className = 'hand-tile-item'; + tileDiv.innerHTML = tile.svg; + tileDiv.dataset.tileId = tile.id; + tileDiv.style.cursor = 'pointer'; + tileDiv.addEventListener('click', () => discardTile(tile.id, tileDiv)); + handTiles.appendChild(tileDiv); + }); + + // Mettre à jour le draw + const container = handTiles.parentElement; + const oldDrawTile = container.querySelector('.draw-tile'); + if (oldDrawTile) { + oldDrawTile.remove(); + } + + if (drawData) { + const drawTileDiv = document.createElement('div'); + drawTileDiv.className = 'hand-tile-item draw-tile'; + drawTileDiv.innerHTML = drawData.svg; + drawTileDiv.dataset.tileId = drawData.id; + drawTileDiv.style.cursor = 'pointer'; + drawTileDiv.addEventListener('click', () => discardTile(drawData.id, drawTileDiv)); + container.appendChild(drawTileDiv); + } + } \ No newline at end of file