Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.86/21: Рейтинг темы: голосов - 21, средняя оценка - 4.86
0 / 0 / 0
Регистрация: 10.03.2019
Сообщений: 319

Система разговора

27.07.2021, 18:33. Показов 4626. Ответов 27
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте!
Можете сказать(или показать), как можно сделать систему разговора с вопросами?
Смотрите:
есть файл разговора:
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
[name], что делаешь!
    [menu]
    <Ничего>
    Ладно
    <Что-то>
    Понятно
    <Уйди>
    Зачем?
    {end}
Пока!
=
Я так скучала по тебе, [name]!
Спасибо, что вернуля. Мне очень нравится проводить время с тобой
=
[name], ты вернулся!
У тебя был хороший день?
    {menu}
    <Да>
    Я рада, что у тебя всё хорошо
    <Нет>
    Что-то не так?
    Надеюсь, что это не я виновата
    {end}
Ну ладно, чем мы займёмся сегодня?
Структура файла:
  • Диалоги разделяются символом =.
  • Каждая строчка записывается в консоль
  • Если строчка начинается с {menu}, то в консоли будет меню выбора:
    • В <> записывается ответ, после него речь к этому ответу.
    • {end} - конец меню.
Хочу сделать, чтобы оно случайно выбирало диалог, и выводило его в консоль
Например:
Кликните здесь для просмотра всего текста

Code
1
2
3
4
5
6
7
8
9
10
У тебя был хороший день?
    {menu}
    <Да>
    Я рада, что у тебя всё хорошо
    <Нет>
    Что-то не так?
    Надеюсь, что это не я виновата
    {end}
Ну ладно
Чем мы займёмся сегодня?
В консоль выводит:
Code
1
2
У тебя был хороший день?
Выберите ответ, Да или Нет
Если выбираем Да, то пишет
Code
1
Я рада, что у тебя всё хорошо
Если Нет, то пишет
Code
1
2
Что-то не так?
Надеюсь, что это не я виновата
Дальше после меню продолжаем выводить строки:
Code
1
2
Ну ладно
Чем мы займёмся сегодня?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
27.07.2021, 18:33
Ответы с готовыми решениями:

Посчитать стоимость разговора
Здравствуйте. Есть вот такая подзадача: Даны длительность разговора (минуты:секунды) и стоимость одной минуты. Нужно посчитать стоимость...

Набор номера телефона для осуществления разговора через гарнитуру компьютера
Господа, доброго времени суток! Столкнулся с задачей написания программы, основной функцией которой является набор номера телефона для...

Запись с микрофона и динамиков (Запись телефонного разговора)
Доброй ночи! Уважаемые граждане, помогите примером кода для записи в wav файл с микрофона и динамиков - запись телефонного разговора. ...

27
Эксперт JavaЭксперт по электроникеЭксперт .NET
 Аватар для wizard41
3465 / 2785 / 576
Регистрация: 04.09.2018
Сообщений: 8,758
Записей в блоге: 3
31.07.2021, 11:51
Студворк — интернет-сервис помощи студентам
Wolfdp, мощно! ТС месяц тут не увидим, пока он будет разбираться что к чему )
0
0 / 0 / 0
Регистрация: 10.03.2019
Сообщений: 319
31.07.2021, 15:48  [ТС]
Wolfdp, Спасибо большое!
Сейчас проверить не могу, ПК далеко, сейчас пишу с телефона на плохом интернете)
Как проверю, напишу)

Добавлено через 2 часа 7 минут
Я вернулся)
Только что опробовал ваш код, есть несколько вопросов:
1. У меня есть например несколько диалогов(набор фраз), которые должны случайно показыватся. Как в вашем примере, только таких диалогов может быть бесконечность. Как можно сделать,
2. Как можно сделать не так, как у вас:
XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<Dialog xsi:type="Question">
    <Id>1</Id>
    <Text>Как настроение? Готов сегодня выложится на полную?! XD</Text>
    <Answers>
      <Answer>
        <Text>Привет! Да, настроение боевое!</Text>
        <NextDialogId>4</NextDialogId>
      </Answer>
      <Answer>
        <Text>Хай, чесно говоря -- я еще сплю...</Text>
        <NextDialogId>3</NextDialogId>
      </Answer>
    </Answers>
  </Dialog>
А вот так:
XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<?xml version="1.0"?>
<ArrayOfDialog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Dialog>
    <Id>0</Id>
    <Text>Привет, ты сегодня рано!</Text>
    <Text>Как настроение? Готов сегодня выложится на полную?! XD</Text>
    <Answers>
      <Answer>
        <AnswerText>Привет! Да, настроение боевое!</AnswerText>
        <Text>Отлично!</Text>
        <Text>Значит сегодня потрудимся на славу!</Text>
        <NextDialogId>4</NextDialogId>
      </Answer>
      <Answer>
        <AnswerText>Хай, чесно говоря -- я еще сплю...</AnswerText>
        <Text>Взбодрить, нам нужно успеть все закончить к началу мероприятия! Я потом тебя угощу кофем.</Text>
        <NextDialogId>4</NextDialogId>
      </Answer>
    </Answers>
    <Text>Как настроение? Готов сегодня выложится на полную?! XD</Text>
    <Text>Вчера все привезли и разгрузили внизу возле навеса.</Text>
    <Text>Нам нужно принести и раставить столы с стульями, растелить скатерти, раставить вазы с цветами и номерки.</Text>
    <NextDialogId>5</NextDialogId>
  </Dialog>
  <Dialog>
    <Id>5</Id>
    <Text>На тебе стулья и столы, я пока принесу вазы и распределю по ним букеты.</Text>
  </Dialog>
</ArrayOfDialog>
Кликните здесь для просмотра всего текста
Вот что я уже имею(извиняюсь за кривой код, уж по другому не знал, как сделать)
Код чтения файла и разбор его на диалоги находится в readIdleTxt()


Добавлено через 1 час 43 минуты
Я изначально планировал сделать как в RenPy, с переходами на другие диалоги, меньшками и прочим:
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
label greeting_gooday:
    m 1hua "Снова привет, [player]. Как дела?"
    menu:
        m "У тебя сегодня был хороший день?"
        "Да.":
            m "Я очень рада за тебя, [player_abb]."
            m "Это заставляет меня чувствовать себя намного лучше, зная, что ты счастлив[mas_gender_none]."
            m "Я постараюсь изо всех сил, чтобы убедиться, что он останется таким, я обещаю."
        "Нет...":
            m "Ох..."
            m "Ну, не волнуйся, [player_abb]. Я всегда здесь для тебя."
            m "Мы можем весь день говорить о твоих проблемах, если ты захочешь."
            m "Я хочу попробовать сделать твой день лучше, и убедиться, что ты всегда счастлив[mas_gender_none]."
            m "Потому что это то что сделает меня счастливой."
            m "Я буду изо всех сил стараться подбодрить тебя, обещаю."
    return
 
label greeting_visit:
    m 1eua "Вот и ты, [player]."
    m "Приятно, что ты заглянул[mas_gender_none]."
    m 1eka "Ты всегда так[mas_gender_oi] заботлив[mas_gender_iii], [player_abb]!"
    m "Спасибо, что проводишь так много времени со мной~"
    m 2hub "Просто помни, что твоё время со мной никогда не тратится впустую."
    return
Но у меня получилось только то, что на гитхабе(ссылка выше под спойлером)
0
Эксперт .NET
 Аватар для Wolfdp
3790 / 1767 / 371
Регистрация: 15.06.2012
Сообщений: 6,543
Записей в блоге: 3
31.07.2021, 16:42
SAn4Es_2005, вы думаете как это "красиво" засунуть в xml, что малость некоректно. Программа не умеет читать как человек, это глупая железяка исполняющая написанный алгоритм. Чтобы было проще понять -- начните не с того как должно выглядить в xml, а как вам будет проще работать в c#, если бы нужно было прям в коде тупо создать Dialog и Question. Вообще для прочтения обязательно.

Как я уже говорил выше -- это простой пример, я намерено не усложнял его, ибо тогда я бы писал его не час, а весь день (чего очень не хочется делать). Для того чтобы вам получить набор случайных диалогов (не путать с Dialog, с неймингом я явно промахнулся, нужно было назвать Phrase или что-то в этом духе), просто сохраняйте не один ArrayOfDialog, а несколько. Более правильно -- обьявите свой класс, скажем MiniScene, который и будет содержать в себе диалоги
C#
1
2
3
4
5
6
7
8
9
10
namespace Nya.CyberForum.ExampleVN.Models
{
    [Serializable]
    public class MimiScene
    {
        [XmlIgnore]
        public Dialog StartDialog { get; set; }
        public Dialog[] Dialogs { get; set; }
    }
}
Вычитка обзеведеться дополнительным циклом (работоспособность кода не проверял)
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
        public void ReadFile(string path)
        {
            scene = new Scene();
 
            var formatter = new XmlSerializer(typeof(MiniScene[]), new[] { typeof(Question), typeof(Dialog) }); // добавляем сериализатор
            using var file = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read); //открываем файл на чтение
            scenes = (IEnumerable<MiniScene>)formatter.Deserialize(file); //считываем
           //не забываем поменять private Scene scene; на private Sceneхъ scenes;
 
           foreach (var scene in scenes)
           {
                var dialogs = scene.Dialogs;
                scene.StartDialog = dialogs.First(); //проставляем точку входа
                var allDialogs = dialogs.Concat(new[] { new End() }).ToArray();
 
                foreach (var dialog in dialogs) //проходим в цикле и по номерам проставляем зависимости
                {
                    if (dialog is Question)
                    {
                        var question = (Question)dialog;
                        foreach (var answer in question.Answers)
                        {
                            answer.NextDialog = scene.AllDialogs.First(x => x.Id == answer.NextDialogId);
                        }
                    }
                    else
                    {
                        dialog.NextDialog = scene.AllDialogs.First(x => x.Id == dialog.NextDialogId);
                    }
                }
           }
        }
вызов всей это красоты можно зарандомить как-то так
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
        public void Play()
        {
while (running)
{
var scene = scenes.OrderBy(x => Guid.NewGuid()).First();
            var dialog = scene.StartDialog;
            while (!(dialog is End)) //просто в цикле проходим каждый диалог
            {
                ProcessDialog(dialog);
                dialog = dialog.NextDialog;
            }
            //_dialogHandler.ExecuteEnd((End)dialog); // можно либо убрать, либо нужно переделать обработку
}
        }
0
0 / 0 / 0
Регистрация: 10.03.2019
Сообщений: 319
31.07.2021, 22:55  [ТС]
Цитата Сообщение от Wolfdp Посмотреть сообщение
засунуть в xml
Ну... не обязательно XML, мне просто посоветовали использовать его, если для этой задачи есть другой способ, не против посмотреть на него)
0
Эксперт .NET
 Аватар для Wolfdp
3790 / 1767 / 371
Регистрация: 15.06.2012
Сообщений: 6,543
Записей в блоге: 3
01.08.2021, 01:42
SAn4Es_2005, давайте я упрощу жизнь вам и себе:
-- сначала учатся программировать
-- потом пробуют реализовывать всякие проекты на подобие тех же визуальных новел

Изменение этой последовательности приводит к постоянным вопросам в попытках реализации своего задума. Я уже указал путь: (де)сериализация в xml или json, материала в сети по этим подходам предостаточно. При достаточном умении нажимать лапками по кнопкам и ясно поставленной цели, можно даже придумать свой формат, чтобы можно было графоманить диалоги без лишних проблем с тегами xml или полями json.

Если вам хочется повторить формат Ren'Py, то придется либо разбирать их код и переносить в свой проект, либо же все это закладывать и реализовывать самостоятельно. По сути это некий недо-скриптовый-язык, где объявлены свои правила наименования, форматирования, следования команд, операторы и прочее. Такое пишется не один день, и не после просмотра видео курса на том же metanit.
0
0 / 0 / 0
Регистрация: 10.03.2019
Сообщений: 319
01.08.2021, 14:04  [ТС]
Всё, сделал всё попроще:
Имеем XML:
XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<Dialogs>
  <Dialog>
    <Id>0</Id>
    <Text>Какая игра твоя любимая?</Text>
    <Text>Моя — «Doki Doki Literature Club»!</Text>
    <Text>А-ха-ха! Просто шутка</Text>
    <Text>Мне просто нравилось говорить это по какой-то причине</Text>
    <text>Но если ты скажешь мне, что какая-то другая романтическая игра лучше, то я буду ревновать~</text>
  </Dialog>
  <Dialog>
    <Text>Как настроение? Готов сегодня выложится на полную?! XD</Text>
    <Menu>
      <Answer text="Привет! Да, настроение боевое!">
        <Text>Отлично!</Text>
        <Text>Значит сегодня потрудимся на славу!</Text>
        <Text>Вчера все привезли и разгрузили внизу возле навеса.</Text>
        <Text>Нам нужно принести и раставить столы с стульями, растелить скатерти, раставить вазы с цветами и номерки.</Text>
      </Answer>
      <Answer text="Хай, чесно говоря -- я еще сплю...">
        <Text>Взбодриcь, нам нужно успеть все закончить к началу мероприятия! Я потом тебя угощу кофем.</Text>
        <Text>Вчера все привезли и разгрузили внизу возле навеса.</Text>
        <Text>Нам нужно принести и раставить столы с стульями, растелить скатерти, раставить вазы с цветами и номерки.</Text>
      </Answer>
    </Menu>
  </Dialog>
  <Dialog>
    <Text>Привет! как себя чуствуешь?</Text>
    <Menu>
      <Answer text="Хорошо">
        <Text>Я рада, что у тебя всё хорошо</Text>
      </Answer>
      <Answer text="Плохо">
        <Text>Что-то не так?</Text>
        <Text>Надеюсь, что это не я виновата</Text>
      </Answer>
    </Menu>
    <Text>Ну ладно, чем мы займёмся сегодня?</Text>
  </Dialog>
</Dialogs>
Создал модель фразы:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
    public class Expression
    {
        public String Text { get; set; }
        public String Face { get; set; }
 
        public Expression(string text, string face)
        {
            if (string.IsNullOrWhiteSpace(face))
            {
                face = "a";
            }
 
            this.Text = text;
            this.Face = face;
        }
        public Expression(string text)
        {
            this.Text = text;
            this.Face = "a";
        }
 
    }
Код меню и "говорения":
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
        public async Task Say(Expression[] expression)
        {
            isSpeaking = true;
 
            playerName = Environment.UserName;
 
            foreach (Expression ex in expression)
            {
                string newText = ex.Text.Replace("[player]", playerName).Replace("{PlayerName}", playerName); //замена
                                                                                                              //Console.WriteLine(newText, true);
                Console.WriteLine(newText);
            }
 
        }
        public void Menu(string question, string[] q, Expression[][] a)
        {
            Console.WriteLine(question);
            for(int i = 0; i < q.Length; i++)
            {
                Console.WriteLine("[" + i +"] - " + q[i]);
            }
            int num = int.Parse(Console.ReadLine());
            _ = Say(a[num]);
 
        }
Основной код считывания и вывода:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
            XmlDocument xDoc = new XmlDocument();
            string path = AppDomain.CurrentDomain.BaseDirectory + "/test.xml";
            xDoc.Load(path);
            // получим корневой элемент
            XmlElement xRoot = xDoc.DocumentElement;
            // обход всех узлов в корневом элементе
            foreach (XmlNode xnode in xRoot)
            {
                if(xnode.Name == "Dialog")
                {
                    Console.WriteLine("Dialog:");
                }
                foreach (XmlNode childnode in xnode.ChildNodes)
                {
                    switch(childnode.Name)
                    {
                        case "Menu":
                            string[] q = new string[childnode.ChildNodes.Count];
                            Expression[][] ex = new Expression[childnode.ChildNodes.Count][];
                            for (int i = 0; i < childnode.ChildNodes.Count; i++)
                            {
                                XmlNode attr = childnode.ChildNodes[i].Attributes.GetNamedItem("text");
                                q[i] = attr.Value;
                                    Expression[] ex1 = new Expression[childnode.ChildNodes[i].ChildNodes.Count];
                                for (int a = 0; a < childnode.ChildNodes[i].ChildNodes.Count; a++)
                                {
                                    ex1[a] = new Expression(childnode.ChildNodes[i].ChildNodes[a].InnerText, "a");
                                }
                                ex[i] = ex1;
                            }
                            Menu("Вопрос: ", q, ex);
                                break;
                        case "Text":
                            Console.WriteLine(childnode.InnerText);
                            break;
                    }
                }
                Console.WriteLine();
            }
            Console.Read();
Кликните здесь для просмотра всего текста
Моё творение)
0
Эксперт JavaЭксперт по электроникеЭксперт .NET
 Аватар для wizard41
3465 / 2785 / 576
Регистрация: 04.09.2018
Сообщений: 8,758
Записей в блоге: 3
01.08.2021, 14:07
SAn4Es_2005, супер!
0
Эксперт .NET
 Аватар для Wolfdp
3790 / 1767 / 371
Регистрация: 15.06.2012
Сообщений: 6,543
Записей в блоге: 3
01.08.2021, 16:14
Цитата Сообщение от SAn4Es_2005 Посмотреть сообщение
C#
1
switch(childnode.Name)
ужс... Хотя, если структура xml в дальнейшем менятся не будет, можно наговнокодить так и забить. Просто приймите к сведению, что если вы "сдвинете" уровень вложености, то потом разгревать вот такие участки будет очень больно.
C#
1
childnode.ChildNodes[i].ChildNodes.Count
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
01.08.2021, 16:14

Вычисление стоимости разговора
напишите программу стоимости телефонного разговора. Известно что тариф днём, вечером и на выходных разные. Пользователь выбирает время...

Подсчитать стоимость телефонного разговора
Пользователь вводит с клавиатуры время начала и время завершения телефонного разговора (часы, минуты и секунды). Подсчитать стоимость...

Разработать класс с методом вычисления стоимости разговора по телефону
Разработать собственный класс, содержащий метод для вычисления стоимости разговора по телефону. Параметрами метода являются: название, код...

Написать программу, определяющую стоимость разговора заданной продолжительности t
Стоимость минуты разговора по телефону — K руб. Если продолжи- тельность разговора превышает 10 минут, то на оставшуюся часть времени...

Структура-пара. Расчитать стоимость разговора, зная тарификацию
Здраствуйте!помогите!!Поле first - целое число, длительность телефонного разговора в минутах; поле second - дробное положительное число,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
28
Ответ Создать тему
Новые блоги и статьи
Генератор паролей (вариант №1)
Maks 29.10.2026
Реализация из решения ниже выполнена исключительно по моей инициативе. Самым главным критерием для меня было создание паролей, в котором отсутствуют знаки: | 1 l I Обработка содержит следующие. . .
Установка ChatGPT (Codex) на Windows без использования Microsoft Store
Fabien159 28.10.2026
Здравствуйте всем читающим! Опишу процесс установки ChatGPT (Codex) на Windows, если по каким-то причинам у вас не получается устанавить его через Microsoft Store. И так: 1. Скачиваем с. . .
Программное добавление префикса в нумерацию документов
Maks 27.10.2026
Реализация из решения ниже выполнена в самописной конфигурации на БСП (помощь начинающему коллеге). Задача: Программно добавить префикс в нумерацию документов. Решение: В модуле объекта. . .
После закрытия оутлука продолжает висеть процесс в диспетчере задач
Maks 27.10.2026
С недавнего времени в продакшене возникла проблема: при закрытии оутлука в диспетчере задач продолжал висеть процесс outlook. exe. Проблема возникла после установки MS Office 2021 LTSC на машинах, под. . .
Baragoz - DPS/HPS бот для WoW 3.3.5a, многоязычный
AmbA 26.10.2026
Хотите ещё ботов? У меня есть один! А я пока отдохну от него. https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=12062&stc=1&d=1793007952 Инструкция внутри. https:/ / youtu. be/ VpfFZSUDGnQ. . .
Особенности gif сгенерированных в Си
russiannick 21.10.2026
Рассмотрим генерацию gif файлов, которые в Си имеют свои особенности. Gif представляет собой графический формат популярный в интернете. Посмотрим на палитру. Gif файл сгенерированный в си отличается. . .
FPS контроллер с анимированными Y-Bot и 3D-звуком miniaudio (Box3D, Recast, BehaviorTree.CPP, ozz-animation, ImGui, OpenGL и SDL3)
8Observer8 18.10.2026
Содержание блога | English Version Полное мультиплатформенное руководство по стартовому проекту с FPS-контроллером игрока, анимированными роботами Y-Bot с 4-слойным блендингом, 3D-физикой Box3D,. . .
Локальный http сервер
Argus19 17.10.2026
Локальный http сервер На работе, на двух локальных компьютерах круглосуточно работают программы опроса приборов с записью в книги Excel,которые раз в сутки записываются на сервер компании. Т. к. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru