generated from technolyceum/ai6-m2
225 lines
7.4 KiB
Markdown
225 lines
7.4 KiB
Markdown
INNA - FRONTEND DEVELOPER MISSION
|
|
Your Role: Game Interface Designer | Your Files: templates/ and static/script.js
|
|
|
|
💡 What You're Building: You're creating what players see and click on!
|
|
|
|
📋 LESSON 1-2: SETUP & BASIC GAME FLOW
|
|
|
|
Step 1: Fork and Clone (10 minutes)
|
|
1. Go to: https://gitea.techshare.cc/technolyceum/ai6-m2
|
|
2. Click the "Fork" button (creates your copy)
|
|
3. Copy your forked repository URL
|
|
4. Open Terminal and type:
|
|
git clone [YOUR-FORKED-URL-HERE]
|
|
cd ai6-m2
|
|
git checkout -b inna-frontend-work
|
|
|
|
Step 2: Review Question Loading (15 minutes)
|
|
Open static/script.js and look at the [loadQuestion](file:///Users/home/YandexDisk/TECHNOLYCEUM/ict_repos/ai6-m2/static/script.js#L9-L19) function:
|
|
|
|
```javascript
|
|
function loadQuestion() {
|
|
apiRequest('/get_question')
|
|
.then(data => {
|
|
if (data.game_over) {
|
|
endGame(data.final_score);
|
|
return;
|
|
}
|
|
|
|
currentQuestion = data;
|
|
displayQuestion(data);
|
|
})
|
|
.catch(error => console.error('Error:', error));
|
|
}
|
|
```
|
|
|
|
Notice how it uses the [apiRequest](file:///Users/home/YandexDisk/TECHNOLYCEUM/ict_repos/ai6-m2/static/script.js#L5-L12) utility function for cleaner code.
|
|
|
|
Step 3: Review Question Display (15 minutes)
|
|
Look at the [displayQuestion](file:///Users/home/YandexDisk/TECHNOLYCEUM/ict_repos/ai6-m2/static/script.js#L21-L41) function:
|
|
|
|
```javascript
|
|
function displayQuestion(data) {
|
|
updateElementText('q-number', data.question_number);
|
|
updateElementText('question-text', data.question);
|
|
updateElementText('prize', data.current_prize);
|
|
|
|
const optionsContainer = document.getElementById('options');
|
|
optionsContainer.innerHTML = '';
|
|
|
|
data.options.forEach((option, index) => {
|
|
const optionElement = document.createElement('div');
|
|
optionElement.className = 'option';
|
|
optionElement.textContent = option;
|
|
optionElement.onclick = () => selectAnswer(option);
|
|
optionsContainer.appendChild(optionElement);
|
|
});
|
|
|
|
// Reset result display
|
|
toggleElementVisibility('result', false);
|
|
const result = document.getElementById('result');
|
|
if (result) {
|
|
result.className = 'result';
|
|
}
|
|
}
|
|
```
|
|
|
|
Notice the utility functions:
|
|
- [updateElementText()](file:///Users/home/YandexDisk/TECHNOLYCEUM/ict_repos/ai6-m2/static/script.js#L14-L19) - Simplifies updating element text
|
|
- [toggleElementVisibility()](file:///Users/home/YandexDisk/TECHNOLYCEUM/ict_repos/ai6-m2/static/script.js#L21-L27) - Standardizes showing/hiding elements
|
|
|
|
📋 LESSON 3-4: ANSWER HANDLING & LIFELINES
|
|
|
|
Step 4: Review Answer Selection (15 minutes)
|
|
Check the [selectAnswer](file:///Users/home/YandexDisk/TECHNOLYCEUM/ict_repos/ai6-m2/static/script.js#L43-L72) function:
|
|
|
|
```javascript
|
|
function selectAnswer(answer) {
|
|
apiRequest('/answer', {
|
|
method: 'POST',
|
|
headers: {'Content-Type': 'application/json'},
|
|
body: JSON.stringify({ answer: answer })
|
|
})
|
|
.then(data => {
|
|
const result = document.getElementById('result');
|
|
if (result) {
|
|
result.style.display = 'block';
|
|
|
|
if (data.correct) {
|
|
result.textContent = 'Correct!';
|
|
result.className = 'result correct';
|
|
|
|
setTimeout(() => {
|
|
if (data.game_over) {
|
|
endGame(data.final_score);
|
|
} else {
|
|
loadQuestion();
|
|
}
|
|
}, 1500);
|
|
} else {
|
|
result.textContent = `Wrong! Correct answer: ${data.correct_answer}`;
|
|
result.className = 'result incorrect';
|
|
|
|
setTimeout(() => {
|
|
endGame(data.final_score);
|
|
}, 2000);
|
|
}
|
|
}
|
|
})
|
|
.catch(error => console.error('Error:', error));
|
|
}
|
|
```
|
|
|
|
Step 5: Review Lifeline Implementation (15 minutes)
|
|
Look at the [useFiftyFifty](file:///Users/home/YandexDisk/TECHNOLYCEUM/ict_repos/ai6-m2/static/script.js#L74-L100) function:
|
|
|
|
```javascript
|
|
function useFiftyFifty() {
|
|
const lifelineBtn = document.querySelector('.lifeline');
|
|
if (lifelineBtn) {
|
|
lifelineBtn.disabled = true;
|
|
}
|
|
|
|
apiRequest('/lifeline/fifty_fifty')
|
|
.then(data => {
|
|
if (data.error) {
|
|
alert(data.error);
|
|
if (lifelineBtn) {
|
|
lifelineBtn.disabled = false;
|
|
}
|
|
return;
|
|
}
|
|
|
|
// Hide two wrong options
|
|
const options = document.querySelectorAll('.option');
|
|
data.remove_indices.forEach(index => {
|
|
if (options[index]) {
|
|
options[index].style.display = 'none';
|
|
}
|
|
});
|
|
})
|
|
.catch(error => {
|
|
console.error('Error:', error);
|
|
if (lifelineBtn) {
|
|
lifelineBtn.disabled = false;
|
|
}
|
|
});
|
|
}
|
|
```
|
|
|
|
Notice the improvements:
|
|
- Uses the [apiRequest](file:///Users/home/YandexDisk/TECHNOLYCEUM/ict_repos/ai6-m2/static/script.js#L5-L12) utility function
|
|
- Has proper error handling with element checks
|
|
- Cleaner, more maintainable code
|
|
|
|
Step 6: Review Utility Functions (10 minutes)
|
|
At the top of script.js, notice the utility functions that make the code DRY:
|
|
|
|
```javascript
|
|
// Utility function for making API requests
|
|
function apiRequest(url, options = {}) {
|
|
return fetch(url, options)
|
|
.then(response => response.json())
|
|
.catch(error => {
|
|
console.error('Error:', error);
|
|
throw error;
|
|
});
|
|
}
|
|
|
|
// Utility function for updating element text content
|
|
function updateElementText(id, text) {
|
|
const element = document.getElementById(id);
|
|
if (element) {
|
|
element.textContent = text;
|
|
}
|
|
}
|
|
|
|
// Utility function for showing/hiding elements
|
|
function toggleElementVisibility(id, show = true) {
|
|
const element = document.getElementById(id);
|
|
if (element) {
|
|
element.style.display = show ? 'block' : 'none';
|
|
}
|
|
}
|
|
```
|
|
|
|
📋 LESSON 5-6: GAME FLOW COMPLETION
|
|
|
|
Step 7: Review Game End and Restart (10 minutes)
|
|
Look at the [endGame](file:///Users/home/YandexDisk/TECHNOLYCEUM/ict_repos/ai6-m2/static/script.js#L102-L108) and [restartGame](file:///Users/home/YandexDisk/TECHNOLYCEUM/ict_repos/ai6-m2/static/script.js#L110-L112) functions:
|
|
|
|
```javascript
|
|
function endGame(score) {
|
|
updateElementText('final-prize', score);
|
|
toggleElementVisibility('game-over', true);
|
|
toggleElementVisibility('question-box', false);
|
|
toggleElementVisibility('lifeline', false);
|
|
}
|
|
|
|
function restartGame() {
|
|
window.location.href = '/start';
|
|
}
|
|
```
|
|
|
|
Notice how they use the utility functions to simplify the code.
|
|
|
|
✅ INNA'S COMPLETION CHECKLIST
|
|
☐ Review question loading implementation
|
|
☐ Understand question display logic
|
|
☐ Review answer handling process
|
|
☐ Understand lifeline implementation
|
|
☐ Recognize utility functions for DRY code
|
|
☐ Review game flow completion
|
|
☐ All code pushed to your branch
|
|
☐ Created Pull Request for teacher to review
|
|
|
|
## Connection Requirements
|
|
|
|
The frontend communicates with the backend API, which must be properly configured with the MongoDB connection string:
|
|
```python
|
|
MONGO_URI = "mongodb://ai6s3:Student123!@localhost:27017/student_db"
|
|
```
|
|
|
|
Ensure the backend developer has correctly configured this connection string in the application's configuration.
|
|
|
|
🎉 Congratulations Inna! You built the entire game interface! |