diff --git a/bot/database.py b/bot/database.py index d3c87ea..0c74371 100644 --- a/bot/database.py +++ b/bot/database.py @@ -32,14 +32,14 @@ class Database: conn.commit() return cursor.lastrowid - def add_throw(self, game_id: int, dice1: int, dice2: int): - """Добавление броска""" + def add_throw(self, game_id: int, dice1: int, dice2: int, unused_points: int = 0): + """Добавление броска с учетом неиспользованных очков""" with self._get_connection() as conn: cursor = conn.cursor() cursor.execute(''' - INSERT INTO throws (game_id, dice1, dice2) - VALUES (?, ?, ?) - ''', (game_id, dice1, dice2)) + INSERT INTO throws (game_id, dice1, dice2, unused_points) + VALUES (?, ?, ?, ?) + ''', (game_id, dice1, dice2, unused_points)) conn.commit() def get_active_game(self, user_id: int): @@ -70,14 +70,22 @@ class Database: conn.commit() def get_statistics(self, user_id: int): - """Получение статистики пользователя""" + """Получение статистики пользователя с учетом неиспользованных очков""" with self._get_connection() as conn: cursor = conn.cursor() stats = cursor.execute(''' SELECT COUNT(*) as total_throws, - AVG(dice1 + dice2) as avg_sum, - COUNT(DISTINCT game_id) as total_games + SUM(CASE + WHEN dice1 = dice2 THEN (dice1 + dice2) * 2 + ELSE dice1 + dice2 + END) as total_base_sum, + SUM(CASE + WHEN dice1 = dice2 THEN (dice1 + dice2) * 2 - unused_points + ELSE dice1 + dice2 - unused_points + END) as total_final_sum, + COUNT(DISTINCT game_id) as total_games, + SUM(unused_points) as total_unused FROM throws t JOIN games g ON t.game_id = g.id WHERE g.user_id = ? @@ -86,11 +94,11 @@ class Database: return dict(stats) def get_game_throws(self, game_id: int): - """Получение всех бросков игры""" + """Получение всех бросков игры с учетом неиспользованных очков""" with self._get_connection() as conn: cursor = conn.cursor() throws = cursor.execute(''' - SELECT dice1, dice2, throw_time + SELECT dice1, dice2, unused_points, throw_time FROM throws WHERE game_id = ? ORDER BY throw_time DESC diff --git a/bot/main.py b/bot/main.py index de8922a..96aa261 100644 --- a/bot/main.py +++ b/bot/main.py @@ -44,9 +44,8 @@ async def start_command(message: types.Message): # Обновляем функцию подсчета статистики в handle_webapp_data def calculate_throw_sum(throw): dice1, dice2 = throw['dice'] - if dice1 == dice2: - return (dice1 + dice2) * 2 - return dice1 + dice2 + base_sum = (dice1 + dice2) * 2 if dice1 == dice2 else dice1 + dice2 + return base_sum - (throw.get('unusedPoints', 0)) @dp.message(F.web_app_data) async def handle_webapp_data(message: types.Message): @@ -67,7 +66,8 @@ async def handle_webapp_data(message: types.Message): db.add_throw( game_id, throw['dice'][0], - throw['dice'][1] + throw['dice'][1], + throw.get('unusedPoints', 0) ) # Завершаем игру @@ -76,32 +76,39 @@ async def handle_webapp_data(message: types.Message): # Обновляем подсчет статистики 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]) + total_base_sum = sum((t['dice'][0] + t['dice'][1]) * 2 if t['dice'][0] == t['dice'][1] else t['dice'][0] + t['dice'][1] for t in throws) + total_final_sum = sum(calculate_throw_sum(t) for t in throws) # Формируем сообщение 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 += f"• Общая сумма: {total_final_sum}" + + if total_base_sum != total_final_sum: + unused_sum = total_base_sum - total_final_sum + response += f" (без минусов: {total_base_sum})\n" + response += f"• Неиспользовано: {unused_sum}\n" + response += f"• Эффективность: {(total_final_sum / total_base_sum * 100):.1f}%\n" + else: + response += "\n" - # Добавляем последние броски с учетом дублей - response += "🎲 Последние броски:\n" + # Добавляем последние броски + response += "\n🎲 Последние броски:\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" - + unused = throw.get('unusedPoints', 0) + base_sum = (throw['dice'][0] + throw['dice'][1]) * 2 if is_double else throw['dice'][0] + throw['dice'][1] + + response += f"{i+1}. {throw['dice'][0]}-{throw['dice'][1]}" + response += f" {'🎯' if is_double else ''}" + if unused > 0: + response += f" = {sum_value} (-{unused})" + else: + response += f" = {sum_value}" + response += "\n" + if total_throws > 5: response += f"... и ещё {total_throws - 5} бросков" @@ -120,14 +127,35 @@ async def statistics_command(message: types.Message): stats = db.get_statistics(user_id) - response = "📊 Общая статистика:\n\n" + response = "📊 Подробная статистика:\n\n" if stats['total_throws']: + total_base_sum = stats['total_base_sum'] or 0 + total_final_sum = stats['total_final_sum'] or 0 + total_unused = stats['total_unused'] or 0 + avg_sum = total_final_sum / stats['total_throws'] + response += ( - f"• Всего игр: {stats['total_games']}\n" + f"🎲 Броски:\n" f"• Всего бросков: {stats['total_throws']}\n" - f"• Средняя сумма: {stats['avg_sum']:.1f}\n" + f"• Количество игр: {stats['total_games']}\n" + f"• Среднее бросков за игру: {stats['total_throws'] / stats['total_games']:.1f}\n\n" + + f"🎯 Очки:\n" + f"• Общая сумма: {total_final_sum}\n" + f"• Сумма без минусов: {total_base_sum}\n" + f"• Средняя сумма за бросок: {avg_sum:.1f}\n" + f"• Эффективность: {(total_final_sum / total_base_sum * 100):.1f}%\n\n" ) + + if total_unused > 0: + avg_unused = total_unused / stats['total_throws'] + response += ( + f"❌ Неиспользованные очки:\n" + f"• Всего неиспользовано: {total_unused}\n" + f"• В среднем за бросок: {avg_unused:.1f}\n" + f"• Процент потерь: {(total_unused / total_base_sum * 100):.1f}%\n" + ) else: response += "У вас пока нет записанных бросков." diff --git a/bot/schema.sql b/bot/schema.sql index 89de875..3c11886 100644 --- a/bot/schema.sql +++ b/bot/schema.sql @@ -12,6 +12,7 @@ CREATE TABLE IF NOT EXISTS throws ( game_id INTEGER, dice1 INTEGER NOT NULL, dice2 INTEGER NOT NULL, + unused_points INTEGER DEFAULT 0, throw_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (game_id) REFERENCES games(id) ); \ No newline at end of file