Раздел навигации

DiceBot - играй в кубик с другом

Добро пожаловать!

Зарегистрировавшись у нас, вы сможете обсуждать, делиться и отправлять личные сообщения другим участникам нашего сообщества.

Зарегистрироваться!
  • Если Вы желаете помогать развитию проекта, готовы заполнять раздел(-ы) и подсказывать другим пользователям на портале, есть возможность попасть в команду редакторов. Для этого следует обратиться в техническую поддержку
lua / python developer
Редактор
Регистрация
13 Июн 2022
Сообщения
48
Для работы вам понадобятся библиотеки: Aiogram( >=3.0 ) , asyncio, json, os.
А также, создайте файл "db.json" в папке с данным файлом.


Python:
import asyncio
import os.path
import json

from aiogram import Bot, Dispatcher, F
from aiogram.filters import Command
from aiogram.types import Message, CallbackQuery, FSInputFile, InputMediaPhoto
from aiogram.enums import DiceEmoji
from aiogram.types import (ReplyKeyboardMarkup, KeyboardButton,
                           InlineKeyboardMarkup, InlineKeyboardButton)

token = "" # Сюда токен

bot = Bot(token)
db = Dispatcher()


class cfg: # Класс для работы с JSON

  def write(tab):
    tab = json.dumps(tab)
    tab = json.loads(str(tab))
    with open("db.json", 'w', encoding='utf-8') as file:
      json.dump(tab, file, indent=4, ensure_ascii=False)

  def read():
    with open("db.json", 'r', encoding='utf-8') as file:
      return json.load(file)


data = cfg.read()


class database: # Класс для получения указателей json и записи

  def get_status(): # Получение количества игроков в поиске
    num = 0
    for user_id, user_data in list(data.items()):
      if user_data["game"]["status"] == 1:
        num += 1
    return num

  def set_game_params(chat_id, param, status): # Функция для изменения игровых параметров
    data[chat_id]["game"][param] = status
    cfg.write(data)

  def get_user(chat_id): # Функция для получения курсора на пользователя
    if str(chat_id) not in data: # Если пользователя нет в JSON
      data[str(chat_id)] = {
          "id": chat_id,
          "game": {
              "status": 0, # Статус( 0 - не в поиске, 1 - в поиске, 2 - в игре )
              "value": 0, # Значение на выпавшем кубике
              "rid": "" # Вражеский ID
          } 
      }
      cfg.write(data)
    return data[str(chat_id)]

  def search(chat_id): # Получение игрока в поиске
    for user_id, user_data in list(data.items()):
      if user_data["game"]["status"] == 1 and user_id != chat_id:
        return user_data


class keyboard: # Класс для работы с клавиатурой

  def main(button):
    kb = ReplyKeyboardMarkup(keyboard=[[
        KeyboardButton(text=button),
    ]],
                             resize_keyboard=True)
    return kb

    def game():
        kb = ReplyKeyboardMarkup(
            keyboard=[
                [
                    KeyboardButton(text="🎲")
                ]
                [
                    KeyboardButton(text="🔴 Завершить"),
                ]
            ],
                                 resize_keyboard=True)
        return kb


@db.message(Command("start")) # Обработчик команды /start
async def start(message: Message):
  user = database.get_user(message.from_user.id) # Получаем курсор на пользователя

  await message.reply( # Приветственное сообщение
      "⚙️ Приветствую тебя в игре \"Кубик\"!\n\n"
      f"🔎 Пользователей в поиске: <b>{database.get_status()}</b>",
      reply_markup=keyboard.main("🔎 Начать поиск игры"),
      parse_mode="HTML")


@db.message(F.text == "🔎 Начать поиск игры") # Обработчик кнопки начала поиска игры
async def search(message: Message):
  user = database.get_user(message.from_user.id) # Получаем курсор на пользователя
  chat_id = str(message.from_user.id)

  if user["game"]["status"] == 0:  # Если мы не ищем игру
    database.set_game_params(chat_id, "status", 1) # Меняем статус на "Поиск игры"
    rival = database.search(str(chat_id)) # Ищем соперника

    if rival is None: # Если соперник не найден
      await message.reply(
          f"Игроков в поиске: {database.get_status()}\n"
          "Поиск игрока продолжается...",
          reply_markup=keyboard.main("🔴 Завершить"))
    else: # Если соперник найден
      database.set_game_params(chat_id, "status", 2) # Меняем наш статус на "В игре"
      database.set_game_params(chat_id, "rid", str(rival["id"])) # Записываем вражеский ID для получения курсора.

      database.set_game_params(str(rival["id"]), "status", 2) # Меняем статус соперника на "В игре"
      database.set_game_params(str(rival["id"]), "rid", chat_id) # Записываем наш ID для получения курсора.

      await bot.send_message(rival["id"],
                             "Соперник найден.",
                             reply_markup=keyboard.game())
      await message.reply("Соперник найден!",
                          reply_markup=keyboard.game())
  elif user["game"]["status"] == 1: # Если мы уже находимся в поиске
    return await message.reply("Вы уже находитесь в поиске!")


@db.message(F.text == "🔴 Завершить") # Обработчик кнопки "Завершить". Работает как в поиске, так и в игре
async def stop_game(message: Message):
  user = database.get_user(message.from_user.id) # Получаем курсор на нашего пользователя
  chat_id = str(message.from_user.id)

  if user["game"]["status"] == 1: # Если мы находимся в поиске игры
    await message.reply("Вы отменили поиск игрока!",
                        reply_markup=keyboard.main("🔎 Начать поиск игры"))
    database.set_game_params(chat_id, "status", 0) # Меняем наш статус на "Не в поиске"
    database.set_game_params(chat_id, "rid", "") # Обнуляем вражеский ID

  if user["game"]["status"] == 2: # Если мы находимся в игре
    rival = data[str(user["game"]["rid"])] # Получаем курсор на противника

    if rival["game"]["value"] > 0 and user["game"]["value"] == 0: # Если соперник кинул кубик , а мы нет
      return await message.reply(
          "Вы ещё не кинули кубик. Вы не можете закончить игру!"
      )

    database.set_game_params(chat_id, "status", 0) # Ставим наш статус игры на "Не в поиске"
    database.set_game_params(chat_id, "rid", "")
    await message.reply("Вы вышли из игры!",
                        reply_markup=keyboard.main("🔎 Начать поиск игры"))

    database.set_game_params(str(rival["id"]), "status", 0) # Ставим cтатус игры соперника на "Не в поиске"
    database.set_game_params(str(rival["id"]), "rid", "")

    await bot.send_message(rival["id"],
                           "Игрок покинул игру!",
                           reply_markup=keyboard.main("🔎 Начать поиск игры"))


@db.message(F.dice.emoji == DiceEmoji.DICE) # Обработчик брошенного кубика
async def play_game(message: Message):
  user = database.get_user(message.from_user.id) # Получаем курсор на пользователя
  chat_id = str(message.from_user.id)
  uvalue = message.dice.value # Получаем значение на кубике

  if user["game"]["status"] == 2: # Если мы находимся в игре
    if user["game"]["value"] > 0: # Если мы уже кинули кубик
      return await message.reply("Вы не можете бросить кубик во второй раз!")

    if message.forward_from != None: # Если данное сообщение переслано, а так делать нельзя
        return await message.reply("Данное сообщение переслано, а это значит, что вы полный идиот.")
    
    database.set_game_params(chat_id, "value", uvalue) # Записываем значение с нашего кубика в JSON
    await message.answer("Вы кинули кубик.")

    
    rival = data[str(user["game"]["rid"])] # Получаем курсор на соперника
    await bot.send_message(rival["id"], "Игрок кинул кубик.")
    rvalue = rival["game"]["value"]

    if rvalue > 0: # Если соперник бросил кубик
      if rvalue > uvalue: # Если у соперника значение больше
        result = ["Вы победили!", "Вы проиграли!"][::-1]
      elif rvalue < uvalue: # Меньше
        result = ["Вы победили!", "Вы проиграли!"]
      elif rvalue == uvalue: # Равно
        result = ["Ничья", "Ничья"]

      await message.reply(f"{result[0]} {uvalue} | {rvalue}")
      await bot.send_message(rival["id"], f"{result[1]} {rvalue} | {uvalue}")

      database.set_game_params(chat_id, "value", 0)
      database.set_game_params(str(rival["id"]), "value", 0)


async def main():
  await db.start_polling(bot)


if __name__ == "__main__":
  asyncio.run(main())
 
Сверху