@Retr0_0

Как реализовать простую игру-вопросник в тг боте на js?

В общем, есть бот, который при команде Играть запускает функцию игры. Игра - простые примеры, на ответ дается 10 секунд. Если пользователь правильно ввел ответ, ему прибавляется одно очко. При нажатии на кнопку закончить - вопросы прекращаются. Пишу на telegraf
import { game, prom } from './game.js'
bot.hears('Играть', ctx => {
    ctx.reply('Через 10 секунд начнутся вопросы. Приготовтесь!', stopGame())
    function send(msg){
       ctx.reply(msg)
    }
    prom(send)
})

bot.hears('Прекратить играть', ctx => {
    ctx.reply('Игра окончена', getMainMenu())
})


game.js:
export function game(call) {
    let operators = ['+', '-']
    let operation = ''
    let result = 0

    function operatorRandom() {
        let operator = operators[Math.floor(Math.random() * operators.length)]
        return operator
    }

    function getRandomInt() {
        return Math.floor(Math.random() * (1000 - 1)) + 1;
    }

    function getOperation() {

        let firstOperand = getRandomInt()
        let secondOperand = getRandomInt()

        if (operatorRandom() === '+') {
            operation = `${firstOperand} + ${secondOperand}`
            result = firstOperand + secondOperand
        } else if (operatorRandom() === '-') {
            operation = `${firstOperand} - ${secondOperand}`
            result = firstOperand - secondOperand
        } else if (operatorRandom() === '/') {
            operation = `${firstOperand} / ${secondOperand}`
            result = firstOperand / secondOperand
        } else if (operatorRandom() === '*') {
            operation = `${firstOperand} * ${secondOperand}`
            result = firstOperand * secondOperand
        }
    }

    getOperation()
    return [operation, result]
}   



export function prom(call){
    return new Promise(function(resolve, reject){
        setInterval(() => {
            call(game()[0])
        }, 10000)
    })
}

Примеры вроде бы отправляются, но в какой-то момент возникает ошибка:

Uncaught TelegramError Error: 400: Bad Request: message text is empty
Process exited with code 1

Что исправить и как правильно реализовать прекращение игры?
  • Вопрос задан
  • 153 просмотра
Решения вопроса 1
szQocks
@szQocks
Проблема в условиях, в том что в каждом условии идёт вызов функции operatorRandom
предположим что в первом условии функция operatorRandom вернет минус, а во втором плюс, тогда выходит что не одно из условий не отрабатывает, и в operation остаётся пустая строка, и дальнейшая ошибка из-за неё

плюс так же вижу жесткую ошибку в будущем, это вызов setTimeout - тут нужен setInterval который бы отслеживал дату начала игры пользователей каждый N миллисекунд, то есть на бэке - должен крутиться игровой цикл бесконечный который бы отслеживал игры и вещал игрокам об их статусах что-то типа setInterval(cb, 50);

по факту для одного юзера - setTimeout будет работать идеально, но юзеров скорее всего же будет не 1, да даже для 10 юзеров, просто эти таймауты будут копиться и всё сломается рано или поздно
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
saboteur_kiev
@saboteur_kiev
software engineer
я пишу бот на баше, там делаю просто.
Храню во внешнем источнике (sql, например), информацию об играх.

Если в текущем чате запущена игра, в sql будет timestamp запуска, chatid , правильный ответ и возможно вопрос, параллельно запущен тред с таймаутом, который завершит игру.

Если игра запущена, все сообщения пользователей проверяются на наличие правильного ответа, и соответственно помечаются.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы