Я пытаюсь написать Discord-бота на JavaScript и столкнулся с проблемой

#javascript #multidimensional-array #fatal-error

#javascript #многомерный массив #фатальная ошибка

Вопрос:

Я пытаюсь написать Discord-бота на JavaScript и столкнулся с проблемой, окно CMD вылетает на рабочий стол, когда доходит до кода в инструкции: «if (styles.includes(cmd2))», кто-нибудь знает, в чем может быть проблема?

Пользователь должен ввести «!рекомендовать», за которым следует либо «фильм», «игра», либо «шоу». В настоящее время это работает нормально.

Сейчас я пытаюсь добавить случай, когда пользователь может ввести «!рекомендовать», за которым следует жанр или стиль, такой как «научная фантастика». Бот должен выполнить поиск в 2D-массиве «фильмы» для любых фильмов, в списке жанров которых есть «научная фантастика». Это не работает.

У меня есть подозрение, что проблема вызвана утверждением «if (movies[i].includes(cmd2))», однако это скорее ощущение, чем основано на каких-либо реальных логических рассуждениях. Строка «genreMovies [i] [y].push(movies[i] [y]);» также может быть источником проблемы. Любая помощь была бы высоко оценена! Спасибо, что нашли время прочитать это!

Код, показанный ниже:

 var Discord = require('discord.io');
var logger = require('winston');
var auth = require('./auth.json');

// Configure logger settings
logger.remove(logger.transports.Console);
logger.add(new logger.transports.Console, {
    colorize: true
});
logger.level = 'debug';
// Initialize Discord Bot
var bot = new Discord.Client({
   token: auth.token,
   autorun: true
});
bot.on('ready', function (evt) {
    logger.info('Connected');
    logger.info('Logged in as: ');
    logger.info(bot.username   ' - ('   bot.id   ')');
});
bot.on('message', function (user, userID, channelID, message, evt) {
    // Our bot needs to know if it will execute a command
    // It will listen for messages that will start with `!`
    if (message.substring(0, 1) == '!') {
        var args = message.substring(1).split(' ');
        var cmd = args[0];
        var cmd2 = args[1];
        var styles = [
        'cyberpunk',
        'dystopia',
        'noir',
        'thriller',
        'sci-fi',
        'post-apocalyptic',
        'action',
        'adventure',
        'romantic',
        'drama',
        'crime',
        'horror',
        'slasher',
        'dark-comedy',
        'mystery',
        'superhero',
        'animated',
        'comedy',
        'historical',
        'fantasy'
        ];
        var gameTypes = [
        'point-and-click',
        'RPG',
        'shooter',
        'stealth',
        'open-world',
        'hack-and-slash'
        ]
        var movies = [
        ['Blade Runner (1982)', 15, '1h 57m', 'cyberpunk, dystopia, noir' , 'film with a brilliant aesthetic and a great cyberpunk noir tale to tell.'],
        ['Blade Runner 2049 (2017)', 15, '2h 44m', 'Cyberpunk, Dystopia, Thriller' , 'visually stunning movie set in a cyberpunk world that explores issues surrounding humanity.'],
        ['Ex Machina (2014)', 15, '1h 48m', 'Sci-Fi, Thriller, Drama, Romance' , 'movie about AI and the issues relating to it with some philisophical questions.']
        ];
        var games = [
        ['Blade Runner (1997)', 16, '8h 30m', 'point-and-click adventure game that captures the films aesthetic brilliantly and has an intruiging plot.'],
        ['Borderlands 2 (2012)', 18, '22h 30m', 'very entertaining comedic first person shooter with a cartoony art style.'],
        ['Deus Ex (2000)', 16, '23h', 'first-person immersive-sim and RPG that delves deep into government conspiracies and capitalistic private agencies.']
        ];
        var tvShows = [
        ['Altered Carbon (2018-2020)', 18, 2, 18, '56m', "thrilling cyberpunk crime drama set in a world where people's personalities are saved in a 'stack' that can be recovered after death."],
        ['Ripper Street (2012-2016)', 15, 5, 37, '1h 7m', 'character focused period drama set in the victorian era following Edmund Reid and his colleagues Sergeant Drake and Homer Jackson.'],
        ['Banshee (2013-2016)', 18, 4, 38, '1h', 'dramatic crime thriller about a criminal who poses as a sheriff in a small southern town with complex characters and emotional payoffs.']
        ];
       
        args = args.splice(1);
        switch(cmd) {
            // !recommend
            case 'recommend':
                switch(cmd2) {
                    // !recommend movie
                    case 'movie':
                        var randInt = getRndInteger(0,3);
                        bot.sendMessage({
                            to: channelID,
                            message: 'You should try '   movies[randInt][0]   '. The movie is rated BBFC '   movies[randInt][1]   ' and is '   movies[randInt][2]   ' long. Genres: '   movies[randInt][3]   '. It is a '   movies[randInt][4]
                        });
                    break;
                    // !recommend game
                    case 'game':
                        var randInt = getRndInteger(0,3);
                        bot.sendMessage({
                            to: channelID,
                            message: 'You should try '   games[randInt][0]   '. The game is rated PEGI '   games[randInt][1]   ' and is '   games[randInt][2]   ' long. It is a '   games[randInt][3]
                        });
                    break;
                    // !recommend TV show
                    case 'show':
                        var randInt = getRndInteger(0,3);
                        bot.sendMessage({
                            to: channelID,
                            message: 'You should try '   tvShows[randInt][0]   '. The show is rated BBFC '   tvShows[randInt][1]   ' and has '   tvShows[randInt][2]   ' seasons with '   tvShows[randInt][3]   ' episodes. Each episode is around '   tvShows[randInt][4]   ' long. It is a '   tvShows[randInt][5]
                        });
                    break;
                }
                if (styles.includes(cmd2)){
                    var i;
                    for (i = 0; i <= movies.length; i  ){
                        if (movies[i].includes(cmd2)) {
                            var max = 0;
                            max  ;
                            var genreMovies = [];
                            var y;
                            for (y = 0; y <= 4; y  ) {
                                genreMovies[i][y].push(movies[i][y]);
                            }
                        }
                    }
                    var randInt = getRndInteger(0,max);
                    bot.sendMessage({
                        to: channelID,
                        message: 'You should try '   genreMovies[randInt][0]   '. The movie is rated BBFC '   genreMovies[randInt][1]   ' and is '   genreMovies[randInt][2]   ' long. Genres: '   genreMovies[randInt][3]   '. It is a '   genreMovies[randInt][4]
                    });
                }
            break;
            case 'help':
                bot.sendMessage({
                    to: channelID,
                    message: "__**List of Commands:**__ n Use *!recommend [mediaType]* e.g. '!recommend movie' and you will get a movie recommendation! n Use *!recommend [genre] [mediaType]* e.g. '!recommend noir movie' and you will get a movie recommendation from that genre! n There are also a number of *hidden commands*! n And as you well know, you can use *!help* to view the command list! n n __**List of Media Types:**__ n movie e.g. '!recommend movie' n game e.g. '!recommend game' n show e.g. '!recommend show'"
                });
            break;
        }
     }
});

function getRndInteger(min, max) {
  return Math.floor(Math.random() * (max - min) )   min;
}
  

Комментарии:

1. genremovies[i][y] кажется неопределенным. я думаю, вы просто хотите genremovies.push(...)

Ответ №1:

movies[i].includes(cmd2) ведет себя не так, как вы ожидаете. Давайте разберем это:

movies[i] содержит данные об одном фильме, например: ['Blade Runner (1982)', 15, '1h 57m', 'cyberpunk, dystopia, noir' , 'film with a brilliant aesthetic and a great cyberpunk noir tale to tell.']

Данные, относящиеся к жанру четвертого элемента массива — 'cyberpunk, dystopia, noir' .

Метод array array.includes(value) возвращает true, если в массиве есть значение, подобное указанному, поэтому, если пользователь вводит !recommend cyberpunk , значение будет cyberpunk . 'cyberpunk' !== 'cyberpunk, dystopia, noir' .

Я бы рекомендовал структурировать данные фильма как объект, что-то вроде:

 {
  name: 'Blade Runner',
  year: 1982,
  genres: ['cyberpunk', 'dystopia', 'noir']
  ...
}
  

Тогда вы можете сделать movies[i].genres.includes(cmd2) .

Затем код выдает ошибку в строке, genreMovies[i][y].push(movies[i][y]) потому что вы определили genreMovies как пустой массив, и вы пытаетесь получить доступ к некоторым, genreMoves[i][y] которые не определены.