nards/bot/main.py
2024-12-18 00:19:45 +07:00

143 lines
5.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from aiogram import Bot, Dispatcher, types, F
from aiogram.filters import Command
from aiogram.types import WebAppInfo, KeyboardButton, ReplyKeyboardMarkup
from bot.database import Database
import json
import asyncio
from bot.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())