first
This commit is contained in:
@@ -0,0 +1,211 @@
|
||||
from flask import Flask, render_template, request, jsonify, session, send_file
|
||||
from questions import QUESTION_POOL
|
||||
import random
|
||||
import uuid
|
||||
import qrcode
|
||||
from io import BytesIO
|
||||
import os
|
||||
import json
|
||||
from datetime import datetime
|
||||
|
||||
app = Flask(__name__)
|
||||
app.secret_key = 'dnr_youth_parliament_secret_key_2024'
|
||||
|
||||
# Хранилище сессий игроков и результатов
|
||||
active_games = {}
|
||||
saved_results = {} # Сохраняем результаты для QR-кодов
|
||||
|
||||
|
||||
class QuizGame:
|
||||
def __init__(self):
|
||||
self.game_id = str(uuid.uuid4())[:8]
|
||||
self.questions_pool = QUESTION_POOL.copy()
|
||||
self.selected_questions = []
|
||||
self.current_question_index = 0
|
||||
self.score = 0
|
||||
self.is_active = True
|
||||
self.user_answers = []
|
||||
self.start_time = datetime.now()
|
||||
self._select_random_questions()
|
||||
|
||||
def _select_random_questions(self):
|
||||
"""Выбирает 7 случайных вопросов из пула"""
|
||||
if len(self.questions_pool) >= 7:
|
||||
self.selected_questions = random.sample(self.questions_pool, 7)
|
||||
else:
|
||||
self.selected_questions = self.questions_pool.copy()
|
||||
|
||||
# Добавляем тайминг к каждому вопросу
|
||||
for q in self.selected_questions:
|
||||
q['time_limit'] = 10
|
||||
|
||||
def get_current_question(self):
|
||||
"""Возвращает текущий вопрос (без правильного ответа)"""
|
||||
if self.current_question_index < len(self.selected_questions):
|
||||
q = self.selected_questions[self.current_question_index]
|
||||
return {
|
||||
'id': self.current_question_index,
|
||||
'text': q['text'],
|
||||
'options': q['options'],
|
||||
'time_limit': q.get('time_limit', 10)
|
||||
}
|
||||
return None
|
||||
|
||||
def check_answer(self, answer_index):
|
||||
"""Проверяет ответ и обновляет счет"""
|
||||
current_q = self.selected_questions[self.current_question_index]
|
||||
is_correct = (answer_index == current_q['correct'])
|
||||
|
||||
# Сохраняем ответ пользователя
|
||||
self.user_answers.append({
|
||||
'question_text': current_q['text'],
|
||||
'options': current_q['options'],
|
||||
'user_answer': answer_index,
|
||||
'user_answer_text': current_q['options'][answer_index] if answer_index != -1 else 'Время вышло',
|
||||
'correct_answer': current_q['options'][current_q['correct']],
|
||||
'correct_index': current_q['correct'],
|
||||
'is_correct': is_correct,
|
||||
'explanation': current_q.get('explanation', '')
|
||||
})
|
||||
|
||||
if is_correct:
|
||||
self.score += 1
|
||||
|
||||
self.current_question_index += 1
|
||||
|
||||
return {
|
||||
'is_correct': is_correct,
|
||||
'correct_answer': current_q['options'][current_q['correct']],
|
||||
'explanation': current_q.get('explanation', ''),
|
||||
'score': self.score,
|
||||
'is_finished': self.current_question_index >= len(self.selected_questions),
|
||||
'total_questions': len(self.selected_questions)
|
||||
}
|
||||
|
||||
def get_result(self):
|
||||
"""Возвращает результат теста со всеми вопросами"""
|
||||
total = len(self.selected_questions)
|
||||
percentage = (self.score / total) * 100
|
||||
|
||||
# Определение звания/результата
|
||||
if percentage >= 90:
|
||||
grade = "🏆 Депутат высшей категории!"
|
||||
message = "Вы отлично знаете историю и структуру Молодёжного Парламента ДНР!"
|
||||
elif percentage >= 70:
|
||||
grade = "⭐ Активный парламентарий!"
|
||||
message = "Хороший результат! Вы достойно показали свои знания."
|
||||
elif percentage >= 50:
|
||||
grade = "📚 Кандидат в парламент!"
|
||||
message = "Неплохо, но есть куда расти. Рекомендуем изучить материалы о работе Парламента."
|
||||
else:
|
||||
grade = "🌱 Будущий лидер!"
|
||||
message = "Не расстраивайтесь! Участие в викторине - первый шаг к большим достижениям."
|
||||
|
||||
# Сохраняем результат для QR-кода
|
||||
result_data = {
|
||||
'game_id': self.game_id,
|
||||
'score': self.score,
|
||||
'total': total,
|
||||
'percentage': round(percentage, 1),
|
||||
'grade': grade,
|
||||
'message': message,
|
||||
'questions_summary': self.user_answers,
|
||||
'completed_at': self.start_time.isoformat()
|
||||
}
|
||||
saved_results[self.game_id] = result_data
|
||||
|
||||
return {
|
||||
'score': self.score,
|
||||
'total': total,
|
||||
'percentage': round(percentage, 1),
|
||||
'grade': grade,
|
||||
'message': message,
|
||||
'questions_summary': self.user_answers,
|
||||
'result_id': self.game_id # Возвращаем ID для QR-кода
|
||||
}
|
||||
|
||||
|
||||
@app.route('/')
|
||||
def index():
|
||||
return render_template('index.html')
|
||||
|
||||
|
||||
@app.route('/api/new_game', methods=['POST'])
|
||||
def new_game():
|
||||
game = QuizGame()
|
||||
active_games[game.game_id] = game
|
||||
return jsonify({
|
||||
'game_id': game.game_id,
|
||||
'question': game.get_current_question(),
|
||||
'question_number': 1,
|
||||
'total_questions': len(game.selected_questions)
|
||||
})
|
||||
|
||||
|
||||
@app.route('/api/check_answer', methods=['POST'])
|
||||
def check_answer():
|
||||
data = request.json
|
||||
game_id = data.get('game_id')
|
||||
answer = data.get('answer')
|
||||
|
||||
game = active_games.get(game_id)
|
||||
if not game or not game.is_active:
|
||||
return jsonify({'error': 'Игра не найдена'}), 404
|
||||
|
||||
result = game.check_answer(answer)
|
||||
|
||||
if result['is_finished']:
|
||||
# Игра завершена
|
||||
final_result = game.get_result()
|
||||
return jsonify({
|
||||
'is_finished': True,
|
||||
'result': final_result
|
||||
})
|
||||
else:
|
||||
# Следующий вопрос
|
||||
return jsonify({
|
||||
'is_finished': False,
|
||||
'result': result,
|
||||
'next_question': game.get_current_question(),
|
||||
'question_number': game.current_question_index + 1,
|
||||
'total_questions': len(game.selected_questions)
|
||||
})
|
||||
|
||||
|
||||
@app.route('/api/result/<result_id>')
|
||||
def get_result_page(result_id):
|
||||
"""Страница с результатами по QR-коду"""
|
||||
result = saved_results.get(result_id)
|
||||
if not result:
|
||||
return "Результат не найден", 404
|
||||
return render_template('result_page.html', result=result)
|
||||
|
||||
|
||||
@app.route('/api/qrcode/<result_id>')
|
||||
def generate_qrcode(result_id):
|
||||
"""Генерация QR-кода со ссылкой на результат"""
|
||||
result_url = request.host_url.rstrip('/') + f'/api/result/{result_id}'
|
||||
|
||||
# Создаём QR-код
|
||||
qr = qrcode.QRCode(
|
||||
version=1,
|
||||
error_correction=qrcode.constants.ERROR_CORRECT_L,
|
||||
box_size=10,
|
||||
border=4,
|
||||
)
|
||||
qr.add_data(result_url)
|
||||
qr.make(fit=True)
|
||||
|
||||
# Создаём изображение
|
||||
img = qr.make_image(fill_color="black", back_color="white")
|
||||
|
||||
# Сохраняем в байты
|
||||
img_io = BytesIO()
|
||||
img.save(img_io, 'PNG')
|
||||
img_io.seek(0)
|
||||
|
||||
return send_file(img_io, mimetype='image/png')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(debug=True, host='0.0.0.0', port=5000)
|
||||
Reference in New Issue
Block a user