Beispiel #1
0
def words_skip_move(message):
    c = configparser.ConfigParser()
    chat_id = str(message.chat.id)
    filename = GAME_WORDS_DATA
    c.read(filename, encoding='utf-8')
    if not c.has_section(chat_id):
        msg = "Игра не найдена"
        bot.send_message(chat_id, msg,
            reply_to_message_id=message.message_id)
        return
    section = c[chat_id]
    order = eval(section["order"])
    current = int(section["current"])
    current += 1
    current %= len(order)
    section["current"] = str(current)

    if str(order[current]) == BOT_ID:
        mentioned = eval(section["mentioned"])
        cur_letter = section["letter"]
        letter = cur_letter

        print("Bot's move")  # test

        answer, msg = make_move(chat_id, message, letter, mentioned)

        current = (current + 1) % len(order)

        section["current"] = str(current)
        next_let = answer.lower().rstrip('ьъ')[-1]
        mentioned.append(answer)
        if next_let == 'ё': next_let = 'е'
        section["letter"] = next_let
        section["mentioned"] = str(mentioned)

        bot.send_message(chat_id, msg, reply_to_message_id=message.message_id)
    else:
        msg = "Ход пропущен."
        bot.send_message(chat_id, msg, reply_to_message_id=message.message_id)
    with open(filename, 'w', encoding='utf-8') as f:
        c.write(f)

    print('Performed skip of move.')  # test
Beispiel #2
0
def answer_message(message):
    _add_user(message.from_user.id)

    c = configparser.ConfigParser()
    chat_id = str(message.chat.id)
    filename = GAME_WORDS_DATA
    c.read(filename, encoding='utf-8')
    if not c.has_section(chat_id):
        # Аnswer can be performed only if section exists.
        return
    section = c[chat_id]
    order = eval(section["order"])
    current = int(section["current"])
    if (c.has_option(chat_id, 'status') and
        c.get(chat_id, 'status') == 'paused'):
        return

    if message.chat.type == 'private':
        pattern = '(?i)(!)?[-а-яё]+'
        if (s := re.fullmatch(pattern, message.text)):
            play_words(chat_id, message)
Beispiel #3
0
def react_game_words(message):
    chat = message.chat
    # Processing further actions may take a great amount of time.
    bot.send_chat_action(chat.id, 'typing')
    _add_user(message.from_user.id)

    cmd_pattern = _cmd_pattern('words')
    help_pattern = cmd_pattern \
        + r'\s(?:[-—\s:]*)(?:правила|инструкция|команды|help)\s*\??'

    if re.fullmatch(cmd_pattern + r'.*?\s+[-!]?skip', message.text):
        words_skip_move(message)
        return
    if re.fullmatch(cmd_pattern + r'\s+(?:приостановить|pause)', message.text):
        bot.send_chat_action(chat.id, 'typing')

        c = configparser.ConfigParser()
        chat_id = str(chat.id)
        filename = GAME_WORDS_DATA
        c.read(filename, encoding='utf-8')
        if not c.has_section(chat_id):
           msg = "Игра не найдена."
           bot.send_message(chat_id, msg,
               reply_to_message_id=message.message_id)
           return
        c[chat_id]['status'] = 'paused'
        with open(filename, 'w', encoding='utf-8') as f:
            c.write(f)
        dot = '.' * (random.random() > 1/2)
        msg = f"Игра приостановлена. Продолжение: /words continue{dot}"
        bot.send_message(chat_id, msg,
            reply_to_message_id=message.message_id)

        return
    if re.fullmatch(cmd_pattern + r'\s+(?:хватит|удалить игру|stop)', message.text):
        bot.send_chat_action(chat.id, 'typing')

        c = configparser.ConfigParser()
        chat_id = str(chat.id)
        filename = GAME_WORDS_DATA
        c.read(filename, encoding='utf-8')
        if c.has_section(chat_id):
           c.remove_section(chat_id)
        else:
            msg = "Игра не найдена."
            bot.send_message(chat_id, msg,
                reply_to_message_id=message.message_id)
            return
        with open(filename, 'w', encoding='utf-8') as f:
            c.write(f)
        dot = '.' * (random.random() > 1/2)
        msg = f"Текущая игра убрана{dot}"
        bot.send_message(chat_id, msg,
            reply_to_message_id=message.message_id)
        return
    if re.fullmatch(cmd_pattern + r'\s+(?:очередь|порядок|order)', message.text):
        bot.send_chat_action(chat.id, 'typing')

        c = configparser.ConfigParser()
        chat_id = str(chat.id)
        filename = GAME_WORDS_DATA
        c.read(filename, encoding='utf-8')
        if not c.has_section(chat_id):
            bot.send_message(chat.id,
                "Игра в этом чате не найдена."
                )
            return
        section = c[chat_id]
        order = eval(section["order"])
        current = int(section["current"])
        uid = order[current]
        cuser = bot.get_chat_member(chat_id, uid).user
        order_ = ', '.join(map(full_name,
            (bot.get_chat_member(chat_id, _uid).user for _uid in order)))
        text_mention = user_text_mention(cuser, fill_as=None)
        msg = f"""Последовательность: {order_}
Сейчас ходит: {text_mention}"""
        bot.send_message(chat_id, msg, parse_mode='HTML')
        return
    if re.fullmatch(help_pattern, message.text):
        bot.send_chat_action(chat.id, 'typing')
        msg = """\
Начало игры
`-----------`
В личной переписке: /words `[начать|start]` `[single]` (`single` — игра самому)
В группе: `/words пользователь\_1 ...`
◽️Имена пользователей — упоминанием;
◽️Если своё имя не указывать, оно первое в очереди

Хода
`----`
В личной переписке: `!слово` либо `слово`
В группе: либо `!слово`, либо `слово` в ответ на сообщение того, кто ходил прошлым.

Другие:
`-------`
`/words pause``|``приостановить` — остановка игры
`/words stop``|``хватит|удалить игру` — прекратить игру и удалить
`/words skip` — пропуск хода
`/words order``|``очередь|порядок` — порядок ходов, текущий игрок
`/words help``|``правила|инструкция|команды` — это сообщение
`/words continue``|``продолжить` — продолжение (после `pause`)
"""
        bot.send_message(chat.id, msg, parse_mode='Markdown')
        return

    if re.fullmatch(cmd_pattern + r'\s+(?:продолжить|continue)', message.text):
        bot.send_chat_action(chat.id, 'typing')

        c = configparser.ConfigParser()
        chat_id = str(chat.id)
        filename = GAME_WORDS_DATA
        c.read(filename, encoding='utf-8')
        if (c.has_option(chat_id, 'status') and 
            c[chat_id]['status'] == 'paused'):
            c.set(chat_id, 'status', 'active')
            with open(filename, 'w', encoding='utf-8') as f:
                c.write(f)
            dot = '.' * (random.random() > 1/2)
            msg = f"Игра продолжена{dot}"
            bot.send_message(chat_id, msg,
                reply_to_message_id=message.message_id)

            return

    if chat.type == 'private':
        if 'single' in message.text:
            order = [message.from_user.id]
        else:
            order = [message.from_user.id, eval(BOT_ID)]
        current = 0
        mentioned = []

        c = configparser.ConfigParser()
        chat_id = str(chat.id)
        filename = GAME_WORDS_DATA
        c.read(filename, encoding='utf-8')
        if c.has_section(chat_id):
            if not re.search('(?:начать|start)', message.text):
                msg = "Игра уже есть. Новая игра: /words начать|start. " \
                      "Также см.: /words help."
                bot.send_message(chat_id, msg,
                    reply_to_message_id=message.message_id)
                return  # Do the game being not registered then.
        if not c.has_section(chat_id):
            c.add_section(chat_id)
        section = c[chat_id]
        section["order"] = str(order)
        section["current"] = str(current)
        section["letter"] = ANY_LETTER
        section["mentioned"] = str(mentioned)
        with open(filename, 'w', encoding='utf-8') as f:
            c.write(f)

        print("Registered. chat_id: " + chat_id)
        bot.send_message(chat_id, "Done. Registered.")
    elif 'group' in chat.type:
        def user_id_(e):
            if e.type == 'text_mention':
                return e.user.id
            elif e.type == 'mention':
                users = load_users()
                # +1: Skips `@`
                uname = message.text[e.offset + 1 : e.offset + e.length]
                for user_id in users:
                    if (_user := _chatMember(user_id, of=chat.id).user) \
                        and _user.username == uname:
                        return user_id
                msg = f"Unknown user: @{uname}"
                bot.send_message(chat.id, msg,
                    reply_to_message_id=message.message_id)

        order = [user_id_(e) for e in message.entities[1:]]
        if None in order:
            return
        if (n := message.from_user.id) not in order:
            order = [n] + order
Beispiel #4
0
def play_words(chat_id, message):
    # """Да, тут считают, что е и ё — одна буква."""

    c = configparser.ConfigParser()
    chat_id = str(chat_id)
    filename = GAME_WORDS_DATA
    c.read(filename, encoding='utf-8')
    if not c.has_section(chat_id):
        msg = "Ошибка: не найдено игру."
        bot.send_message(chat_id, msg,
            reply_to_message_id=message.message_id)
        raise NoSectionError
    section = c[chat_id]
    order = eval(section["order"])
    current = int(section["current"])
    cur_letter = section["letter"]
    mentioned = eval(section["mentioned"])
    
    dot = '.' * (random.choice([0, 1, 2]) < 1)

    if (match := re.fullmatch(WORDS_GAME_PATTERN, message.text)) \
    and (n := message.from_user.id) in order:
        if message.chat.type != 'private' and not (
            #                            comment vvvvvvvvv
            re.fullmatch(r"(?s)\!\s?(?:[-\w]+)(?:\s*\(.+\))?", message.text) or
            #                          ^^^^^^ word
            (message.reply_to_message and
            message.reply_to_message.from_user.id == order[current - 1])):
            return
        if n != order[current]:
            answer_msg = f"Не твой сейчас ход{dot}"  # " Ход игрока "
            # user_text_mention(user)!
            bot.send_message(chat_id, answer_msg, 
                reply_to_message_id=message.message_id)
            return  #~
        word = match.group(1)
        print(word)  # test
        if cur_letter != "." and word[0].lower().replace('ё', 'е') != cur_letter:
            answer_msg = f"На букву {cur_letter!r}{dot}"
            bot.send_message(chat_id, answer_msg, 
                reply_to_message_id=message.message_id)
            return
        if requests.get(f"https://loopy.ru/?word={word}&def=").status_code \
            == 404:
            answer_msg = f"Вау. Кажется, я не знаю этого слова. Хотя, \
возможно, оно лежит где-то на полке в папке data, но я не смотрел." \
 + f" Переходи, пожалуйста{dot}" + " Что \
это слово значит? (Ход не засчитан. Потом либо напиши ответом на это \
сообщение толкование слова, я его в словарь запишу, либо назови другое \
слово. И вообще, это not implemented ещё{dot})"*feature_exists('teach_word')
            bot.send_message(chat_id, answer_msg,
                reply_to_message_id=message.message_id)
            return
        if word.casefold() in map(lambda s: s.casefold(), mentioned):
            answer_msg = f"Слово {word!r} уже было в этой игре{dot}"
            bot.send_message(chat_id, answer_msg, 
                reply_to_message_id=message.message_id)
            return
        mentioned.append(word)
        res = word.lower().rstrip('ь')
        assert re.fullmatch("(?i)[-а-яё]+", res)  # really required?
        letter = res[-1]
        section["letter"] = letter
        current = (current + 1) % len(order)
        if str(order[current]) == BOT_ID:
            print("Bot's move at game `words`")  # test-log
            
            try:
                answer, msg = make_move(chat_id, message, letter, mentioned)
            except Exception as e:
                print(e)
                return

            current = (current + 1) % len(order)
            
            mentioned.append(answer)
            
            next_let = answer.lower().rstrip('ьъ')[-1]
            if next_let == 'ё': next_let = 'е'
            section["letter"] = next_let

            bot.send_message(chat_id, msg, reply_to_message_id=message.message_id)

        section["current"] = str(current)
        section["mentioned"] = str(mentioned)

        with open(filename, 'w', encoding='utf-8') as f:
            c.write(f)
Beispiel #5
0
                    if (_user := _chatMember(user_id, of=chat.id).user) \
                        and _user.username == uname:
                        return user_id
                msg = f"Unknown user: @{uname}"
                bot.send_message(chat.id, msg,
                    reply_to_message_id=message.message_id)

        order = [user_id_(e) for e in message.entities[1:]]
        if None in order:
            return
        if (n := message.from_user.id) not in order:
            order = [n] + order
        current = 0
        mentioned = []

        c = configparser.ConfigParser()
        chat_id = str(chat.id)
        filename = GAME_WORDS_DATA
        c.read(filename, encoding='utf-8')
        if not c.has_section(chat_id):
            c.add_section(chat_id)
        section = c[chat_id]
        section["order"] = str(order)
        section["current"] = str(current)
        section["letter"] = ANY_LETTER
        section["mentioned"] = str(mentioned)
        with open(filename, 'w', encoding='utf-8') as f:
            c.write(f)
        
        print("Registered. chat_id: " + chat_id)
        bot.send_message(chat_id, "Done. Registered.")