143 lines
5.9 KiB
Python
143 lines
5.9 KiB
Python
from aiogram import Bot, Dispatcher, types, F
|
||
from aiogram.filters import Command
|
||
from aiogram.types import WebAppInfo, KeyboardButton, ReplyKeyboardMarkup
|
||
from database import Database
|
||
import json
|
||
import asyncio
|
||
from config import BOT_TOKEN, WEBAPP_URL
|
||
import logging
|
||
|
||
# Настройка логирования
|
||
logging.basicConfig(
|
||
level=logging.INFO,
|
||
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
|
||
)
|
||
logger = logging.getLogger(__name__)
|
||
|
||
# Инициализация бота и диспетчера
|
||
bot = Bot(token=BOT_TOKEN)
|
||
dp = Dispatcher()
|
||
db = Database()
|
||
|
||
# Упрощенная клавиатура
|
||
def get_main_keyboard():
|
||
keyboard = [
|
||
[
|
||
KeyboardButton(
|
||
text="Записать броски 🎲",
|
||
web_app=WebAppInfo(url=WEBAPP_URL)
|
||
)
|
||
],
|
||
[KeyboardButton(text="Статистика 📊")]
|
||
]
|
||
return ReplyKeyboardMarkup(keyboard=keyboard, resize_keyboard=True)
|
||
|
||
@dp.message(Command("start"))
|
||
async def start_command(message: types.Message):
|
||
logger.info(f"User {message.from_user.id} ({message.from_user.username}) started the bot")
|
||
await message.answer(
|
||
"🎲 Добро пожаловать в счётчик кубиков для нард!\n\n"
|
||
"Нажмите «Записать броски» чтобы начать новую игру.",
|
||
reply_markup=get_main_keyboard()
|
||
)
|
||
|
||
# Обновляем функцию подсчета статистики в handle_webapp_data
|
||
def calculate_throw_sum(throw):
|
||
dice1, dice2 = throw['dice']
|
||
if dice1 == dice2:
|
||
return (dice1 + dice2) * 2
|
||
return dice1 + dice2
|
||
|
||
@dp.message(F.web_app_data)
|
||
async def handle_webapp_data(message: types.Message):
|
||
try:
|
||
user = message.from_user
|
||
logger.info(f"Received webapp data from user {user.id} ({user.username})")
|
||
|
||
data = json.loads(message.web_app_data.data)
|
||
|
||
if data['type'] == 'game_session':
|
||
# Создаем новую игру
|
||
game_id = db.create_game(user.id, user.username)
|
||
logger.info(f"Created new game {game_id} for user {user.id}")
|
||
|
||
# Записываем все броски
|
||
throws = data['throws']
|
||
for throw in throws:
|
||
db.add_throw(
|
||
game_id,
|
||
throw['dice'][0],
|
||
throw['dice'][1]
|
||
)
|
||
|
||
# Завершаем игру
|
||
db.end_game(game_id)
|
||
logger.info(f"Game {game_id} completed with {len(throws)} throws")
|
||
|
||
# Обновляем подсчет статистики
|
||
total_throws = len(throws)
|
||
total_sum = sum(calculate_throw_sum(t) for t in throws)
|
||
avg_sum = total_sum / total_throws if total_throws > 0 else 0
|
||
doubles = sum(1 for t in throws if t['dice'][0] == t['dice'][1])
|
||
|
||
# Находим максимальный и минимальный броски с учетом дублей
|
||
throws_with_sums = [(t, calculate_throw_sum(t)) for t in throws]
|
||
max_throw = max(throws_with_sums, key=lambda x: x[1])
|
||
min_throw = min(throws_with_sums, key=lambda x: x[1])
|
||
|
||
# Формируем сообщение
|
||
response = "🎯 Игра завершена!\n\n"
|
||
response += f"📊 Статистика игры:\n"
|
||
response += f"• Всего бросков: {total_throws}\n"
|
||
response += f"• Общая сумма: {total_sum}\n"
|
||
response += f"• Средняя сумма: {avg_sum:.1f}\n"
|
||
response += f"• Дублей выпало: {doubles}\n"
|
||
response += f"• Максимальный бросок: {max_throw[0]['dice'][0]}-{max_throw[0]['dice'][1]} (сумма: {max_throw[1]})\n"
|
||
response += f"• Минимальный бросок: {min_throw[0]['dice'][0]}-{min_throw[0]['dice'][1]} (сумма: {min_throw[1]})\n\n"
|
||
|
||
# Добавляем последние броски с учетом дублей
|
||
response += "🎲 Последние броски:\n"
|
||
for i, throw in enumerate(throws[:5]):
|
||
sum_value = calculate_throw_sum(throw)
|
||
is_double = throw['dice'][0] == throw['dice'][1]
|
||
response += f"{i+1}. {throw['dice'][0]}-{throw['dice'][1]} {'🎯' if is_double else ''} (сумма: {sum_value})\n"
|
||
|
||
if total_throws > 5:
|
||
response += f"... и ещё {total_throws - 5} бросков"
|
||
|
||
await message.answer(response)
|
||
logger.info(f"Sent game statistics to user {user.id}")
|
||
|
||
except Exception as e:
|
||
logger.error(f"Error handling webapp data: {e}", exc_info=True)
|
||
await message.answer("❌ Произошла ошибка при обработке данных.")
|
||
|
||
@dp.message(Command("statistics"))
|
||
@dp.message(F.text == "Статистика 📊")
|
||
async def statistics_command(message: types.Message):
|
||
user_id = message.from_user.id
|
||
logger.info(f"User {user_id} requested statistics")
|
||
|
||
stats = db.get_statistics(user_id)
|
||
|
||
response = "📊 Общая статистика:\n\n"
|
||
|
||
if stats['total_throws']:
|
||
response += (
|
||
f"• Всего игр: {stats['total_games']}\n"
|
||
f"• Всего бросков: {stats['total_throws']}\n"
|
||
f"• Средняя сумма: {stats['avg_sum']:.1f}\n"
|
||
)
|
||
else:
|
||
response += "У вас пока нет записанных бросков."
|
||
|
||
await message.answer(response)
|
||
logger.info(f"Sent statistics to user {user_id}")
|
||
|
||
# Запуск бота
|
||
async def main():
|
||
logger.info("Starting bot")
|
||
await dp.start_polling(bot)
|
||
|
||
if __name__ == '__main__':
|
||
asyncio.run(main()) |