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

GuessNumberBot - угадай число соперника

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

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

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

Не забудьте заполнить переменную token в коде.

Логика игры:
1. Поиск игры начинается после нажатия на кнопку "Найти игру".
2. При нахождении игрока , игра рандомно выбирает ведущего.
3. Ведущий должен написать число от 1 до 10, а не ведущий - отгадать это число.
4. Завершить игру или поиск можно на кнопку "Завершить", она появляется после начала поиска.



Python:
import asyncio
import json
import random

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


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

bot = Bot(token)
db = Dispatcher()


class js: # Класс для работы с 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 = js.read()

class database: # Класс для работы с базой данных
    def get_user_cursor(from_id): # Функция для получения курсора на игрока из БД
        result = False
        if from_id not in data:
            data[from_id] = {
                "status": 0,
                "game": {
                    "role": 0,
                    "number": -1,
                    "rid": ""
                }
            }
            js.write(data)
            result = True
        return data[from_id], result

    def set_status(from_id, status): # Смена статуса игрока( 1 - в поиске, 2 - в игре )
        data[from_id]["status"] = status
        js.write(data)

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

    def search_user(from_id): # Функция для поиска игрока
        for user_id, user_data in list(data.items()):
            if str(user_id) != from_id:
                if user_data["status"] == 1:
                    return {
                        "id": str(user_id),
                        "data": user_data
                    }
        return None

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


class keyboard: # Класс для работы с клавиатурой
    def main():
        kb = ReplyKeyboardMarkup(
            keyboard = [
                [
                    KeyboardButton(text="🔎 Найти игру")
                ]
            ],
            resize_keyboard = True
        )
        return kb

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

@db.message(Command("start")) # Обработчик команды /start
async def start_message(message: Message):
    user, is_register = database.get_user_cursor(str(message.from_user.id)) # Получаем курсор на игрока

    if is_register: # Если игрок не был зарегистрирован в боте
        await message.answer(
            "Добро пожаловать в игру \"Угадай число\"",
            reply_markup = keyboard.main()
        )


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

    if user["status"] == 0: # Если игрок не в игре и не в поиске
        database.set_status(chat_id, 1) # Меняем статус на "В поиске"
        rival = database.search_user(chat_id) # Делаем быстрый поиск игрока

        if rival is None: # Если игрок не был найден сразу
            await message.answer(
                "Вы начали поиск игрока\n"
                f"Игроков в поиске: {database.get_users_num()}",
                reply_markup = keyboard.finish()
            )
        else: # Если игрок сразу найден
            database.set_status(chat_id, 2) # Меняем наш статус на "В игре"
            database.set_status(rival["id"], 2) # Меняем статус соперника на "В игре"

            database.set_game_params(chat_id, "rid", rival["id"]) # Обмениваемся айдишниками
            database.set_game_params(rival["id"], "rid", chat_id)

            rand = random.randint(0,1) # Рандом для определения ведущего

            if rand == 0: # Если мы ведущие
                database.set_game_params(chat_id, "role", 1) # Меняем нашу роль на 1(ведущий)
                await message.answer(
                    f"Вы являетесь ведущим!\n"
                    "Загадывайте число от 1 до 10",
                    reply_markup = keyboard.finish()
                )

                await bot.send_message(rival["id"], "Вы не являетесь ведущим!\nЖдите пока игрок загадает число!", reply_markup = keyboard.finish())
            else: # Если ведущий - соперник
                database.set_game_params(rival["id"], "role", 1) # Меняем роль соперника на 1(ведущий)
                await bot.send_message(rival["id"],
                    f"Вы являетесь ведущим!\n"
                    "Загадывайте число от 1 до 10",
                    reply_markup = keyboard.finish()
                )

                await message.answer("Вы не являетесь ведущим!\nЖдите пока игрок загадает число!", reply_markup = keyboard.finish())
    elif user["status"] == 1: # Если мы уже в поиске
        return await message.answer("Вы уже в поиске!")


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

    if user["status"] == 1: # Если мы в поиск, просто завершаем поиск
        database.set_status(chat_id, 0) # Меняем наш статус на "Не в поиске и не в игре"
        await message.answer("Вы вышли из поиска!", reply_markup = keyboard.main())
    elif user["status"] == 2: # Если мы в игре
        await message.answer("Вы вышли из игры!", reply_markup = keyboard.main())
        database.set_status(chat_id, 0) # Меняем наш статус на "Не в поиске и не в игре"
        database.set_game_params(chat_id, "number", -1) # Меняем загаданное игровое число на -1(не загаданно)
        database.set_game_params(chat_id, "role", 0) # Меняем роль на 0(игрок)

        await bot.send_message(user["game"]["rid"], "Игрок покинул игру!", reply_markup = keyboard.main())
        database.set_status(user["game"]["rid"], 0) # Меняем статус соперника на "Не в поиске и не в игре"
        database.set_game_params(user["game"]["rid"], "number", -1) # Меняем загаданное игровое число на -1(не загаданно)
        database.set_game_params(user["game"]["rid"], "role", 0) # Меняем роль на 0(игрок)

        database.set_game_params(user["game"]["rid"], "rid", "")
        database.set_game_params(chat_id, "rid", "")
    elif user["status"] == 0:
        await message.answer("Возвращаю...", reply_markup = keyboard.main())


@db.message() # Обработка всех сообщений
async def handler_message(message: Message):
    chat_id = str(message.from_user.id)
    user = database.get_user_cursor(chat_id)

    if user["status"] == 2: # Если мы в игре
        if user["game"]["role"] == 1: # Если наша роль - Ведущий
            if user["game"]["number"] == -1: # Если мы не загадали число
                if message.text.isdigit(): # Если наш текст - число
                    if int(message.text) >= 0 and int(message.text) <= 10: # Если число в диапазоне от 1 до 10
                        database.set_game_params(chat_id, "number", int(message.text)) # Меняем загаданное число на введенное

                        await message.answer(
                            f"Вы загадали число: {message.text}"
                        )

                        await bot.send_message(user["game"]["rid"], "Игрок загадал число! Угадывайте.")
                    else: # Если число не в диапазоне 1-10
                        await message.answer(
                            "Можно загадать число только от 1 до 10!"
                        )
            else: # Если мы уже загадали число
                await message.answer("Вы уже загадали число!")
        else: # Если наша роль - Игрок
            if message.text.isdigit(): # ПЕсли наш текст - число
                number = int(message.text)
                rival = database.get_user_cursor(user["game"]["rid"]) # Получаем курсор на соперника(он - ведущий)

                if number == rival["game"]["number"]: # Если введенное нами число = загаданному числу соперником
                    await message.answer(
                        "Вы отгадали число!\nТеперь вы являетесь ведущим!\nЗагадывайте число"
                    )

                    await bot.send_message(user["game"]["rid"], "Игрок отгадал число! Теперь вы не являетесь ведущим! Ожидайте, пока игрок загадает число!")

                    database.set_game_params(chat_id, "role", 1) # Меняем нашу роль на - ведущий
                    database.set_game_params(user["game"]["rid"], "role", 0) # Меняем роль соперника на - игрок
                    database.set_game_params(user["game"]["rid"], "number", -1) # Меняем загаданное число на -1( не загаданно )
                else: # Если мы не отгадали число
                    await message.answer(
                        "Вы не отгадали число!"
                    )


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


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