test / index.html
arbib's picture
je veux une jeux educatife pour la geographie pour les adultes - Initial Deployment
f1c55b8 verified
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>GéoChallenge - Jeu éducatif de géographie</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>
.country-flag {
height: 120px;
object-fit: contain;
background-color: #f8fafc;
border-radius: 8px;
padding: 8px;
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
}
.monument-image {
height: 180px;
width: 100%;
object-fit: cover;
border-radius: 8px;
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
}
.progress-bar {
transition: width 0.5s ease-in-out;
}
.option-btn {
transition: all 0.2s ease;
}
.option-btn:hover {
transform: translateY(-2px);
}
.option-btn.correct {
background-color: #10b981 !important;
color: white !important;
}
.option-btn.incorrect {
background-color: #ef4444 !important;
color: white !important;
}
.pulse-animation {
animation: pulse 2s infinite;
}
@keyframes pulse {
0% { transform: scale(1); }
50% { transform: scale(1.05); }
100% { transform: scale(1); }
}
</style>
</head>
<body class="bg-gray-50 min-h-screen font-sans">
<div class="container mx-auto px-4 py-8 max-w-4xl">
<!-- Header -->
<header class="text-center mb-8">
<h1 class="text-4xl font-bold text-blue-800 mb-2">GéoChallenge</h1>
<p class="text-lg text-gray-600">Testez vos connaissances en géographie mondiale</p>
<div class="flex justify-center mt-4">
<div class="w-full bg-gray-200 rounded-full h-4 max-w-xl">
<div id="progress-bar" class="progress-bar bg-blue-600 h-4 rounded-full" style="width: 0%"></div>
</div>
</div>
<div id="score-display" class="mt-2 text-lg font-semibold text-blue-700">
Score: <span id="score">0</span>/<span id="total-questions">0</span>
</div>
</header>
<!-- Game Area -->
<main>
<!-- Start Screen -->
<div id="start-screen" class="bg-white rounded-xl shadow-lg p-8 text-center">
<div class="mb-6">
<i class="fas fa-globe-europe text-6xl text-blue-600 mb-4"></i>
<h2 class="text-2xl font-bold text-gray-800 mb-2">Bienvenue sur GéoChallenge</h2>
<p class="text-gray-600 mb-6">Un jeu éducatif pour tester et améliorer vos connaissances en géographie. Prêt à relever le défi ?</p>
</div>
<div class="mb-6">
<label for="difficulty" class="block text-gray-700 font-medium mb-2">Niveau de difficulté</label>
<select id="difficulty" class="w-full md:w-64 px-4 py-2 border border-gray-300 rounded-lg focus:ring-blue-500 focus:border-blue-500">
<option value="easy">Facile</option>
<option value="medium">Moyen</option>
<option value="hard">Difficile</option>
</select>
</div>
<button id="start-btn" class="bg-blue-600 hover:bg-blue-700 text-white font-bold py-3 px-8 rounded-lg text-lg transition-all duration-300 transform hover:scale-105 pulse-animation">
Commencer le jeu <i class="fas fa-play ml-2"></i>
</button>
</div>
<!-- Question Screen -->
<div id="question-screen" class="hidden bg-white rounded-xl shadow-lg p-6 md:p-8">
<div class="flex justify-between items-center mb-6">
<div id="question-number" class="text-gray-500 font-medium">Question 1/10</div>
<div id="timer" class="bg-blue-100 text-blue-800 px-3 py-1 rounded-full font-semibold flex items-center">
<i class="fas fa-clock mr-2"></i>
<span id="time">30</span>s
</div>
</div>
<div id="question-container">
<h2 id="question-text" class="text-xl md:text-2xl font-bold text-gray-800 mb-6"></h2>
<!-- Flag Question -->
<div id="flag-question" class="hidden mb-8">
<div class="flex justify-center">
<img id="flag-image" src="" alt="Drapeau du pays" class="country-flag">
</div>
</div>
<!-- Monument Question -->
<div id="monument-question" class="hidden mb-8">
<div class="flex justify-center">
<img id="monument-image" src="" alt="Monument" class="monument-image">
</div>
</div>
<!-- Options Container -->
<div id="options-container" class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6">
<!-- Options will be inserted here by JavaScript -->
</div>
</div>
<div class="flex justify-between items-center mt-6">
<button id="hint-btn" class="bg-yellow-100 hover:bg-yellow-200 text-yellow-800 font-medium py-2 px-4 rounded-lg flex items-center">
<i class="fas fa-lightbulb mr-2"></i> Indice
</button>
<button id="next-btn" class="hidden bg-blue-600 hover:bg-blue-700 text-white font-bold py-2 px-6 rounded-lg">
Suivant <i class="fas fa-arrow-right ml-2"></i>
</button>
</div>
</div>
<!-- Hint Modal -->
<div id="hint-modal" class="hidden fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
<div class="bg-white rounded-xl p-6 max-w-md mx-4">
<div class="flex justify-between items-center mb-4">
<h3 class="text-xl font-bold text-gray-800"><i class="fas fa-lightbulb text-yellow-500 mr-2"></i> Indice</h3>
<button id="close-hint" class="text-gray-500 hover:text-gray-700">
<i class="fas fa-times"></i>
</button>
</div>
<p id="hint-text" class="text-gray-700 mb-4"></p>
<div class="text-right">
<button id="use-hint" class="bg-blue-600 hover:bg-blue-700 text-white font-medium py-2 px-4 rounded-lg">
Utiliser cet indice
</button>
</div>
</div>
</div>
<!-- Results Screen -->
<div id="results-screen" class="hidden bg-white rounded-xl shadow-lg p-8 text-center">
<div class="mb-6">
<div class="flex justify-center mb-4">
<div class="w-24 h-24 rounded-full bg-blue-100 flex items-center justify-center">
<i class="fas fa-trophy text-4xl text-yellow-500"></i>
</div>
</div>
<h2 class="text-2xl font-bold text-gray-800 mb-2">Résultats finaux</h2>
<p id="result-message" class="text-gray-600 mb-6"></p>
</div>
<div class="bg-gray-50 rounded-lg p-6 mb-8">
<div class="grid grid-cols-3 gap-4 text-center">
<div>
<div class="text-3xl font-bold text-blue-600" id="final-score">0</div>
<div class="text-gray-500">Score</div>
</div>
<div>
<div class="text-3xl font-bold text-green-600" id="correct-answers">0</div>
<div class="text-gray-500">Correctes</div>
</div>
<div>
<div class="text-3xl font-bold text-red-600" id="wrong-answers">0</div>
<div class="text-gray-500">Incorrectes</div>
</div>
</div>
</div>
<div class="mb-6">
<h3 class="text-lg font-semibold text-gray-700 mb-3">Détail des réponses</h3>
<div id="answers-detail" class="space-y-3 max-h-60 overflow-y-auto">
<!-- Answers detail will be inserted here -->
</div>
</div>
<button id="restart-btn" class="bg-blue-600 hover:bg-blue-700 text-white font-bold py-3 px-8 rounded-lg text-lg">
Rejouer <i class="fas fa-redo ml-2"></i>
</button>
</div>
</main>
<!-- Footer -->
<footer class="mt-12 text-center text-gray-500 text-sm">
<p>GéoChallenge - Un jeu éducatif pour apprendre la géographie en s'amusant</p>
<p class="mt-1">© 2023 Tous droits réservés</p>
</footer>
</div>
<script>
// Game data
const gameData = {
easy: [
{
type: "capital",
question: "Quelle est la capitale de la France ?",
options: ["Lyon", "Marseille", "Paris", "Bordeaux"],
answer: "Paris",
hint: "Cette ville est connue comme la 'Ville Lumière' et abrite la Tour Eiffel."
},
{
type: "flag",
question: "À quel pays appartient ce drapeau ?",
flag: "https://upload.wikimedia.org/wikipedia/commons/thumb/0/05/Flag_of_Brazil.svg/320px-Flag_of_Brazil.svg.png",
options: ["Argentine", "Brésil", "Colombie", "Venezuela"],
answer: "Brésil",
hint: "Ce pays est le plus grand d'Amérique du Sud et est connu pour le Carnaval de Rio."
},
{
type: "monument",
question: "Dans quel pays se trouve ce monument ?",
monument: "https://upload.wikimedia.org/wikipedia/commons/thumb/d/df/NYC_Empire_State_Building.jpg/320px-NYC_Empire_State_Building.jpg",
options: ["Canada", "États-Unis", "Royaume-Uni", "Australie"],
answer: "États-Unis",
hint: "Ce gratte-ciel emblématique est situé à New York."
},
{
type: "capital",
question: "Quelle est la capitale du Japon ?",
options: ["Osaka", "Kyoto", "Tokyo", "Hiroshima"],
answer: "Tokyo",
hint: "C'est la plus grande ville du Japon et l'une des métropoles les plus peuplées du monde."
},
{
type: "flag",
question: "À quel pays appartient ce drapeau ?",
flag: "https://upload.wikimedia.org/wikipedia/commons/thumb/f/fa/Flag_of_the_People%27s_Republic_of_China.svg/320px-Flag_of_the_People%27s_Republic_of_China.svg.png",
options: ["Japon", "Corée du Sud", "Chine", "Vietnam"],
answer: "Chine",
hint: "Ce pays est le plus peuplé du monde et abrite la Grande Muraille."
}
],
medium: [
{
type: "capital",
question: "Quelle est la capitale de l'Afrique du Sud ?",
options: ["Pretoria", "Le Cap", "Bloemfontein", "Les trois"],
answer: "Les trois",
hint: "Ce pays a trois capitales officielles pour différentes branches du gouvernement."
},
{
type: "monument",
question: "Dans quel pays se trouve ce monument ?",
monument: "https://upload.wikimedia.org/wikipedia/commons/thumb/d/de/Colosseo_2020.jpg/320px-Colosseo_2020.jpg",
options: ["Grèce", "Italie", "Espagne", "Turquie"],
answer: "Italie",
hint: "Cet amphithéâtre antique est situé dans la capitale de ce pays."
},
{
type: "flag",
question: "À quel pays appartient ce drapeau ?",
flag: "https://upload.wikimedia.org/wikipedia/commons/thumb/9/9e/Flag_of_Japan.svg/320px-Flag_of_Japan.svg.png",
options: ["Corée du Sud", "Japon", "Chine", "Thaïlande"],
answer: "Japon",
hint: "Ce pays est connu comme le 'Pays du Soleil Levant'."
},
{
type: "capital",
question: "Quelle est la capitale du Canada ?",
options: ["Toronto", "Montréal", "Ottawa", "Vancouver"],
answer: "Ottawa",
hint: "Cette ville est située dans la province de l'Ontario, près de la frontière avec le Québec."
},
{
type: "monument",
question: "Dans quel pays se trouve ce monument ?",
monument: "https://upload.wikimedia.org/wikipedia/commons/thumb/5/53/Sydney_Opera_House_and_Harbour_Bridge_Dusk_%282%29_2019-06-21.jpg/320px-Sydney_Opera_House_and_Harbour_Bridge_Dusk_%282%29_2019-06-21.jpg",
options: ["Nouvelle-Zélande", "Australie", "Afrique du Sud", "Argentine"],
answer: "Australie",
hint: "Ce monument emblématique est situé dans la plus grande ville de ce pays."
}
],
hard: [
{
type: "capital",
question: "Quelle est la capitale de la Suisse ?",
options: ["Zurich", "Genève", "Berne", "Bâle"],
answer: "Berne",
hint: "Bien que ce ne soit pas la plus grande ville du pays, c'est la capitale fédérale."
},
{
type: "flag",
question: "À quel pays appartient ce drapeau ?",
flag: "https://upload.wikimedia.org/wikipedia/commons/thumb/5/5c/Flag_of_Portugal.svg/320px-Flag_of_Portugal.svg.png",
options: ["Portugal", "Serbie", "Slovaquie", "Lituanie"],
answer: "Portugal",
hint: "Ce pays européen est connu pour ses explorateurs comme Vasco de Gama."
},
{
type: "monument",
question: "Dans quel pays se trouve ce monument ?",
monument: "https://upload.wikimedia.org/wikipedia/commons/thumb/1/1a/Machu_Picchu%2C_Peru.jpg/320px-Machu_Picchu%2C_Peru.jpg",
options: ["Mexique", "Pérou", "Bolivie", "Équateur"],
answer: "Pérou",
hint: "Cette ancienne cité inca est située dans les Andes."
},
{
type: "capital",
question: "Quelle est la capitale de la Nouvelle-Zélande ?",
options: ["Auckland", "Christchurch", "Wellington", "Dunedin"],
answer: "Wellington",
hint: "Cette ville est située à l'extrémité sud de l'île du Nord."
},
{
type: "flag",
question: "À quel pays appartient ce drapeau ?",
flag: "https://upload.wikimedia.org/wikipedia/commons/thumb/2/2e/Flag_of_the_Czech_Republic.svg/320px-Flag_of_the_Czech_Republic.svg.png",
options: ["Tchéquie", "Slovaquie", "Slovénie", "Croatie"],
answer: "Tchéquie",
hint: "Ce pays d'Europe centrale a pour capitale Prague."
}
]
};
// Game state
let currentQuestions = [];
let currentQuestionIndex = 0;
let score = 0;
let timer;
let timeLeft = 30;
let usedHints = 0;
let answersDetail = [];
// DOM elements
const startScreen = document.getElementById('start-screen');
const questionScreen = document.getElementById('question-screen');
const resultsScreen = document.getElementById('results-screen');
const startBtn = document.getElementById('start-btn');
const nextBtn = document.getElementById('next-btn');
const hintBtn = document.getElementById('hint-btn');
const useHintBtn = document.getElementById('use-hint');
const closeHintBtn = document.getElementById('close-hint');
const hintModal = document.getElementById('hint-modal');
const restartBtn = document.getElementById('restart-btn');
const difficultySelect = document.getElementById('difficulty');
const questionText = document.getElementById('question-text');
const optionsContainer = document.getElementById('options-container');
const questionNumber = document.getElementById('question-number');
const timeDisplay = document.getElementById('time');
const scoreDisplay = document.getElementById('score');
const totalQuestions = document.getElementById('total-questions');
const progressBar = document.getElementById('progress-bar');
const flagQuestion = document.getElementById('flag-question');
const flagImage = document.getElementById('flag-image');
const monumentQuestion = document.getElementById('monument-question');
const monumentImage = document.getElementById('monument-image');
const hintText = document.getElementById('hint-text');
const finalScore = document.getElementById('final-score');
const correctAnswers = document.getElementById('correct-answers');
const wrongAnswers = document.getElementById('wrong-answers');
const resultMessage = document.getElementById('result-message');
const answersDetailContainer = document.getElementById('answers-detail');
// Event listeners
startBtn.addEventListener('click', startGame);
nextBtn.addEventListener('click', nextQuestion);
hintBtn.addEventListener('click', showHint);
useHintBtn.addEventListener('click', useHint);
closeHintBtn.addEventListener('click', closeHint);
restartBtn.addEventListener('click', restartGame);
// Start the game
function startGame() {
const difficulty = difficultySelect.value;
currentQuestions = [...gameData[difficulty]];
currentQuestionIndex = 0;
score = 0;
usedHints = 0;
answersDetail = [];
// Shuffle questions for random order
shuffleArray(currentQuestions);
// Update UI
startScreen.classList.add('hidden');
questionScreen.classList.remove('hidden');
totalQuestions.textContent = currentQuestions.length;
updateScore();
// Load first question
loadQuestion();
}
// Load the current question
function loadQuestion() {
const question = currentQuestions[currentQuestionIndex];
// Reset UI
optionsContainer.innerHTML = '';
nextBtn.classList.add('hidden');
flagQuestion.classList.add('hidden');
monumentQuestion.classList.add('hidden');
// Update question info
questionText.textContent = question.question;
questionNumber.textContent = `Question ${currentQuestionIndex + 1}/${currentQuestions.length}`;
// Show appropriate content based on question type
if (question.type === 'flag') {
flagQuestion.classList.remove('hidden');
flagImage.src = question.flag;
flagImage.alt = `Drapeau de ${question.answer}`;
} else if (question.type === 'monument') {
monumentQuestion.classList.remove('hidden');
monumentImage.src = question.monument;
monumentImage.alt = `Monument de ${question.answer}`;
}
// Create options
const shuffledOptions = [...question.options];
shuffleArray(shuffledOptions);
shuffledOptions.forEach(option => {
const button = document.createElement('button');
button.textContent = option;
button.className = 'option-btn bg-gray-100 hover:bg-gray-200 text-gray-800 font-medium py-3 px-4 rounded-lg text-left';
button.addEventListener('click', () => selectAnswer(option));
optionsContainer.appendChild(button);
});
// Set hint text
hintText.textContent = question.hint;
// Start timer
startTimer();
// Update progress bar
const progress = ((currentQuestionIndex) / currentQuestions.length) * 100;
progressBar.style.width = `${progress}%`;
}
// Select an answer
function selectAnswer(selectedOption) {
clearInterval(timer);
const question = currentQuestions[currentQuestionIndex];
const isCorrect = selectedOption === question.answer;
// Disable all buttons
const buttons = document.querySelectorAll('.option-btn');
buttons.forEach(button => {
button.disabled = true;
if (button.textContent === question.answer) {
button.classList.add('correct');
} else if (button.textContent === selectedOption && !isCorrect) {
button.classList.add('incorrect');
}
});
// Update score if correct
if (isCorrect) {
score++;
updateScore();
}
// Store answer detail
answersDetail.push({
question: question.question,
correctAnswer: question.answer,
userAnswer: selectedOption,
isCorrect: isCorrect
});
// Show next button
nextBtn.classList.remove('hidden');
}
// Next question
function nextQuestion() {
currentQuestionIndex++;
if (currentQuestionIndex < currentQuestions.length) {
loadQuestion();
} else {
showResults();
}
}
// Show results
function showResults() {
questionScreen.classList.add('hidden');
resultsScreen.classList.remove('hidden');
const correctCount = answersDetail.filter(answer => answer.isCorrect).length;
const wrongCount = answersDetail.length - correctCount;
// Update results
finalScore.textContent = score;
correctAnswers.textContent = correctCount;
wrongAnswers.textContent = wrongCount;
// Set result message based on performance
let message;
const percentage = (correctCount / answersDetail.length) * 100;
if (percentage >= 80) {
message = "Félicitations ! Vous êtes un véritable expert en géographie !";
} else if (percentage >= 60) {
message = "Bon travail ! Vous avez de solides connaissances en géographie.";
} else if (percentage >= 40) {
message = "Pas mal ! Continuez à apprendre et vous vous améliorerez.";
} else {
message = "Ne vous découragez pas ! La géographie s'apprend avec le temps.";
}
resultMessage.textContent = message;
// Show answers detail
answersDetailContainer.innerHTML = '';
answersDetail.forEach((answer, index) => {
const answerElement = document.createElement('div');
answerElement.className = 'bg-gray-50 p-3 rounded-lg';
const questionText = document.createElement('p');
questionText.className = 'font-medium text-gray-800';
questionText.textContent = `${index + 1}. ${answer.question}`;
const userAnswer = document.createElement('p');
userAnswer.className = `text-sm ${answer.isCorrect ? 'text-green-600' : 'text-red-600'}`;
userAnswer.innerHTML = `<span class="font-medium">Votre réponse:</span> ${answer.userAnswer}`;
if (!answer.isCorrect) {
const correctAnswer = document.createElement('p');
correctAnswer.className = 'text-sm text-gray-600';
correctAnswer.innerHTML = `<span class="font-medium">Réponse correcte:</span> ${answer.correctAnswer}`;
answerElement.appendChild(correctAnswer);
}
answerElement.prepend(userAnswer);
answerElement.prepend(questionText);
answersDetailContainer.appendChild(answerElement);
});
// Update progress bar to 100%
progressBar.style.width = '100%';
}
// Restart game
function restartGame() {
resultsScreen.classList.add('hidden');
startScreen.classList.remove('hidden');
}
// Update score display
function updateScore() {
scoreDisplay.textContent = score;
}
// Start timer for current question
function startTimer() {
timeLeft = 30;
timeDisplay.textContent = timeLeft;
timer = setInterval(() => {
timeLeft--;
timeDisplay.textContent = timeLeft;
if (timeLeft <= 0) {
clearInterval(timer);
timeUp();
}
}, 1000);
}
// Handle time up
function timeUp() {
const question = currentQuestions[currentQuestionIndex];
// Disable all buttons
const buttons = document.querySelectorAll('.option-btn');
buttons.forEach(button => {
button.disabled = true;
if (button.textContent === question.answer) {
button.classList.add('correct');
}
});
// Store answer detail (no answer)
answersDetail.push({
question: question.question,
correctAnswer: question.answer,
userAnswer: "Aucune réponse (temps écoulé)",
isCorrect: false
});
// Show next button
nextBtn.classList.remove('hidden');
}
// Show hint modal
function showHint() {
hintModal.classList.remove('hidden');
}
// Use hint
function useHint() {
usedHints++;
closeHint();
// Remove two incorrect options
const question = currentQuestions[currentQuestionIndex];
const buttons = Array.from(document.querySelectorAll('.option-btn'));
const incorrectButtons = buttons.filter(btn => btn.textContent !== question.answer);
// Shuffle and remove two incorrect options
shuffleArray(incorrectButtons);
for (let i = 0; i < Math.min(2, incorrectButtons.length); i++) {
incorrectButtons[i].classList.add('hidden');
}
// Disable hint button
hintBtn.disabled = true;
hintBtn.classList.add('opacity-50');
}
// Close hint modal
function closeHint() {
hintModal.classList.add('hidden');
}
// Utility function to shuffle array
function shuffleArray(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]];
}
return array;
}
</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=arbib/test" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html>