From 4740d0003bdfb1780c5d21dc1bd91d363b9fdd9a Mon Sep 17 00:00:00 2001 From: Ahmad El Masri Date: Thu, 5 Jun 2025 06:32:33 +0200 Subject: [PATCH] init: initialize project - 2 games --- .gitignore | 1 + find-and-write/index.html | 215 ++++++++++++++ tictactoe/README.md | 70 +++++ tictactoe/game.js | 598 ++++++++++++++++++++++++++++++++++++++ tictactoe/index.html | 109 +++++++ tictactoe/questions.js | 439 ++++++++++++++++++++++++++++ tictactoe/styles.css | 352 ++++++++++++++++++++++ 7 files changed, 1784 insertions(+) create mode 100644 .gitignore create mode 100644 find-and-write/index.html create mode 100644 tictactoe/README.md create mode 100644 tictactoe/game.js create mode 100644 tictactoe/index.html create mode 100644 tictactoe/questions.js create mode 100644 tictactoe/styles.css diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1d74e21 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.vscode/ diff --git a/find-and-write/index.html b/find-and-write/index.html new file mode 100644 index 0000000..987a68f --- /dev/null +++ b/find-and-write/index.html @@ -0,0 +1,215 @@ + + + + + Classroom Word Search Game + + + + + + +
+ + + diff --git a/tictactoe/README.md b/tictactoe/README.md new file mode 100644 index 0000000..b45d1da --- /dev/null +++ b/tictactoe/README.md @@ -0,0 +1,70 @@ +# Educational Tic Tac Toe + +A Tic Tac Toe game with an educational twist! Players must correctly answer questions to make their moves. + +## Features + +- Classic Tic Tac Toe gameplay +- Educational questions that must be answered correctly to make a move +- Support for both True/False and Multiple Choice questions +- Full support for Arabic language +- Different question categories: General Knowledge, Math, Science, and Language +- Score tracking for multiple games +- Responsive design that works on all devices + +## How to Play + +1. Open `index.html` in a web browser +2. Players take turns clicking on empty cells +3. When a cell is clicked, a question appears +4. If the player answers correctly, they get to place their mark (X or O) +5. If the player answers incorrectly, their turn is skipped +6. The first player to get three marks in a row (horizontally, vertically, or diagonally) wins +7. If all cells are filled without a winner, the game is a draw + +## Game Settings + +You can customize the game experience using the settings panel: + +### Question Type +- **True/False**: Simple true or false questions +- **Multiple Choice**: Questions with multiple options + +### Language +- **English**: Questions and interface in English +- **Arabic**: Questions and interface in Arabic (with RTL support) + +### Category +- **General Knowledge**: Various general knowledge questions +- **Math**: Mathematical questions and problems +- **Science**: Science-related questions +- **Language**: Questions about language and vocabulary + +## Running the Game + +Simply open the `index.html` file in any modern web browser: + +``` +firefox index.html +``` + +or + +``` +google-chrome index.html +``` + +## Customizing Questions + +You can add or modify questions by editing the `questions.js` file. The questions are organized by: +- Language (english, arabic) +- Category (general, math, science, language) +- Type (truefalse, multiplechoice) + +## Browser Compatibility + +This game works in all modern browsers: +- Chrome +- Firefox +- Safari +- Edge \ No newline at end of file diff --git a/tictactoe/game.js b/tictactoe/game.js new file mode 100644 index 0000000..95723e0 --- /dev/null +++ b/tictactoe/game.js @@ -0,0 +1,598 @@ +// Educational Tic Tac Toe Game + +// Game variables +let currentPlayer = 'X'; +let gameBoard = ['', '', '', '', '', '', '', '', '']; +let gameActive = true; +let scores = { X: 0, O: 0 }; +let gameSettings = { + questionType: 'multiplechoice', + language: 'arabic', + category: 'beginners', // Changed to beginners for new users + timerSeconds: 5 // 5 seconds timer +}; + +// Timer variables +let timerInterval = null; +let timeLeft = 0; + +// DOM Elements +const cells = document.querySelectorAll('.cell'); +const player1Element = document.getElementById('player1'); +const player2Element = document.getElementById('player2'); +const resetButton = document.getElementById('resetBtn'); +const newGameButton = document.getElementById('newGameBtn'); +const questionModal = document.getElementById('questionModal'); +const questionText = document.getElementById('questionText'); +const answerOptions = document.getElementById('answerOptions'); +const feedback = document.getElementById('feedback'); +const gameOverModal = document.getElementById('gameOverModal'); +const gameResult = document.getElementById('gameResult'); +const playAgainButton = document.getElementById('playAgainBtn'); +const applySettingsButton = document.getElementById('applySettingsBtn'); + +// Timer elements +const timerContainer = document.getElementById('timerContainer'); +const timerBar = document.getElementById('timerBar'); +const timerText = document.getElementById('timerText'); + +// Settings elements +const questionTypeSelect = document.getElementById('questionType'); +const questionLanguageSelect = document.getElementById('questionLanguage'); +const questionCategorySelect = document.getElementById('questionCategory'); +const questionTimerSelect = document.getElementById('questionTimer'); + +// Current question and selected cell +let currentQuestion = null; +let selectedCellIndex = null; +let questionPlayer = null; // Track which player clicked the cell + +// Initialize the game +function initGame() { + // Add event listeners to cells + cells.forEach(cell => { + cell.addEventListener('click', () => handleCellClick(parseInt(cell.dataset.index))); + }); + + // Add event listeners to buttons + resetButton.addEventListener('click', resetGame); + newGameButton.addEventListener('click', newGame); + playAgainButton.addEventListener('click', newGame); + applySettingsButton.addEventListener('click', applySettings); + + // Add event listener to language select to update categories + questionLanguageSelect.addEventListener('change', updateCategoryOptions); + + // Initialize settings from selects + questionTypeSelect.value = gameSettings.questionType; + questionLanguageSelect.value = gameSettings.language; + questionCategorySelect.value = gameSettings.category; + questionTimerSelect.value = gameSettings.timerSeconds; + + // Update category options based on selected language + updateCategoryOptions(); + + // Set up the initial game state + updateGameDisplay(); + + // Update UI language immediately based on default settings + updateUILanguage(); + + // Set document direction for Arabic + if (gameSettings.language === 'arabic') { + document.documentElement.dir = 'rtl'; + } +} + +// Update category options based on selected language +function updateCategoryOptions() { + const language = questionLanguageSelect.value; + + // Clear existing options + questionCategorySelect.innerHTML = ''; + + if (language === 'english') { + // Add English categories + const mathOption = document.createElement('option'); + mathOption.value = 'math'; + mathOption.textContent = 'Mathematics'; + questionCategorySelect.appendChild(mathOption); + + // Set default for English + questionCategorySelect.value = 'math'; + } else if (language === 'arabic') { + // Add Arabic categories + const islamicOption = document.createElement('option'); + islamicOption.value = 'islamic'; + islamicOption.textContent = 'Islamic'; + questionCategorySelect.appendChild(islamicOption); + + const beginnersOption = document.createElement('option'); + beginnersOption.value = 'beginners'; + beginnersOption.textContent = 'Beginners Arabic'; + questionCategorySelect.appendChild(beginnersOption); + + // Set default for Arabic + questionCategorySelect.value = 'beginners'; + } +} + +// Handle cell click +function handleCellClick(index) { + // Ignore clicks if game is not active or cell is already filled + if (!gameActive || gameBoard[index] !== '') return; + + // Store the selected cell index and current player + selectedCellIndex = index; + questionPlayer = currentPlayer; // Store which player clicked the cell + + // Get a random question based on current settings + currentQuestion = getRandomQuestion( + gameSettings.language, + gameSettings.category, + gameSettings.questionType + ); + + // Display the question + showQuestion(currentQuestion); +} + +// Show question modal +function showQuestion(question) { + // Set the question text with appropriate language attribute + questionText.textContent = question.question; + if (gameSettings.language === 'arabic') { + questionText.setAttribute('lang', 'ar'); + } else { + questionText.removeAttribute('lang'); + } + + // Clear previous answer options and feedback + answerOptions.innerHTML = ''; + feedback.textContent = ''; + feedback.className = 'feedback'; + + // Create answer options based on question type + if (gameSettings.questionType === 'truefalse') { + // True/False question + const trueOption = document.createElement('div'); + trueOption.className = 'answer-option'; + trueOption.textContent = gameSettings.language === 'arabic' ? 'صحيح' : 'True'; + trueOption.addEventListener('click', () => checkAnswer(true)); + + const falseOption = document.createElement('div'); + falseOption.className = 'answer-option'; + falseOption.textContent = gameSettings.language === 'arabic' ? 'خطأ' : 'False'; + falseOption.addEventListener('click', () => checkAnswer(false)); + + answerOptions.appendChild(trueOption); + answerOptions.appendChild(falseOption); + } else { + // Multiple choice question + + // Create a shuffled array of indices + const originalAnswer = question.answer; + const indices = Array.from({ length: question.options.length }, (_, i) => i); + const shuffledIndices = shuffleArray([...indices]); + + // Create a mapping from shuffled positions to original positions + const shuffleMap = {}; + shuffledIndices.forEach((originalIndex, newIndex) => { + shuffleMap[newIndex] = originalIndex; + }); + + // Display options in shuffled order + shuffledIndices.forEach((originalIndex, newIndex) => { + const optionElement = document.createElement('div'); + optionElement.className = 'answer-option'; + optionElement.textContent = question.options[originalIndex]; + if (gameSettings.language === 'arabic') { + optionElement.setAttribute('lang', 'ar'); + } + // When clicked, map back to the original index for checking + optionElement.addEventListener('click', () => checkAnswer(originalIndex, shuffleMap)); + answerOptions.appendChild(optionElement); + }); + } + + // Show the modal + questionModal.classList.add('show'); + + // Setup timer if enabled + if (gameSettings.timerSeconds > 0) { + // Show timer container + timerContainer.style.display = 'block'; + + // Reset timer + timeLeft = gameSettings.timerSeconds; + updateTimerDisplay(); + + // Clear any existing timer + if (timerInterval) { + clearInterval(timerInterval); + } + + // Start the timer + timerInterval = setInterval(() => { + timeLeft--; + updateTimerDisplay(); + + if (timeLeft <= 0) { + // Time's up + clearInterval(timerInterval); + timeOut(); + } + }, 1000); + } else { + // Hide timer if disabled + timerContainer.style.display = 'none'; + } +} + +// Update the timer display +function updateTimerDisplay() { + // Update text + timerText.textContent = `${timeLeft}s`; + + // Update progress bar + const percentage = (timeLeft / gameSettings.timerSeconds) * 100; + timerBar.style.width = `${percentage}%`; + + // Change color based on time left + timerBar.className = 'timer-bar'; + if (timeLeft <= Math.floor(gameSettings.timerSeconds / 3)) { + timerBar.classList.add('danger'); + } else if (timeLeft <= Math.floor(gameSettings.timerSeconds / 2)) { + timerBar.classList.add('warning'); + } +} + +// Handle time out +function timeOut() { + // Show feedback + feedback.textContent = gameSettings.language === 'arabic' + ? 'انتهى الوقت!' + : 'Time\'s up!'; + feedback.classList.add('incorrect'); + + // Switch players after a delay + setTimeout(() => { + hideQuestionModal(); + switchPlayer(); + }, 1500); +} + +// Check the answer +function checkAnswer(userAnswer, shuffleMap = null) { + // Clear the timer if it's running + if (timerInterval) { + clearInterval(timerInterval); + timerInterval = null; + } + + // Get all answer options + const options = document.querySelectorAll('.answer-option'); + + // Determine if the answer is correct + let isCorrect = false; + + if (gameSettings.questionType === 'truefalse') { + isCorrect = userAnswer === currentQuestion.answer; + + // Highlight the selected option + options[userAnswer ? 0 : 1].classList.add('selected'); + + // Highlight the correct option + options[currentQuestion.answer ? 0 : 1].classList.add('correct'); + + // If wrong, highlight as incorrect + if (!isCorrect) { + options[userAnswer ? 0 : 1].classList.add('incorrect'); + } + } else { + isCorrect = userAnswer === currentQuestion.answer; + + // Find the positions in the shuffled array + let selectedPosition = -1; + let correctPosition = -1; + + if (shuffleMap) { + // Find the position of the selected answer in the shuffled array + for (let i = 0; i < options.length; i++) { + if (shuffleMap[i] === userAnswer) { + selectedPosition = i; + } + if (shuffleMap[i] === currentQuestion.answer) { + correctPosition = i; + } + } + } else { + // If no shuffle map (shouldn't happen), use original positions + selectedPosition = userAnswer; + correctPosition = currentQuestion.answer; + } + + // Highlight the selected option + if (selectedPosition >= 0 && selectedPosition < options.length) { + options[selectedPosition].classList.add('selected'); + } + + // Highlight the correct option + if (correctPosition >= 0 && correctPosition < options.length) { + options[correctPosition].classList.add('correct'); + } + + // If wrong, highlight as incorrect + if (!isCorrect && selectedPosition >= 0 && selectedPosition < options.length) { + options[selectedPosition].classList.add('incorrect'); + } + } + + // Show feedback + feedback.textContent = isCorrect + ? (gameSettings.language === 'arabic' ? 'إجابة صحيحة!' : 'Correct!') + : (gameSettings.language === 'arabic' ? 'إجابة خاطئة!' : 'Incorrect!'); + feedback.classList.add(isCorrect ? 'correct' : 'incorrect'); + + // Show explanation if available + if (currentQuestion.explanation) { + setTimeout(() => { + feedback.textContent += ' ' + currentQuestion.explanation; + }, 500); + } + + // If correct, make the move after a short delay + if (isCorrect) { + setTimeout(() => { + // Make sure we're using the player who clicked the cell + if (currentPlayer !== questionPlayer) { + // If the player has changed, switch back to the original player + currentPlayer = questionPlayer; + + // Update the active player display + player1Element.classList.toggle('active', currentPlayer === 'X'); + player2Element.classList.toggle('active', currentPlayer === 'O'); + } + + makeMove(selectedCellIndex); + hideQuestionModal(); + }, 1500); + } else { + // If incorrect, close the modal after a delay and switch players + setTimeout(() => { + hideQuestionModal(); + + // Only switch if the current player is still the one who clicked + if (currentPlayer === questionPlayer) { + switchPlayer(); + } + + // Reset the question player + questionPlayer = null; + }, 2000); + } +} + +// Hide the question modal +function hideQuestionModal() { + // Clear the timer if it's running + if (timerInterval) { + clearInterval(timerInterval); + timerInterval = null; + } + + questionModal.classList.remove('show'); +} + +// Make a move on the board +function makeMove(index) { + // Update the game board + gameBoard[index] = currentPlayer; + + // Update the cell display + cells[index].textContent = currentPlayer; + cells[index].classList.add(currentPlayer.toLowerCase()); + + // Check for win or draw + if (checkWin()) { + endGame(false); + } else if (checkDraw()) { + endGame(true); + } else { + // Switch players + switchPlayer(); + } +} + +// Switch the current player +function switchPlayer() { + currentPlayer = currentPlayer === 'X' ? 'O' : 'X'; + + // Update the active player display + player1Element.classList.toggle('active'); + player2Element.classList.toggle('active'); +} + +// Check if the current player has won +function checkWin() { + const winPatterns = [ + [0, 1, 2], [3, 4, 5], [6, 7, 8], // Rows + [0, 3, 6], [1, 4, 7], [2, 5, 8], // Columns + [0, 4, 8], [2, 4, 6] // Diagonals + ]; + + for (const pattern of winPatterns) { + const [a, b, c] = pattern; + if (gameBoard[a] && gameBoard[a] === gameBoard[b] && gameBoard[a] === gameBoard[c]) { + // Highlight the winning cells + cells[a].classList.add('highlight'); + cells[b].classList.add('highlight'); + cells[c].classList.add('highlight'); + return true; + } + } + + return false; +} + +// Check if the game is a draw +function checkDraw() { + return gameBoard.every(cell => cell !== ''); +} + +// End the game +function endGame(isDraw) { + gameActive = false; + + if (!isDraw) { + // Update scores + scores[currentPlayer]++; + document.querySelector(`#player${currentPlayer === 'X' ? '1' : '2'} .player-score`).textContent = scores[currentPlayer]; + + // Show game over message + gameResult.textContent = gameSettings.language === 'arabic' + ? `اللاعب ${currentPlayer} فاز!` + : `Player ${currentPlayer} wins!`; + } else { + // Show draw message + gameResult.textContent = gameSettings.language === 'arabic' ? 'تعادل!' : 'It\'s a draw!'; + } + + // Show game over modal + setTimeout(() => { + gameOverModal.classList.add('show'); + }, 1000); +} + +// Reset the current game +function resetGame() { + // Clear the board + gameBoard = ['', '', '', '', '', '', '', '', '']; + gameActive = true; + currentPlayer = 'X'; + + // Reset the UI + cells.forEach(cell => { + cell.textContent = ''; + cell.className = 'cell'; + }); + + player1Element.classList.add('active'); + player2Element.classList.remove('active'); + + // Clear any active timers + if (timerInterval) { + clearInterval(timerInterval); + timerInterval = null; + } + + // Hide modals + questionModal.classList.remove('show'); + gameOverModal.classList.remove('show'); +} + +// Start a new game (reset game and scores) +function newGame() { + // Reset scores + scores = { X: 0, O: 0 }; + document.querySelector('#player1 .player-score').textContent = '0'; + document.querySelector('#player2 .player-score').textContent = '0'; + + // Reset the game + resetGame(); +} + +// Apply new settings +function applySettings() { + gameSettings.questionType = questionTypeSelect.value; + gameSettings.language = questionLanguageSelect.value; + gameSettings.category = questionCategorySelect.value; + gameSettings.timerSeconds = parseInt(questionTimerSelect.value); + + // Validate language-category combination + // Make sure the selected category exists for the selected language + if (gameSettings.language === 'english' && gameSettings.category !== 'math') { + // For English, only math category is available + gameSettings.category = 'math'; + questionCategorySelect.value = 'math'; + } else if (gameSettings.language === 'arabic' && + (gameSettings.category !== 'islamic' && gameSettings.category !== 'beginners')) { + // For Arabic, only islamic and beginners categories are available + gameSettings.category = 'beginners'; + questionCategorySelect.value = 'beginners'; + } + + // Update UI language if needed + updateUILanguage(); + + // Start a new game with new settings + newGame(); +} + +// Update UI language based on selected language +function updateUILanguage() { + const isArabic = gameSettings.language === 'arabic'; + + // Update document direction + document.documentElement.dir = isArabic ? 'rtl' : 'ltr'; + + // Update button texts + resetButton.textContent = isArabic ? 'إعادة اللعبة' : 'Reset Game'; + newGameButton.textContent = isArabic ? 'لعبة جديدة' : 'New Game'; + playAgainButton.textContent = isArabic ? 'العب مرة أخرى' : 'Play Again'; + applySettingsButton.textContent = isArabic ? 'تطبيق الإعدادات' : 'Apply Settings'; + + // Update headings + document.querySelector('h1').textContent = isArabic ? 'لعبة تيك تاك تو التعليمية' : 'Educational Tic Tac Toe'; + document.querySelector('.settings h3').textContent = isArabic ? 'إعدادات اللعبة' : 'Game Settings'; + document.querySelector('.used-words-container h3').textContent = isArabic ? 'الكلمات المستخدمة:' : 'Selected Words:'; + + // Update player names + document.querySelector('#player1 .player-name').textContent = isArabic ? 'اللاعب 1' : 'Player 1'; + document.querySelector('#player2 .player-name').textContent = isArabic ? 'اللاعب 2' : 'Player 2'; + + // Update settings labels + const labels = document.querySelectorAll('.setting-group label'); + if (isArabic) { + labels[0].textContent = 'نوع السؤال:'; + labels[1].textContent = 'اللغة:'; + labels[2].textContent = 'الفئة:'; + labels[3].textContent = 'الوقت المحدد (ثواني):'; + } else { + labels[0].textContent = 'Question Type:'; + labels[1].textContent = 'Language:'; + labels[2].textContent = 'Category:'; + labels[3].textContent = 'Time Limit (seconds):'; + } + + // Update modal texts + document.querySelector('#questionModal h2').textContent = isArabic + ? 'أجب على السؤال لإجراء حركتك' + : 'Answer the question to make your move'; +} + +// Update the game display +function updateGameDisplay() { + // Update UI language + updateUILanguage(); + + // Update player scores + document.querySelector('#player1 .player-score').textContent = scores.X; + document.querySelector('#player2 .player-score').textContent = scores.O; + + // Update active player + player1Element.classList.toggle('active', currentPlayer === 'X'); + player2Element.classList.toggle('active', currentPlayer === 'O'); +} + +// Utility function to shuffle an array (Fisher-Yates algorithm) +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; +} + +// Initialize the game when the page loads +window.addEventListener('load', initGame); \ No newline at end of file diff --git a/tictactoe/index.html b/tictactoe/index.html new file mode 100644 index 0000000..3eb073f --- /dev/null +++ b/tictactoe/index.html @@ -0,0 +1,109 @@ + + + + + + Educational Tic Tac Toe + + + +
+

Educational Tic Tac Toe

+ +
+
+
+ X + Player 1 + 0 +
+
+ O + Player 2 + 0 +
+
+
+ + +
+
+ +
+
+
+
+
+
+
+
+
+
+
+ + + + + +
+

Game Settings

+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ +
+
+ + + + + \ No newline at end of file diff --git a/tictactoe/questions.js b/tictactoe/questions.js new file mode 100644 index 0000000..80edc37 --- /dev/null +++ b/tictactoe/questions.js @@ -0,0 +1,439 @@ +// Questions database for the Educational Tic Tac Toe game +// Organized by language, category, and question type + +const questionsDB = { + english: { + math: { + truefalse: [ + { + question: "The sum of angles in a triangle is 180 degrees.", + answer: true, + explanation: "In Euclidean geometry, the sum of the angles in any triangle is 180 degrees." + }, + { + question: "Pi (π) is exactly equal to 22/7.", + answer: false, + explanation: "22/7 is just an approximation of pi. Pi is an irrational number." + }, + { + question: "Any number raised to the power of 0 equals 1.", + answer: true, + explanation: "By definition, any non-zero number raised to the power of 0 equals 1." + }, + { + question: "The square root of 4 is 2.", + answer: true, + explanation: "The square root of 4 is 2 because 2 × 2 = 4." + }, + { + question: "There are 13 prime numbers less than 40.", + answer: false, + explanation: "There are 12 prime numbers less than 40: 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, and 37." + } + ], + multiplechoice: [ + { + question: "What is 7 × 8?", + options: ["54", "56", "64", "72"], + answer: 1, + explanation: "7 × 8 = 56" + }, + { + question: "Which of these is a prime number?", + options: ["15", "21", "27", "29"], + answer: 3, + explanation: "29 is a prime number because it is only divisible by 1 and itself." + }, + { + question: "What is the area of a square with sides of length 5?", + options: ["10", "20", "25", "30"], + answer: 2, + explanation: "The area of a square is side length squared: 5² = 25" + }, + { + question: "If x + 5 = 12, what is x?", + options: ["5", "7", "12", "17"], + answer: 1, + explanation: "x + 5 = 12, so x = 12 - 5 = 7" + }, + { + question: "What is the next number in the sequence: 2, 4, 8, 16, ...?", + options: ["24", "32", "36", "64"], + answer: 1, + explanation: "Each number is doubled to get the next number. 16 × 2 = 32" + } + ] + } + }, + arabic: { + islamic: { + multiplechoice: [ + { + question: "س: من هو النبي محمد ﷺ؟", + options: [ + "هو محمد بن عبد الله بن عبد المطلب، آخر الأنبياء والمرسلين", + "هو عيسى بن مريم، نبي من أنبياء الله", + "هو موسى بن عمران، كليم الله", + "هو إبراهيم الخليل، أبو الأنبياء" + ], + answer: 0, + explanation: "ج: هو محمد بن عبد الله بن عبد المطلب، آخر الأنبياء والمرسلين" + }, + { + question: "س: متى ولد النبي ﷺ؟", + options: [ + "ولد يوم الاثنين 12 ربيع الأول في عام الفيل (حوالي سنة 571 ميلادية)", + "ولد يوم الجمعة 17 رمضان (حوالي سنة 570 ميلادية)", + "ولد يوم الأربعاء 10 محرم (حوالي سنة 569 ميلادية)", + "ولد يوم السبت 25 شوال (حوالي سنة 572 ميلادية)" + ], + answer: 0, + explanation: "ج: ولد يوم الاثنين 12 ربيع الأول في عام الفيل (حوالي سنة 571 ميلادية)" + }, + { + question: "س: لماذا سمي النبي ﷺ بالصادق الأمين؟", + options: [ + "لأنه كان معروفًا بالصدق والأمانة بين الناس قبل البعثة", + "لأنه كان يحب الصدق ويكره الكذب", + "لأن قريش أطلقت عليه هذا اللقب بعد الهجرة", + "لأنه كان يأمر الناس بالصدق والأمانة" + ], + answer: 0, + explanation: "ج: لأنه كان معروفًا بالصدق والأمانة بين الناس قبل البعثة." + }, + { + question: "س: كم كان عمر النبي ﷺ عندما نزل عليه الوحي؟", + options: [ + "30 سنة", + "35 سنة", + "40 سنة", + "45 سنة" + ], + answer: 2, + explanation: "ج: كان عمره 40 سنة" + }, + { + question: "س: أين نزل أول وحي على النبي ﷺ؟", + options: [ + "في المسجد الحرام", + "في غار حراء بمكة", + "في بيته", + "في المدينة المنورة" + ], + answer: 1, + explanation: "ج: في غار حراء بمكة" + }, + { + question: "س: ما هي أول آية نزلت على النبي ﷺ؟", + options: [ + "﴿اقْرَأْ بِاسْمِ رَبِّكَ الَّذِي خَلَقَ﴾", + "﴿بِسْمِ اللَّهِ الرَّحْمَنِ الرَّحِيمِ﴾", + "﴿الْحَمْدُ لِلَّهِ رَبِّ الْعَالَمِينَ﴾", + "﴿يَا أَيُّهَا الْمُدَّثِّرُ﴾" + ], + answer: 0, + explanation: "ج: ﴿اقْرَأْ بِاسْمِ رَبِّكَ الَّذِي خَلَقَ﴾ (سورة العلق:1)." + } + ] + }, + beginners: { + truefalse: [ + { + question: "كتاب = boek (Nederlands) / book (English)", + answer: true, + explanation: "Correct! كتاب betekent 'boek' in het Nederlands" + }, + { + question: "قلم = tafel (Nederlands) / table (English)", + answer: false, + explanation: "Nee, قلم betekent 'pen' in het Nederlands. 'Tafel' is طاولة in het Arabisch" + }, + { + question: "باب = deur (Nederlands) / door (English)", + answer: true, + explanation: "Correct! باب betekent 'deur' in het Nederlands" + }, + { + question: "ماء = vuur (Nederlands) / fire (English)", + answer: false, + explanation: "Nee, ماء betekent 'water' in het Nederlands. 'Vuur' is نار in het Arabisch" + }, + { + question: "شمس = zon (Nederlands) / sun (English)", + answer: true, + explanation: "Correct! شمس betekent 'zon' in het Nederlands" + }, + { + question: "طعام = eten (Nederlands) / food (English)", + answer: true, + explanation: "Correct! طعام betekent 'eten' in het Nederlands" + }, + { + question: "يد = voet (Nederlands) / foot (English)", + answer: false, + explanation: "Nee, يد betekent 'hand' in het Nederlands. 'Voet' is قدم in het Arabisch" + }, + { + question: "قطة = kat (Nederlands) / cat (English)", + answer: true, + explanation: "Correct! قطة betekent 'kat' in het Nederlands" + }, + { + question: "عين = oog (Nederlands) / eye (English)", + answer: true, + explanation: "Correct! عين betekent 'oog' in het Nederlands" + }, + { + question: "أنف = oor (Nederlands) / ear (English)", + answer: false, + explanation: "Nee, أنف betekent 'neus' in het Nederlands. 'Oor' is أذن in het Arabisch" + }, + { + question: "فم = mond (Nederlands) / mouth (English)", + answer: true, + explanation: "Correct! فم betekent 'mond' in het Nederlands" + }, + { + question: "رأس = haar (Nederlands) / hair (English)", + answer: false, + explanation: "Nee, رأس betekent 'hoofd' in het Nederlands. 'Haar' is شعر in het Arabisch" + }, + { + question: "قدم = voet (Nederlands) / foot (English)", + answer: true, + explanation: "Correct! قدم betekent 'voet' in het Nederlands" + }, + { + question: "أب = moeder (Nederlands) / mother (English)", + answer: false, + explanation: "Nee, أب betekent 'vader' in het Nederlands. 'Moeder' is أم in het Arabisch" + }, + { + question: "أخ = broer (Nederlands) / brother (English)", + answer: true, + explanation: "Correct! أخ betekent 'broer' in het Nederlands" + }, + { + question: "جد = opa (Nederlands) / grandfather (English)", + answer: true, + explanation: "Correct! جد betekent 'opa' in het Nederlands" + }, + { + question: "جدة = tante (Nederlands) / aunt (English)", + answer: false, + explanation: "Nee, جدة betekent 'oma' in het Nederlands. 'Tante' is عمة of خالة in het Arabisch" + }, + { + question: "صديق = vriend (Nederlands) / friend (English)", + answer: true, + explanation: "Correct! صديق betekent 'vriend' in het Nederlands" + }, + { + question: "مطبخ = badkamer (Nederlands) / bathroom (English)", + answer: false, + explanation: "Nee, مطبخ betekent 'keuken' in het Nederlands. 'Badkamer' is حمام in het Arabisch" + }, + { + question: "غرفة = kamer (Nederlands) / room (English)", + answer: true, + explanation: "Correct! غرفة betekent 'kamer' in het Nederlands" + }, + { + question: "سرير = stoel (Nederlands) / chair (English)", + answer: false, + explanation: "Nee, سرير betekent 'bed' in het Nederlands. 'Stoel' is كرسي in het Arabisch" + }, + { + question: "طاولة = tafel (Nederlands) / table (English)", + answer: true, + explanation: "Correct! طاولة betekent 'tafel' in het Nederlands" + }, + { + question: "حليب = melk (Nederlands) / milk (English)", + answer: true, + explanation: "Correct! حليب betekent 'melk' in het Nederlands" + }, + { + question: "بيضة = kaas (Nederlands) / cheese (English)", + answer: false, + explanation: "Nee, بيضة betekent 'ei' in het Nederlands. 'Kaas' is جبن in het Arabisch" + }, + { + question: "لحم = vlees (Nederlands) / meat (English)", + answer: true, + explanation: "Correct! لحم betekent 'vlees' in het Nederlands" + } + ], + multiplechoice: [ + { + question: "بيت", + options: ["Auto / Car", "Huis / House", "School / School", "Boom / Tree"], + answer: 1, + explanation: "Correct! بيت betekent 'huis' in het Nederlands (house in English)" + }, + { + question: "مدرسة", + options: ["Ziekenhuis / Hospital", "Markt / Market", "School / School", "Bibliotheek / Library"], + answer: 2, + explanation: "Correct! مدرسة betekent 'school' in het Nederlands" + }, + { + question: "سيارة", + options: ["Auto / Car", "Bus / Bus", "Fiets / Bicycle", "Trein / Train"], + answer: 0, + explanation: "Correct! سيارة betekent 'auto' in het Nederlands (car in English)" + }, + { + question: "قمر", + options: ["Ster / Star", "Zon / Sun", "Maan / Moon", "Planeet / Planet"], + answer: 2, + explanation: "Correct! قمر betekent 'maan' in het Nederlands (moon in English)" + }, + { + question: "كلب", + options: ["Kat / Cat", "Hond / Dog", "Vogel / Bird", "Vis / Fish"], + answer: 1, + explanation: "Correct! كلب betekent 'hond' in het Nederlands (dog in English)" + }, + { + question: "طفل", + options: ["Man / Man", "Vrouw / Woman", "Kind / Child", "Opa / Grandfather"], + answer: 2, + explanation: "Correct! طفل betekent 'kind' in het Nederlands (child in English)" + }, + { + question: "فاكهة", + options: ["Fruit / Fruit", "Groente / Vegetable", "Vlees / Meat", "Brood / Bread"], + answer: 0, + explanation: "Correct! فاكهة betekent 'fruit' in het Nederlands" + }, + { + question: "نافذة", + options: ["Deur / Door", "Raam / Window", "Muur / Wall", "Vloer / Floor"], + answer: 1, + explanation: "Correct! نافذة betekent 'raam' in het Nederlands (window in English)" + }, + { + question: "شعر", + options: ["Haar / Hair", "Oog / Eye", "Neus / Nose", "Oor / Ear"], + answer: 0, + explanation: "Correct! شعر betekent 'haar' in het Nederlands (hair in English)" + }, + { + question: "أذن", + options: ["Neus / Nose", "Mond / Mouth", "Oor / Ear", "Tand / Tooth"], + answer: 2, + explanation: "Correct! أذن betekent 'oor' in het Nederlands (ear in English)" + }, + { + question: "أم", + options: ["Vader / Father", "Moeder / Mother", "Zus / Sister", "Broer / Brother"], + answer: 1, + explanation: "Correct! أم betekent 'moeder' in het Nederlands (mother in English)" + }, + { + question: "أخت", + options: ["Oom / Uncle", "Tante / Aunt", "Broer / Brother", "Zus / Sister"], + answer: 3, + explanation: "Correct! أخت betekent 'zus' in het Nederlands (sister in English)" + }, + { + question: "خبز", + options: ["Brood / Bread", "Kaas / Cheese", "Melk / Milk", "Ei / Egg"], + answer: 0, + explanation: "Correct! خبز betekent 'brood' in het Nederlands (bread in English)" + }, + { + question: "ماء", + options: ["Koffie / Coffee", "Thee / Tea", "Water / Water", "Sap / Juice"], + answer: 2, + explanation: "Correct! ماء betekent 'water' in het Nederlands" + }, + { + question: "تفاحة", + options: ["Banaan / Banana", "Appel / Apple", "Sinaasappel / Orange", "Aardbei / Strawberry"], + answer: 1, + explanation: "Correct! تفاحة betekent 'appel' in het Nederlands (apple in English)" + }, + { + question: "موز", + options: ["Appel / Apple", "Peer / Pear", "Banaan / Banana", "Druif / Grape"], + answer: 2, + explanation: "Correct! موز betekent 'banaan' in het Nederlands (banana in English)" + }, + { + question: "برتقال", + options: ["Aardbei / Strawberry", "Sinaasappel / Orange", "Citroen / Lemon", "Kiwi / Kiwi"], + answer: 1, + explanation: "Correct! برتقال betekent 'sinaasappel' in het Nederlands (orange in English)" + }, + { + question: "دجاج", + options: ["Vlees / Meat", "Vis / Fish", "Kip / Chicken", "Varken / Pork"], + answer: 2, + explanation: "Correct! دجاج betekent 'kip' in het Nederlands (chicken in English)" + }, + { + question: "سمك", + options: ["Kip / Chicken", "Vlees / Meat", "Varken / Pork", "Vis / Fish"], + answer: 3, + explanation: "Correct! سمك betekent 'vis' in het Nederlands (fish in English)" + }, + { + question: "جبن", + options: ["Kaas / Cheese", "Boter / Butter", "Yoghurt / Yogurt", "Room / Cream"], + answer: 0, + explanation: "Correct! جبن betekent 'kaas' in het Nederlands (cheese in English)" + }, + { + question: "بيضة", + options: ["Melk / Milk", "Ei / Egg", "Boter / Butter", "Suiker / Sugar"], + answer: 1, + explanation: "Correct! بيضة betekent 'ei' in het Nederlands (egg in English)" + }, + { + question: "كرسي", + options: ["Tafel / Table", "Stoel / Chair", "Kast / Cabinet", "Bed / Bed"], + answer: 1, + explanation: "Correct! كرسي betekent 'stoel' in het Nederlands (chair in English)" + }, + { + question: "سرير", + options: ["Kast / Cabinet", "Tafel / Table", "Stoel / Chair", "Bed / Bed"], + answer: 3, + explanation: "Correct! سرير betekent 'bed' in het Nederlands (bed in English)" + }, + { + question: "مطبخ", + options: ["Keuken / Kitchen", "Badkamer / Bathroom", "Slaapkamer / Bedroom", "Woonkamer / Living room"], + answer: 0, + explanation: "Correct! مطبخ betekent 'keuken' in het Nederlands (kitchen in English)" + }, + { + question: "حمام", + options: ["Slaapkamer / Bedroom", "Woonkamer / Living room", "Badkamer / Bathroom", "Keuken / Kitchen"], + answer: 2, + explanation: "Correct! حمام betekent 'badkamer' in het Nederlands (bathroom in English)" + } + ] + } + } +}; + +// Function to get a random question based on settings +function getRandomQuestion(language, category, type) { + // Validate parameters + if (!questionsDB[language] || !questionsDB[language][category] || !questionsDB[language][category][type]) { + console.error(`Invalid question parameters: ${language}, ${category}, ${type}`); + return null; + } + + // Get the questions array + const questions = questionsDB[language][category][type]; + + // Return a random question + return questions[Math.floor(Math.random() * questions.length)]; +} + +// Export the function for use in other files +window.getRandomQuestion = getRandomQuestion; \ No newline at end of file diff --git a/tictactoe/styles.css b/tictactoe/styles.css new file mode 100644 index 0000000..42098aa --- /dev/null +++ b/tictactoe/styles.css @@ -0,0 +1,352 @@ +* { + margin: 0; + padding: 0; + box-sizing: border-box; + font-family: Arial, sans-serif; +} + +body { + background-color: #f5f5f5; + display: flex; + justify-content: center; + padding: 20px; +} + +.container { + width: 100%; + max-width: 800px; + background-color: white; + border-radius: 10px; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); + padding: 20px; +} + +h1 { + text-align: center; + margin-bottom: 20px; + color: #333; +} + +/* Game Info Styles */ +.game-info { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 20px; + padding: 10px; + background-color: #f0f0f0; + border-radius: 5px; +} + +.player-info { + display: flex; + gap: 20px; +} + +.player { + display: flex; + flex-direction: column; + align-items: center; + padding: 10px; + border-radius: 5px; + opacity: 0.7; + transition: all 0.3s; +} + +.player.active { + background-color: #e3f2fd; + opacity: 1; + box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); +} + +.player-symbol { + font-size: 24px; + font-weight: bold; + margin-bottom: 5px; +} + +.player-name { + font-size: 14px; +} + +.player-score { + font-size: 18px; + font-weight: bold; + margin-top: 5px; +} + +.game-controls { + display: flex; + gap: 10px; +} + +button { + padding: 10px 15px; + border: none; + border-radius: 5px; + background-color: #4CAF50; + color: white; + cursor: pointer; + font-size: 16px; + transition: background-color 0.3s; +} + +button:hover { + background-color: #45a049; +} + +#resetBtn { + background-color: #f44336; +} + +#resetBtn:hover { + background-color: #d32f2f; +} + +/* Game Board Styles */ +.game-board { + display: grid; + grid-template-columns: repeat(3, 1fr); + grid-gap: 10px; + margin: 0 auto 30px; + max-width: 400px; +} + +.cell { + aspect-ratio: 1/1; + background-color: #e0e0e0; + border-radius: 5px; + display: flex; + align-items: center; + justify-content: center; + font-size: 48px; + font-weight: bold; + cursor: pointer; + transition: all 0.3s; +} + +.cell:hover { + background-color: #d0d0d0; +} + +.cell.x { + color: #f44336; +} + +.cell.o { + color: #2196F3; +} + +.cell.highlight { + background-color: #ffeb3b; +} + +/* Modal Styles */ +.modal { + display: none; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.5); + z-index: 100; + justify-content: center; + align-items: center; +} + +.modal.show { + display: flex; +} + +.modal-content { + background-color: white; + padding: 30px; + border-radius: 10px; + max-width: 500px; + width: 90%; + box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3); +} + +.modal h2 { + margin-bottom: 20px; + text-align: center; + color: #333; +} + +.timer-container { + width: 100%; + height: 30px; + background-color: #f0f0f0; + border-radius: 15px; + margin-bottom: 15px; + position: relative; + overflow: hidden; +} + +.timer-bar { + height: 100%; + width: 100%; + background-color: #4CAF50; + border-radius: 15px; + transition: width 1s linear; +} + +.timer-text { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + font-weight: bold; + color: #333; +} + +.timer-bar.warning { + background-color: #FFC107; +} + +.timer-bar.danger { + background-color: #F44336; +} + +.question-text { + font-size: 28px; + margin-bottom: 30px; + line-height: 1.6; + text-align: center; + font-weight: bold; +} + +.answer-options { + display: flex; + flex-direction: column; + gap: 15px; + margin-bottom: 25px; +} + +.answer-option { + padding: 20px; + border: 3px solid #ddd; + border-radius: 8px; + cursor: pointer; + transition: all 0.3s; + font-size: 22px; + text-align: center; +} + +.answer-option:hover { + background-color: #f5f5f5; + border-color: #bbb; +} + +.answer-option.selected { + border-color: #2196F3; + background-color: #e3f2fd; +} + +.answer-option.correct { + border-color: #4CAF50; + background-color: #e8f5e9; +} + +.answer-option.incorrect { + border-color: #f44336; + background-color: #ffebee; +} + +.feedback { + text-align: center; + font-weight: bold; + margin-top: 25px; + min-height: 30px; + font-size: 24px; + padding: 15px; + border-radius: 8px; +} + +.feedback.correct { + color: #4CAF50; + background-color: #e8f5e9; + border: 3px solid #4CAF50; +} + +.feedback.incorrect { + color: #f44336; + background-color: #ffebee; + border: 3px solid #f44336; +} + +/* Settings Styles */ +.settings { + margin-top: 30px; + padding: 20px; + background-color: #f9f9f9; + border-radius: 5px; +} + +.settings h3 { + margin-bottom: 15px; + color: #333; +} + +.setting-group { + margin-bottom: 15px; + display: flex; + align-items: center; +} + +.setting-group label { + width: 120px; + font-weight: bold; + color: #555; +} + +.setting-group select { + flex: 1; + padding: 8px; + border-radius: 5px; + border: 1px solid #ddd; + font-size: 16px; + background-color: white; +} + +#applySettingsBtn { + margin-top: 10px; + background-color: #2196F3; +} + +#applySettingsBtn:hover { + background-color: #1976D2; +} + +/* RTL Support for Arabic */ +[lang="ar"] { + direction: rtl; + text-align: right; +} + +/* Responsive Styles */ +@media (max-width: 600px) { + .game-info { + flex-direction: column; + gap: 15px; + } + + .cell { + font-size: 36px; + } + + .setting-group { + flex-direction: column; + align-items: flex-start; + } + + .setting-group label { + margin-bottom: 5px; + width: 100%; + } + + .setting-group select { + width: 100%; + } +} \ No newline at end of file