Spaces:
Running
Running
<html lang="fr"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Qui est-ce ? FDES Edition</title> | |
<script src="https://cdn.tailwindcss.com"></script> | |
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
<style> | |
.card { | |
perspective: 1000px; | |
width: 150px; | |
height: 200px; | |
cursor: pointer; | |
transition: transform 0.3s; | |
} | |
.card:hover { | |
transform: scale(1.05); | |
} | |
.card-inner { | |
position: relative; | |
width: 100%; | |
height: 100%; | |
transform-style: preserve-3d; | |
transition: transform 0.6s; | |
} | |
.card.flipped .card-inner { | |
transform: rotateY(180deg); | |
} | |
.card-front, .card-back { | |
position: absolute; | |
width: 100%; | |
height: 100%; | |
backface-visibility: hidden; | |
border-radius: 10px; | |
display: flex; | |
flex-direction: column; | |
justify-content: center; | |
align-items: center; | |
padding: 10px; | |
box-shadow: 0 4px 8px rgba(0,0,0,0.1); | |
} | |
.card-back { | |
transform: rotateY(180deg); | |
overflow-y: auto; | |
} | |
.card-icon { | |
font-size: 3rem; | |
margin-bottom: 10px; | |
} | |
.progress-bar { | |
height: 10px; | |
background-color: #e0e0e0; | |
border-radius: 5px; | |
overflow: hidden; | |
} | |
.progress-fill { | |
height: 100%; | |
background-color: #4CAF50; | |
transition: width 0.3s; | |
} | |
@media (max-width: 640px) { | |
.card { | |
width: 100px; | |
height: 150px; | |
} | |
.card-icon { | |
font-size: 2rem; | |
} | |
} | |
</style> | |
</head> | |
<body class="bg-gray-100 min-h-screen"> | |
<div class="container mx-auto px-4 py-8"> | |
<!-- Header --> | |
<header class="text-center mb-8"> | |
<h1 class="text-3xl md:text-4xl font-bold text-green-800 mb-2">Qui est-ce ? FDES Edition</h1> | |
<p class="text-gray-600">Découvrez les impacts environnementaux des produits de construction</p> | |
<div class="mt-4"> | |
<span class="inline-block bg-green-100 text-green-800 px-3 py-1 rounded-full text-sm font-semibold"> | |
<i class="fas fa-leaf mr-1"></i> Base INIES | |
</span> | |
</div> | |
</header> | |
<!-- Game Area --> | |
<div class="bg-white rounded-xl shadow-lg p-6 mb-8"> | |
<!-- Game Info --> | |
<div class="flex flex-wrap justify-between items-center mb-6"> | |
<div class="mb-4 sm:mb-0"> | |
<h2 class="text-xl font-semibold text-gray-800">Tour <span id="turn-count">1</span></h2> | |
<p class="text-gray-600">Cartes restantes: <span id="remaining-cards">24</span></p> | |
</div> | |
<div class="w-full sm:w-auto"> | |
<div class="progress-bar"> | |
<div class="progress-fill" style="width: 100%"></div> | |
</div> | |
<p class="text-right text-sm text-gray-600 mt-1">Difficulté: Moyenne</p> | |
</div> | |
</div> | |
<!-- Cards Grid --> | |
<div id="cards-container" class="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-6 gap-4 mb-8"> | |
<!-- Cards will be dynamically inserted here --> | |
</div> | |
<!-- Question Area --> | |
<div class="bg-gray-50 rounded-lg p-4"> | |
<h3 class="text-lg font-semibold mb-3 text-gray-800">Poser une question</h3> | |
<div class="flex flex-wrap gap-3 mb-4"> | |
<button class="filter-btn bg-green-100 hover:bg-green-200 text-green-800 px-4 py-2 rounded-lg transition" data-filter="category"> | |
<i class="fas fa-tag mr-2"></i>Catégorie | |
</button> | |
<button class="filter-btn bg-blue-100 hover:bg-blue-200 text-blue-800 px-4 py-2 rounded-lg transition" data-filter="manufacturer"> | |
<i class="fas fa-industry mr-2"></i>Fabricant | |
</button> | |
<button class="filter-btn bg-purple-100 hover:bg-purple-200 text-purple-800 px-4 py-2 rounded-lg transition" data-filter="impact"> | |
<i class="fas fa-fire mr-2"></i>Impact environnemental | |
</button> | |
<button class="filter-btn bg-yellow-100 hover:bg-yellow-200 text-yellow-800 px-4 py-2 rounded-lg transition" data-filter="health"> | |
<i class="fas fa-heartbeat mr-2"></i>Santé | |
</button> | |
</div> | |
<div id="question-options" class="hidden bg-white p-4 rounded-lg shadow-inner mb-4"> | |
<!-- Options will be dynamically inserted here --> | |
</div> | |
<div class="flex justify-between items-center"> | |
<button id="submit-guess" class="bg-red-500 hover:bg-red-600 text-white px-6 py-2 rounded-lg font-medium transition"> | |
<i class="fas fa-lightbulb mr-2"></i>Faire une supposition | |
</button> | |
<button id="submit-question" class="bg-green-600 hover:bg-green-700 text-white px-6 py-2 rounded-lg font-medium transition hidden"> | |
<i class="fas fa-question mr-2"></i>Poser la question | |
</button> | |
</div> | |
</div> | |
</div> | |
<!-- Game Instructions --> | |
<div class="bg-white rounded-xl shadow-lg p-6"> | |
<h2 class="text-xl font-semibold mb-4 text-gray-800">Comment jouer ?</h2> | |
<div class="grid md:grid-cols-3 gap-4"> | |
<div class="bg-blue-50 p-4 rounded-lg"> | |
<div class="flex items-center mb-2"> | |
<div class="bg-blue-100 p-2 rounded-full mr-3"> | |
<i class="fas fa-1 text-blue-600"></i> | |
</div> | |
<h3 class="font-medium text-blue-800">Choisissez un produit</h3> | |
</div> | |
<p class="text-gray-700">Sélectionnez mentalement une carte produit sans la retourner.</p> | |
</div> | |
<div class="bg-green-50 p-4 rounded-lg"> | |
<div class="flex items-center mb-2"> | |
<div class="bg-green-100 p-2 rounded-full mr-3"> | |
<i class="fas fa-2 text-green-600"></i> | |
</div> | |
<h3 class="font-medium text-green-800">Répondez aux questions</h3> | |
</div> | |
<p class="text-gray-700">L'ordinateur pose des questions pour éliminer des options.</p> | |
</div> | |
<div class="bg-purple-50 p-4 rounded-lg"> | |
<div class="flex items-center mb-2"> | |
<div class="bg-purple-100 p-2 rounded-full mr-3"> | |
<i class="fas fa-3 text-purple-600"></i> | |
</div> | |
<h3 class="font-medium text-purple-800">Devinez le produit</h3> | |
</div> | |
<p class="text-gray-700">L'ordinateur tente de deviner votre produit en fonction des réponses.</p> | |
</div> | |
</div> | |
</div> | |
</div> | |
<script> | |
// Sample FDES data | |
const products = [ | |
{ | |
id: 1, | |
name: "Brique terre cuite", | |
category: "Maçonnerie", | |
manufacturer: "Terreal", | |
icon: "fas fa-home", | |
color: "bg-red-100", | |
textColor: "text-red-800", | |
co2: "0.8 kg CO₂ eq/m²", | |
health: "Aucun risque sanitaire connu", | |
recyclability: "90% recyclable" | |
}, | |
{ | |
id: 2, | |
name: "Béton cellulaire", | |
category: "Maçonnerie", | |
manufacturer: "Siporex", | |
icon: "fas fa-cubes", | |
color: "bg-gray-100", | |
textColor: "text-gray-800", | |
co2: "1.2 kg CO₂ eq/m²", | |
health: "Poussières irritantes", | |
recyclability: "70% recyclable" | |
}, | |
{ | |
id: 3, | |
name: "Panneau OSB", | |
category: "Bois", | |
manufacturer: "Kronoply", | |
icon: "fas fa-tree", | |
color: "bg-amber-100", | |
textColor: "text-amber-800", | |
co2: "0.5 kg CO₂ eq/m²", | |
health: "Colles sans formaldéhyde", | |
recyclability: "95% valorisable" | |
}, | |
{ | |
id: 4, | |
name: "Laine de verre", | |
category: "Isolation", | |
manufacturer: "Isover", | |
icon: "fas fa-igloo", | |
color: "bg-blue-100", | |
textColor: "text-blue-800", | |
co2: "1.5 kg CO₂ eq/m²", | |
health: "Protection respiratoire recommandée", | |
recyclability: "60% recyclable" | |
}, | |
{ | |
id: 5, | |
name: "Plaque de plâtre", | |
category: "Cloison", | |
manufacturer: "Placo", | |
icon: "fas fa-border-style", | |
color: "bg-white", | |
textColor: "text-gray-800", | |
co2: "0.7 kg CO₂ eq/m²", | |
health: "Poussières gypse non toxiques", | |
recyclability: "85% recyclable" | |
}, | |
{ | |
id: 6, | |
name: "Carrelage céramique", | |
category: "Revêtement", | |
manufacturer: "Novoceram", | |
icon: "fas fa-border-all", | |
color: "bg-indigo-100", | |
textColor: "text-indigo-800", | |
co2: "1.8 kg CO₂ eq/m²", | |
health: "Aucun risque sanitaire", | |
recyclability: "100% recyclable" | |
}, | |
{ | |
id: 7, | |
name: "Parquet chêne", | |
category: "Revêtement", | |
manufacturer: "Tarkett", | |
icon: "fas fa-border-all", | |
color: "bg-amber-100", | |
textColor: "text-amber-800", | |
co2: "0.9 kg CO₂ eq/m²", | |
health: "Traitement écologique", | |
recyclability: "100% biodégradable" | |
}, | |
{ | |
id: 8, | |
name: "Laine de roche", | |
category: "Isolation", | |
manufacturer: "Rockwool", | |
icon: "fas fa-igloo", | |
color: "bg-gray-100", | |
textColor: "text-gray-800", | |
co2: "1.6 kg CO₂ eq/m²", | |
health: "Protection respiratoire recommandée", | |
recyclability: "65% recyclable" | |
} | |
]; | |
// Game state | |
let remainingProducts = [...products]; | |
let currentFilter = null; | |
let selectedProduct = null; | |
let turnCount = 1; | |
// Initialize the game | |
function initGame() { | |
renderCards(); | |
updateGameInfo(); | |
// Event listeners for filter buttons | |
document.querySelectorAll('.filter-btn').forEach(btn => { | |
btn.addEventListener('click', function() { | |
currentFilter = this.dataset.filter; | |
showQuestionOptions(currentFilter); | |
}); | |
}); | |
// Event listener for submit question button | |
document.getElementById('submit-question').addEventListener('click', processQuestion); | |
// Event listener for guess button | |
document.getElementById('submit-guess').addEventListener('click', makeGuess); | |
} | |
// Render all product cards | |
function renderCards() { | |
const container = document.getElementById('cards-container'); | |
container.innerHTML = ''; | |
remainingProducts.forEach(product => { | |
const card = document.createElement('div'); | |
card.className = 'card'; | |
card.dataset.id = product.id; | |
card.innerHTML = ` | |
<div class="card-inner"> | |
<div class="card-front ${product.color} ${product.textColor}"> | |
<div class="card-icon"> | |
<i class="${product.icon}"></i> | |
</div> | |
<div class="text-center font-medium text-sm">${product.category}</div> | |
</div> | |
<div class="card-back bg-white"> | |
<h4 class="font-bold text-center mb-2">${product.name}</h4> | |
<div class="text-xs"> | |
<p><span class="font-semibold">Fabricant:</span> ${product.manufacturer}</p> | |
<p><span class="font-semibold">CO₂:</span> ${product.co2}</p> | |
<p><span class="font-semibold">Santé:</span> ${product.health}</p> | |
<p><span class="font-semibold">Recyclage:</span> ${product.recyclability}</p> | |
</div> | |
</div> | |
</div> | |
`; | |
container.appendChild(card); | |
}); | |
} | |
// Update game info display | |
function updateGameInfo() { | |
document.getElementById('remaining-cards').textContent = remainingProducts.length; | |
document.getElementById('turn-count').textContent = turnCount; | |
// Update progress bar | |
const progress = (remainingProducts.length / products.length) * 100; | |
document.querySelector('.progress-fill').style.width = `${progress}%`; | |
} | |
// Show question options based on filter | |
function showQuestionOptions(filter) { | |
const optionsContainer = document.getElementById('question-options'); | |
optionsContainer.innerHTML = ''; | |
optionsContainer.classList.remove('hidden'); | |
document.getElementById('submit-question').classList.remove('hidden'); | |
let options = []; | |
let questionText = ''; | |
switch(filter) { | |
case 'category': | |
questionText = 'Le produit appartient-il à la catégorie...'; | |
options = [...new Set(products.map(p => p.category))]; | |
break; | |
case 'manufacturer': | |
questionText = 'Le produit est-il fabriqué par...'; | |
options = [...new Set(products.map(p => p.manufacturer))]; | |
break; | |
case 'impact': | |
questionText = 'L\'impact CO₂ du produit est-il...'; | |
options = ['Faible (<1 kg CO₂ eq/m²)', 'Moyen (1-1.5 kg CO₂ eq/m²)', 'Élevé (>1.5 kg CO₂ eq/m²)']; | |
break; | |
case 'health': | |
questionText = 'Le produit présente-t-il...'; | |
options = ['Aucun risque sanitaire', 'Risques limités', 'Protection nécessaire']; | |
break; | |
} | |
optionsContainer.innerHTML = ` | |
<h4 class="font-medium mb-3">${questionText}</h4> | |
<div class="grid grid-cols-1 sm:grid-cols-2 gap-2"> | |
${options.map(opt => ` | |
<label class="flex items-center bg-gray-100 hover:bg-gray-200 rounded-lg p-3 cursor-pointer transition"> | |
<input type="radio" name="questionOption" value="${opt}" class="mr-2"> | |
${opt} | |
</label> | |
`).join('')} | |
</div> | |
`; | |
} | |
// Process the selected question | |
function processQuestion() { | |
const selectedOption = document.querySelector('input[name="questionOption"]:checked'); | |
if (!selectedOption) { | |
alert('Veuillez sélectionner une option'); | |
return; | |
} | |
const optionValue = selectedOption.value; | |
let filteredProducts = []; | |
switch(currentFilter) { | |
case 'category': | |
filteredProducts = remainingProducts.filter(p => p.category === optionValue); | |
break; | |
case 'manufacturer': | |
filteredProducts = remainingProducts.filter(p => p.manufacturer === optionValue); | |
break; | |
case 'impact': | |
if (optionValue.includes('Faible')) { | |
filteredProducts = remainingProducts.filter(p => parseFloat(p.co2) < 1); | |
} else if (optionValue.includes('Moyen')) { | |
filteredProducts = remainingProducts.filter(p => parseFloat(p.co2) >= 1 && parseFloat(p.co2) <= 1.5); | |
} else { | |
filteredProducts = remainingProducts.filter(p => parseFloat(p.co2) > 1.5); | |
} | |
break; | |
case 'health': | |
if (optionValue.includes('Aucun')) { | |
filteredProducts = remainingProducts.filter(p => p.health.includes('Aucun')); | |
} else if (optionValue.includes('limités')) { | |
filteredProducts = remainingProducts.filter(p => !p.health.includes('Aucun') && !p.health.includes('Protection')); | |
} else { | |
filteredProducts = remainingProducts.filter(p => p.health.includes('Protection')); | |
} | |
break; | |
} | |
// Computer makes a guess if only one product remains | |
if (filteredProducts.length === 1) { | |
setTimeout(() => { | |
alert(`L'ordinateur pense que vous avez sélectionné: ${filteredProducts[0].name}`); | |
endGame(true); | |
}, 500); | |
return; | |
} | |
// If no products match, computer learns the answer was no | |
if (filteredProducts.length === 0) { | |
alert(`Aucun produit ne correspond à cette caractéristique. L'ordinateur élimine ces options.`); | |
} else { | |
remainingProducts = filteredProducts; | |
turnCount++; | |
updateGameInfo(); | |
renderCards(); | |
} | |
// Reset question UI | |
document.getElementById('question-options').classList.add('hidden'); | |
document.getElementById('submit-question').classList.add('hidden'); | |
} | |
// Player makes a guess | |
function makeGuess() { | |
if (remainingProducts.length === 0) { | |
alert('Aucun produit restant à deviner'); | |
return; | |
} | |
const options = remainingProducts.map(p => p.name).join('\n'); | |
const guess = prompt(`Faites votre supposition parmi ces produits:\n\n${options}`); | |
if (guess) { | |
const found = remainingProducts.find(p => p.name === guess); | |
if (found) { | |
alert(`Correct! Vous avez deviné: ${guess}`); | |
endGame(false); | |
} else { | |
alert('Incorrect. Continuez à poser des questions.'); | |
} | |
} | |
} | |
// End the game | |
function endGame(computerWon) { | |
if (computerWon) { | |
alert('L\'ordinateur a gagné ! Voulez-vous rejouer ?'); | |
} else { | |
alert('Vous avez gagné ! Voulez-vous rejouer ?'); | |
} | |
if (confirm('Nouvelle partie ?')) { | |
resetGame(); | |
} | |
} | |
// Reset the game | |
function resetGame() { | |
remainingProducts = [...products]; | |
turnCount = 1; | |
currentFilter = null; | |
selectedProduct = null; | |
document.getElementById('question-options').classList.add('hidden'); | |
document.getElementById('submit-question').classList.add('hidden'); | |
renderCards(); | |
updateGameInfo(); | |
} | |
// Initialize the game when page loads | |
window.addEventListener('DOMContentLoaded', initGame); | |
</script> | |
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=GabrielVidal/qui-fdes" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> | |
</html> |