Цикл с перерывом или продолжение на основе пользовательского ввода - PullRequest
0 голосов
/ 22 мая 2019

Я слабо знаю, как использовать цикл. Я использовал простые и понимаю, как это работает. Тем не менее, у меня есть ситуация, когда я думаю, что цикл будет полезен, но я не совсем уверен, как получить желаемый результат. Я самоучка в javascript, и я пробовал осматривать некоторые другие посты, но я не помню, чтобы видел что-то, что помогло в моем случае. Это может быть одним из моих пробелов в понимании.

Что я хотел бы сделать: этот код будет снимать верхнюю карту с колоды карт для TCG. У каждой карты есть «тип». Я хочу, чтобы человек ввел в Discord команду типа "! Flipcard 10". Я бы хотел, чтобы бот делал петлю, чтобы переворачивать карты с верха колоды, пока не достигнет 10, ИЛИ не перевернут определенный тип карт. "Типы" карт, с которыми я работаю, это "action", "evo", "flip" и "hero". Я только хочу, чтобы бот по-разному реагировал на тип карты "Flip". Я получил рабочий код, где я могу сделать это, если пользователь вводит флипкарту!, Но делает это по одному. Максимальное количество карт, которое можно перевернуть, составляет 34 карты или около того, но это происходит реже, чем меньшее число.

Я только что написал код из того, что, как мне кажется, мне нужно сделать, но я застрял, не зная точно, куда идти дальше. Так что это еще не совсем функциональный код. В настоящее время я получаю сообщение об ошибке "недопустимый оператор прерывания", поэтому я не могу прогрессировать намного дальше.

for (i = 0; i < damageToTake; i++) {
cardRemoved = deckAarray.shift()


//Bunch of stuff edited out for Embed mentioned below

    if (cardType == "Flip"){
       message.channel.send(flipEmbed)
       const filter = m => m.author.id === message.author.id
       author.send(`You revealed a Flip card! Do you wish to use it? Please reply with 'yes' or 'no'.`).then((newmsg) => {
       newmsg.channel.awaitMessages(filter, {
       max: 1,
        }).then((collected) => {

            reply = collected.first();

              if (reply.content == 'yes'){
                 console.log("Yes reply.")
                 break;
              } else if (reply.content == 'no'){
                 console.log("No reply")
                 } 
                })
            })
            } else if (cardType != "Flip"){
                message.channel.send(nonflipEmbed)
                continue;
            }
        }
    })
    }

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

Я думаю, что на правильном пути, но я не уверен, как заставить это работать именно так, как я надеюсь.

Итак, чтобы сделать вывод ...

Я хотел бы этот код для следующего:

1) Пользователь вводит команду и указывает, сколько карт перевернуть. 2) Цикл должен перевернуть карты (отображение правильного встраивания в зависимости от типа карты) 3) При обнаружении типа «флип-карты» я бы хотел, чтобы код приостановился, по сути, чтобы спросить автора, хотят ли они использовать флип-карту, которая была раскрыта. Если да, остановите цикл. Если нет, продолжайте цикл с того места, где он остановился, до тех пор, пока не будет перевернуто нужное число ИЛИ, если обнаружится другой тип флип-карты.

Заранее спасибо за помощь!

Ответы [ 2 ]

0 голосов
/ 22 мая 2019

То, что вы пытаетесь сделать, невозможно без модификации кода. Причина этого в том, что циклы for являются синхронными, а обещания - нет. Это означает, что .then() будет достигнуто только после завершения цикла.

Один из способов обойти это - обернуть все внутри асинхронной функции и запустить там свой цикл. Затем используйте предложения try-catch, чтобы выйти из цикла при необходимости. Рассмотрите пример игрушки ниже:

 ( async () => {
    for (i = 0; i < 100; i++) {
        console.log('i:', i);

        try {
            const val = await randomPromise();
            console.log('should resolve and break!');
            console.log(val);
            break;
        } catch (e) {
            console.log('moving on...');
        }
    }
})();


 function randomPromise() {
    return new Promise( (resolve, reject) => {
        const val = Math.random();
        if (val > 0.9) {
            resolve(val);
        } else {
            reject(0);
        }
    })
 }
0 голосов
/ 22 мая 2019

Вы изменили контексты - так как у вас есть две функции, которые ничего не знают о потоке управления друг друга (например: if / then, для циклов, while и т.д.). Они не могут влиять друг на друга так, как вы хотите. То, что вы делаете, является эквивалентом этого псевдокода:

function printAllNumbers() {
  for(currentNumber : allNumbers) {
    printNumber(currentNumber);
  }
}

function printNumber(num) {
    print(num);
    break; // This won't work because it has no clue about for/loop in other func
}

printNumber ограничен, так что он знает только то, что делает его собственная функция (эти две строки). Он не имеет ни малейшего представления о for / each в вызове printAllNumbers, поэтому вы видите ошибку.

И то, что я сказал выше, является лишь частично верным - на самом деле, возможно, в данный момент у вас 2 глубоких функции, потому что вы вызвали .then (), а затем после того, как ваш .newMessage () вызвал другой .then (). Вы читаете код последовательно, но вы должны попытаться посмотреть на него как на ветвящиеся пути следующим образом:

for {
    call async functions and (.then) call these other functions
}
...some time passes
<branched off path> The other functions within .then(functions) get called

Я рекомендую прочитать о том, как работают асинхронные функции, а также о том, как работают обещания, чтобы лучше понять, в каком порядке будет выполняться ваш код.

Чтобы сделать то, что вы хотите, вам нужно написать отдельный код для обработки этих сценариев:

1) Получение количества карточек от пользователя и просто зацикливание и печать этих карточек в чате

2) Получение дальнейших входных данных в зависимости от пользователя (необходимо будет отслеживать пользователя) и текущего состояния их карточек, которые были перевернуты - вероятно, необходимо пронумеровать карточки и попросить их отправить команду, например, USE 1 или ВЫБРАТЬ ВСЕ

Код не будет останавливаться в середине вашего цикла для ожидания ввода, каждый из них должен быть различным фрагментом кода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...