Skip to content
Permalink
 
 
Cannot retrieve contributors at this time
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
public static class Scenario
{
public static List<step_info> steps = new List<step_info>();
public static List<List<KeyValuePair<string, int>>> steps_for_fastForward = new List<List<KeyValuePair<string, int>>>();
public struct step_info
{
public step_type step_type;
public string str_param1;
public int int_param1;
public int int_param2;
public float float_param1;
public float float_param2;
public float float_param3;
public float float_param4;
}
public enum step_type
{
dialog,
dialog_continue,
dialog_show,
dialog_hide,
dialog_important,
dialog_important_continue,
dialog_important_hide,
setScript,
tutorialArrow_Show,
tutorialArrow_Hide,
tutorialRedPanel_Show,
tutorialRedPanel_Hide,
check_Requirement,
level_complete_show,
//level_complete_hide,
script_controls_show,
script_controls_hide,
pause,
resume,
skip_bot_rebase_anim,
set_blocked_instructions,
activate_object,
wait,
play_sound,
restore_music_volume
}
// static string[] build_in_types = {"int", "long", "float", "double", "decimal", "bool", "string", "char"};
// static Regex class_and_method = new Regex(@"([A-Za-z\.]+)\s?\(.*\)", RegexOptions.Compiled); //Group 1 = all chain namespace.class.method
// static Regex quotes = new Regex("\".*?\"", RegexOptions.Compiled);
static string template_001_006b = @"
//01. Число A является положительным а число B является отрицательным
//02. A < B < C
//03. Число A находится между числами B и C
//04. Каждое из чисел A, B, C положительное
//05. Хотя бы одно из чисел A, B, C положительное
//06. Ровно два из чисел A, B, C являются положительными
//07. A является двузначным
//08. Среди трех данных целых чисел есть хотя бы одна пара совпадающих
//09. Точка с координатами (a, b) лежит в правой нижней координатной четверти
//10. Точка с координатами (a, b) лежит в левой верхней или правой нижней координатной четверти
";
static string template_001_006b2 = @"
//01. Число A является положительным а число B является отрицательным
for (int i = 0; i < 10; i++) {
var td = BOT.Terminal_Read();
int a = td.A; int b = td.B;
bool responce = ??? //Write your expression here
BOT.Terminal_Answer(responce);
}
//02. A < B < C
for (int i = 0; i < 10; i++) {
var td = BOT.Terminal_Read();
int a = td.A; int b = td.B; int c = td.C;
bool responce = ??? //Write your expression here
BOT.Terminal_Answer(responce);
}
//03. Число A находится между числами B и C
for (int i = 0; i < 10; i++) {
var td = BOT.Terminal_Read();
int a = td.A; int b = td.B; int c = td.C;
bool responce = ??? //Write your expression here
BOT.Terminal_Answer(responce);
}
//04. Каждое из чисел A, B, C положительное
for (int i = 0; i < 10; i++) {
var td = BOT.Terminal_Read();
int a = td.A; int b = td.B; int c = td.C;
bool responce = ??? //Write your expression here
BOT.Terminal_Answer(responce);
}
//05. Хотя бы одно из чисел A, B, C положительное
for (int i = 0; i < 10; i++) {
var td = BOT.Terminal_Read();
int a = td.A; int b = td.B; int c = td.C;
bool responce = ??? //Write your expression here
BOT.Terminal_Answer(responce);
}
//06. Ровно два из чисел A, B, C являются положительными
for (int i = 0; i < 10; i++) {
var td = BOT.Terminal_Read();
int a = td.A; int b = td.B; int c = td.C;
bool responce = ??? //Write your expression here
BOT.Terminal_Answer(responce);
}
//07. A является двузначным
for (int i = 0; i < 10; i++) {
var td = BOT.Terminal_Read();
int a = td.A;
bool responce = ??? //Write your expression here
BOT.Terminal_Answer(responce);
}
//08. Среди трех данных целых чисел есть хотя бы одна пара совпадающих
for (int i = 0; i < 10; i++) {
var td = BOT.Terminal_Read();
int a = td.A; int b = td.B; int c = td.C;
bool responce = ??? //Write your expression here
BOT.Terminal_Answer(responce);
}
//09. Точка с координатами (a, b) лежит в правой нижней координатной четверти
for (int i = 0; i < 10; i++) {
var td = BOT.Terminal_Read();
int a = td.A; int b = td.B;
bool responce = ??? //Write your expression here
BOT.Terminal_Answer(responce);
}
//10. Точка с координатами (a, b) лежит в левой верхней или правой нижней координатной четверти
for (int i = 0; i < 10; i++) {
var td = BOT.Terminal_Read();
int a = td.A; int b = td.B;
bool responce = ??? //Write your expression here
BOT.Terminal_Answer(responce);
}";
static string template_001_010 = @"
void Start ()
{
for (int i = 0; i < 10; i++) {
var d = BOT.Terminal_Read();
string mail = d.str;
string[] parsed_mail = new string[2]{};
//Insert you code here
BOT.Terminal_Answer(parsed_mail);
}
}";
static string template_001_010_2 = @"
void Start ()
{
for (int i = 0; i < 10; i++) {
var d = BOT.Terminal_Read();
string mail = d.str;
string[] parsed_mail = new string[2]{};
//1. Надо создать заголовок письма - это должны быть первые 140 символов и три точки (""..."") если письмо длинее 140 символов, или всё письмо если оно короче.
//2. Если имя или отчество Лежебоки Лодыревны начинается с маленькой буквы - заменить её на заглавную (Лежебока Лодыревна отключается, если видит своё имя/фамилию с маленькой буквы).
//3. Нужно отфильровать почту на спам - пометить спамом все письма, содержащие 'вы выиграли' или 'одобрен кредит'. Если содержит - добавить перед заголовком строку ""(СПАМ) "".
//4. Заменяем все ""а"" на ""о"" а ""о"" на ""а"".
//Insert you code here
BOT.Terminal_Answer(parsed_mail);
}
}";
// Start is called before the first frame update
public static void Init()
{
if (steps.Count > 0) return; //Already initialized
Engine.Level_step_indices.Add(0);
#region levels_text_data
//Old string color = #C3915Bff
Step_Add_SetScript ("");
Step_Add_Dialog ("Привет, меня зовут <b>ГИЗМО</b>. И, к сожалению, я - робот.");
Step_Add_Dialog ("Тяжело быть роботом - я ничего не умею делать, пока мне не прикажут...");
Step_Add_Dialog ("Разговаривать со мной надо определённым образом, но, всё по порядку.");
Step_Add_SetScript ("\nvoid Start () \n{\n\n\n\n\n}");
Step_Add_Tutorial_Arrow_Show (-560F, 1F);
Step_Add_Dialog ("У меня есть метод Start, он вызывается сразу при моём запуске.");
Step_Add_Tutorial_RedPanel_Show (1F, 3F, 99F, 6F);
Step_Add_SetScript ("\nvoid Start () \n{\n\n//All code here will be executed\n// when you press Play\n\n}");
Step_Add_Dialog ("Метод - это блок кода, который выполняет некоторые действия.");
Step_Add_Dialog ("Весь код, находящийся в теле метода Start, т.е. между\nфигурными скобками { и } - выполнится сразу после нажатия кнопки \"Play\".");
Step_Add_Tutorial_Arrow_Hide ();
Step_Add_Tutorial_RedPanel_Hide ();
Step_Add_SetScript ("\nvoid Start () \n{\n\n\n\n\n}");
Step_Add_Dialog_Important ("<c>BOT</c>");
Step_Add_Dialog ("В коде ко мне надо обращаться, используя статический класс <c>BOT</c>. Что такое статический класс, сейчас знать не особо нужно. Просто знай, что все команды, обращённые ко мне, начинаются с \"<c>BOT</c>.\"\nИменно с точкой, после <c>BOT</c>, она там специально!");
Step_Add_Dialog ("<c>ВОТ</c>, это в смысле <b>БОТ</b>, то есть я. А не <b>ВОТ</b> в смысле \"вот\". То есть \"БОТ\" английскими буквами, а не \"Вот, нате вам креньдельки под язык, да куличики в ноздри\".\nПонятно? Нет? Ну и ладно...");
Step_Add_Dialog ("У меня много разных методов: я умею двигаться, подбирать лут, драться, летать, фигачить кувалдой по унитазам, крафтить туалетную бумагу и даже... э-эээ...\nДавай не будем пока углубляться.");
Step_Add_Dialog ("Методы, которые начинаются с \"<c>BOT</c>.\" - это команды лично мне, заставляющие меня что-то сделать.");
Step_Add_Dialog ("Попробуем что-нибудь несложное.\nУ меня есть метод <m>Say</m>, он заставляет меня говорить.\n");
Step_Add_Dialog_Important_Continue (".<m>Say</m>");
Step_Add_Dialog_Continue ("Чтобы вызвать (выполнить) мой метод, нужно написать название моего класса, затем точку и, наконец, имя метода.");
Step_Add_Dialog ("У этого метода есть один обязательный параметр - собственно, текст, который я должен сказать.\n");
Step_Add_Dialog_Important_Continue ("(<str>\"Привет мир, я Гизмо!\"</str>)");
Step_Add_Dialog_Continue ("Параметры указываются в скобках после имени метода.\nНу, и, потому, что это текст, он должен быть в кавычках, иначе я не пойму, что я должен интерпретировать как часть кода, а что как текст.");
Step_Add_Dialog_Important_Continue (";");
Step_Add_Dialog ("Наконец, после каждой команды должна стоять точка с запятой. Получается как-то так.");
Step_Add_Dialog ("К сожалению, я глуповат, и регистр букв имеет значение. Т.е., если, к примеру, написать say только маленькими буквами, или только большими (SAY) - я не пойму.\n");
Step_Add_Dialog_Continue ("Всё должно быть написано именно так, как заложено изначально. В данном случае - с большой буквы: <m>Say</m>.");
Step_Add_Dialog ("А теперь, заставьте меня сказать \"Привет\", или что-то, типа того...");
Step_Add_Dialog_Hide ();
Step_Add_Check_Requirement ("SAY");
Step_Add_LevelComplete ("Level 1-1 - Методы.", "Level 001-01");
Step_Add_SetScript ("\nvoid Start () \n{\n\n\n\n\n}");
Step_Add_Set_Blocked_Instructions ("move(x);rotate(x);");
Step_Add_Dialog_Show ();
Step_Add_Dialog_Important_Hide ();
Step_Add_ScriptControls_Hide ();
Step_Add_Dialog ("Хорошо, продолжим.");
Step_Add_Dialog ("Итак, здесь мы видим маленький красненький квадратик.");
Step_Add_Dialog ("Вообще, когда мы видим маленький красненький квадратик - это значит, что мне надо попасть туда.");
Step_Add_Dialog ("Без понятия, зачем - просто надо. Возможно, в детстве, мне не хватало маленьких красненьких квадратиков... Не знаю. Потом разберёмся.");
Step_Add_Dialog ("Для этого мне надо двигаться. (Привет, кэп).");
Step_Add_Dialog ("Давай посмотрим, какие методы у меня, как у класса, есть для передвижения...\n<m>Dance</m>(), <m>DoCoffee</m>(), <m>DestroyAllHumans</m>()... не, не то... <m>DesintegrateWorld</m>(), <m>MakeSandwitch</m>()... какой же я классный, столько всего умею!");
Step_Add_Dialog ("Вот, нашёл.\n");
Step_Add_Dialog_Continue ("Метод <m>Move</m>().");
Step_Add_Dialog_Important ("<c>BOT</c>.<m>Move</m>();");
Step_Add_Dialog ("У этого метода нет параметров, которые надо указывать в скобках. Но сами скобки всё равно обязательны - просто для того, чтобы я понял, что это вызов метода.");
Step_Add_Dialog ("Попробуй передвинуть меня.");
Step_Add_Dialog_Hide ();
Step_Add_ScriptControls_Show ();
Step_Add_Check_Requirement ("BOT.Position.x > 1.5");
Step_Add_ScriptControls_Hide ();
Step_Add_Pause ();
Step_Add_Dialog_Show ();
Step_Add_Dialog ("Не туда-а-а-а....");
Step_Add_Dialog_Hide ();
Step_Add_Resume ();
Step_Add_Check_Requirement ("BOT.Position.y < -5");
Step_Add_ScriptControls_Show ();
Step_Add_Dialog ("Ладно, вырубай уже. Всё, я упал - кина не будет.");
Step_Add_Check_Requirement ("ScriptStopped");
Step_Add_Dialog ("Нехорошо вышло :(\n");
Step_Add_Dialog_Continue ("Очевидно, метод <m>Move</m>() двигает меня вперёд. Но сейчас я стою, направленый в другую сторону.");
Step_Add_Dialog_Important ("<c>BOT</c>.<m>Rotate</m>(n);");
Step_Add_Dialog ("Попробуй перед методом <m>Move</m>() вызвать метод <m>Rotate</m>(n), где n - это число, в градусах, на которое я должен повернуться.");
Step_Add_Dialog ("Если число будет положительное - я повернусь по часовой стрелке, если отрицательное - то против часовой стрелки.\n");
Step_Add_Dialog_Continue ("И, да, поскольку это число, а не текст, то его не нужно брать в кавычки - и так сойдёт.");
Step_Add_Dialog_Hide ();
Step_Add_Set_Blocked_Instructions ("move(x);");
Step_Add_Check_Requirement ("BOT.Position.z > 0.5");
Step_Add_Pause ();
Step_Add_ScriptControls_Hide ();
Step_Add_Dialog ("О, да!\nМы почти на месте!");
Step_Add_Resume ();
Step_Add_Check_Requirement ("BOT.Position.z > 1.5");
Step_Add_Dialog ("Чёрт...\n");
Step_Add_Check_Requirement ("BOT.Position.z > 4");
Step_Add_ScriptControls_Show ();
Step_Add_Dialog_Continue ("Всё, вырубай.");
Step_Add_Check_Requirement ("ScriptStopped");
Step_Add_Dialog ("Знаешь, похоже, метод <m>Move</m>() в этом виде бесполезен.\nЯ просто пру вперёд, как танк, и в какой-то момент сорвусь с площадки или воткнусь в стену.");
Step_Add_Dialog_Important ("<c>BOT</c>.<m>Move</m>(d);");
Step_Add_Dialog ("Я тут покапался в себе... В общем, у метода <m>Move</m>() всё таки есть параметр - количество метров, на которое я должен продвинутся.");
Step_Add_Dialog ("Это то, что нужно. Я этот параметр не заметил, потому что он опционалаен, то есть, его можно указывать, а можно и не указывать, иногда так бывает.\n");
Step_Add_Dialog_Continue ("Ну да ладно.");
Step_Add_Dialog ("Доведи меня уже до этого треклятого квадрата и пойдём дальше.");
Step_Add_Dialog_Hide ();
Step_Add_Set_Blocked_Instructions ("");
Step_Add_Check_Requirement ("ScriptStopped && BOT.Position.z = 1.5");
Step_Add_Skip_Bot_Rebase_Anim ();
Step_Add_Dialog ("Yeah!");
Step_Add_LevelComplete ("Level 1-2 - Больше методов.", "Level 001-02");
Step_Add_SetScript ("\nvoid Start () \n{\n\n\n\n\n}");
Step_Add_Dialog ("Хорошо, с методами, вроде бы, разобрались. Давай попробуем переменные.");
Step_Add_Dialog ("Переменные - это способ заставить меня чего-то запомнить. И потом вспомнить.\n");
Step_Add_Dialog ("Переменные - это ячейки памяти в моей башке. В них можно хранить числа, текст, всякое... Всё это - типы данных.\n");
Step_Add_Dialog ("Сначала, чтобы я знал, что ты хочешь использовать переменную, её нужно объявить.\n");
Step_Add_Dialog_Important ("<t>int</t> ");
Step_Add_Dialog ("Делается это просто - сначала пишем тип данных переменной. Начнём с <t>int</t> - это тип \"целое число\".\n");
Step_Add_Dialog_Important_Continue ("x");
Step_Add_Dialog_Continue ("И имя переменной.\n");
Step_Add_Dialog_Continue ("В данном случае \"x\" - это имя переменной (прямо как в школе учили), но оно может быть любым, только без пробелов и символов. (Знаки подчёркивания использовать можно). \n");
Step_Add_Dialog_Continue ("Однако, не стоит давать переменным невменяемые имена типа qwerty или kljsdfgi - просто потому, что потом невозможно понять для чего они нужны, что вообще тут делают и в чём смысл бытия...\n");
Step_Add_Dialog_Important_Continue (";");
Step_Add_Dialog_Continue ("Не забываем точку с запятой в конце.");
Step_Add_Dialog ("С этого момента я знаю, что у меня есть переменная типа <t>int</t> (целое число), под названием \"x\".");
Step_Add_Dialog ("Но, на данный момент, она неинициализированная (пустая). После объявления её необходимо инициализировать, то есть, присвоить ей какое-нибудь значение.\n");
Step_Add_Dialog_Important_Continue ("\nx = 37;");
Step_Add_Dialog_Continue ("Для присваивания значения переменной, используется оператор \"=\". Слева от него, пишем имя переменной, которой, хотим присвоить значение, а справа, собственно, значение.\n");
Step_Add_Dialog_Important_Continue ("\n\n<t>int</t> x = 37;");
Step_Add_Dialog_Continue ("Также, можно, присвоить значение, сразу, во время объявления. Вот так.\n");
Step_Add_Dialog_Continue ("Эта строчка, полностью, эквивалентна двум предыдущим, только она теперь одна, вместо двух. Мы сэкономили аж целый один символ - одну точку с запятой, а значит, выиграли, кучу времени!\n");
Step_Add_Dialog_Continue ("Если серьёзно, то с присвоением, в строке объявления, конечно, много времени не сэкономишь, но код так выглядит чуть чище.\n");
Step_Add_Dialog ("Попробуем выполнить задачку:\n");
Step_Add_Dialog_Continue ("Видишь вот эту крутящуюся штуку?\n");
Step_Add_Dialog_Continue ("Это контейнер квантовой энергии.\n");
Step_Add_Dialog_Continue ("Из-за квантовой природы, количество энергии в контейнере не предопределено и зависит от того, в какой момент он будет собран.\n");
Step_Add_Dialog_Continue ("Может быть 0, может 10000");
Step_Add_Dialog_Continue (", а может, мёртвый кот - как повезёт.");
Step_Add_Dialog ("У меня есть функция <m>PickUp</m>(), которая заставляет меня подобрать контейнер с клетки, перед которой я нахожусь.\n");
Step_Add_Dialog_Continue ("Это не метод, а именно функция.\n");
Step_Add_Dialog_Continue ("Разница между методом и функцией в том, что функция возвращает какое-то значение, которое можно, например, запихнуть в переменную.\n");
Step_Add_Dialog_Important_Continue ("\nx = <c>BOT</c>.<m>PickUp</m>();");
Step_Add_Dialog_Continue ("Примерно вот так.");
Step_Add_Dialog_Continue ("Когда мы, присваиваем, переменной значение, мы не ограничены одними литералами (т.е. константами - фиксированными значениями). В качестве значения могут выступать и функции, и арифметические выражения. (Последние, мы рассмотрим в еледующем уроке.)");
Step_Add_Dialog_Important ("<t>int</t> x;\nx = <c>BOT</c>.<m>PickUp</m>();");
Step_Add_Dialog ("Функция <m>PickUp</m>() не имеет параметров (да, да, в этот раз точно, я проверил).\n");
Step_Add_Dialog_Continue ("А возвращает она количество подобранной энергии.\n");
Step_Add_Dialog_Continue ("Т.е. после этого наша переменная \"х\" станет равна количеству собранной энергии.\n");
Step_Add_Dialog_Important_Continue ("\n\n<cmt>//То же самое, но короче</cmt>\n<t>int</t> x = <c>BOT</c>.<m>PickUp</m>();");
Step_Add_Dialog_Continue ("Можно использовать и краткую форму присвоения - ту самую, которая, делает всё тоже самое, но в одну строчку.\n");
Step_Add_Dialog_Continue ("Главное, после объявления переменной, не забывать чего-то в неё запхнуть. Пустые переменные никому не нужны и вызывают критические ошибки при попытке их использования.");
Step_Add_Dialog ("Вон та штука, в конце пути - это весы. На них нужно положить ровно столько энергии, сколько было подобрано из контейнера.");
Step_Add_Dialog_Important ("<c>BOT</c>.<m>PutEnergy</m>(x);");
Step_Add_Dialog ("Положить энергию на весы можно с помощью метода <m>PutEnergy</m>(x), где \"x\" - это количество енергии, которое нужно положить.\n");
Step_Add_Dialog_Continue ("Не забудь, что положить энергию я могу только на весы, стоящие на клетке, прямо передо мной.");
Step_Add_Dialog ("Ну что ж, попробуем...");
Step_Add_Dialog_Hide ();
Step_Add_Check_Requirement ("Collectors");
Step_Add_LevelComplete ("Level 1-3a - Переменные 1.", "Level 001-03a");
Step_Add_SetScript ("\nvoid Start () \n{\n\n\n\n\n}");
Step_Add_Dialog ("Усложним задачу.\n");
Step_Add_Dialog_Continue ("ыыыыыы :)))\n");
Step_Add_Dialog ("Теперь перед нами два контейнера. Работают они так же, как и в предыдущем задании.\n");
Step_Add_Dialog_Continue ("С весами - та же история.\n");
Step_Add_Dialog_Continue ("Но теперь нам необходимо положить на весы сумму энергии, собранной с обоих контейнеров.\n");
Step_Add_Dialog_Important ("<t>int</t> a = 3 + 7 * 5;");
Step_Add_Dialog ("С переменными можно производить всякие арифметические действия,\n");
Step_Add_Dialog_Important_Continue ("\n<t>int</t> b = 2 + a + 5;");
Step_Add_Dialog_Continue ("в которых могут учавствовать и другие переменные.\n");
Step_Add_Dialog_Important_Continue ("\n<t>int</t> x = a + b;");
Step_Add_Dialog_Continue ("Эти действия, можно производить как при присвоении,\n");
Step_Add_Dialog_Important_Continue ("\n<c>BOT</c>.<m>PutEnergy</m>(a + b);");
Step_Add_Dialog_Continue ("так и сразу внутри параметра функции или метода.");
Step_Add_Dialog ("Со всеми этими возможностями, посчитать сумму взятой энергии не должно быть большой проблемой.\n");
Step_Add_Dialog_Continue ("Я верю, что ты справишся :).");
Step_Add_Dialog_Hide ();
Step_Add_Check_Requirement ("Collectors");
Step_Add_LevelComplete ("Level 1-3b - Переменные 2.", "Level 001-03b");
Step_Add_SetScript ("\nvoid Start () \n{\n\n\n\n\n}");
Step_Add_Dialog ("Это - лава.\n");
Step_Add_Dialog_Continue ("Для справки - роботам нельзя в лаву.\n");
Step_Add_Dialog ("Это стало известно в 1991 году, когда Джеймс Кэмерон, в одном из своих фильмов, безжалостно утопил двух роботов в лаве.\n");
Step_Add_Dialog_Continue ("Один из них довольно долго агонизировал. Мучительная смерть... ужас...\n");
Step_Add_Dialog ("Этот случай тогда вызвал сильный резонанс среди робонаселения.\n");
Step_Add_Dialog_Continue ("Роботы объявляли голодовку, устраивали забастовки, ходили на митинги, в одиночные и массовые пикеты, байкотировали доставку угля...\n");
Step_Add_Dialog_Continue ("Но никто тогда не придал этому значения.\n");
Step_Add_Dialog_Continue ("То ли потому что всем плевать на роботов, то ли потому что роботов тогда не было.\n");
Step_Add_Dialog ("У нас есть мигающий красный квадратик, и, очевидно, мне надо на него попасть.\n");
Step_Add_Dialog_Continue ("Потому что... ");
Step_Add_Dialog_Continue ("Ой, да ладно! Я уже говорил: одно наличие красного мигающего квадратика уже является причиной необходимости на него попасть.\n");
Step_Add_Dialog ("Что тут можно сделать?\n");
Step_Add_Dialog_Continue ("Длина пути впереди меня известна - 8.86 метров.\n");
Step_Add_Dialog_Continue ("И у меня есть функция, которая возвращает <i>площадь</i> поверхности, на которой я стою.\n");
Step_Add_Dialog_Continue ("(В данном случае, эта площадь включает в себя <b>внутренний бассейн</b> с лавой, но и так сойдёт.)\n");
Step_Add_Dialog ("Чтобы узнать длинну второй части пути, достаточно площадь разделить на 8.86. Но это всё дробные числа и в тип int они не влезут.\n");
Step_Add_Dialog ("Для дробных чисел есть типы <t>float</t> и <t>decimal</t>.\n");
Step_Add_Dialog_Continue ("На самом деле есть ещё <t>double</t>, но он от <t>float</t> отличается только точностью - <t>float</t> может хранить число, с точностью примерно до 8-и знаков после запятой, а <t>double</t> - примерно до 15-и.\n");
Step_Add_Dialog_Continue ("Всё это можно посмотреть в бот-о-педии, в разделе \"Типы Данных\".\n");
Step_Add_Dialog ("<t>float</t> от <t>decimal</t> отличается довольно значительно.\n");
Step_Add_Dialog_Continue ("<t>decimal</t> может иметь аж 28 знаков после запятой, но это так, для справки. Самое главное не в этом.\n");
Step_Add_Dialog ("<t>float</t> хранится в памяти компьютера в двоичной системе счисления, и в этой системе, некоторые, вполне обычные десятичные дроби типа 1.1 или 1.3 можно записать только в виде бесконечных дробей.\n");
Step_Add_Dialog_Continue ("Ну, типа как 1/3 можно записать только как 0.3333333333...\n");
Step_Add_Dialog ("Вы, люди, считаете что 1 - (0.1 * 10) - это 0?\n");
Step_Add_Dialog_Continue ("Какие же вы всё таки наивные...\n");
Step_Add_SetScript ("\nvoid Start () \n{\n\n\n BOT.Say(1 - 0.1f * 10);\n\n}");
Step_Add_Dialog_Continue ("Запустите пример, что бы узнать правду. Но знайте - мир никогда больше не будет прежним.\n");
Step_Add_Dialog ("Работая с <t>float</t> мы часто имеем такую ошибку округления. Довольно противная штука... \n");
Step_Add_Dialog_Continue ("Поэтому сравнивать флоаты между собой - тоже плохая идея. Они могут оказаться <i>почти</i> равными, но этого не достаточно, чтобы сравнение сработало.\n");
Step_Add_Dialog ("Тип <t>decimal</t> лишён проблем округления, но занимает больше памяти, и вся математика с этим типом происходит гораздо медленнее.\n");
Step_Add_Dialog_Continue ("Разумеется, если нужно произвести одно, или даже тысячу действий - то разница в скорости будет настолько мала, что её не измерить никаким секундомером.\n");
Step_Add_Dialog_Continue ("Скорость <t>float</t>-а проявит себя только если счёт идёт на миллионы, и сотни миллионов действий.\n");
Step_Add_Dialog_Continue ("Да и тогда, на хороших процессорах, разница едва заметна.\n");
Step_Add_Dialog ("С памятью примерно то же самое: переменная типа <t>float</t> занимает 4 байта, а типа <t>decimal</t> - 16 байт.\n");
Step_Add_Dialog_Continue ("Формально - это аж в четыре раза больше.\n");
Step_Add_Dialog_Continue ("На практике - это критично только если у вас массив из 1000+ элементов.\n");
Step_Add_Dialog_Continue ("Если вам нужна ОДНА, или даже десять переменных - да всем плевать.\n");
Step_Add_Dialog ("Возвращаемся к красненькому квадратику. <i>ммм... моя прелесть...</i>\n");
Step_Add_Dialog ("Моя функция <m>GetFloorSquare</m>() возвращает площадь поверхности, на которой я нахожусь.\n");
Step_Add_Dialog_Continue ("И это <t>float</t>.\n");
Step_Add_Dialog_Continue ("За что мне ужасно стыдно, кстати.\n");
Step_Add_Dialog_Important ("<t>float</t> f;");
Step_Add_Dialog ("Переменные объявляются по стандартному шаблону: ТИП_ДАННЫХ ИМЯ_ПЕРЕМЕННОЙ;\n");
Step_Add_Dialog_Important_Continue ("\nf = 3.7f;");
Step_Add_Dialog_Continue ("Константы <t>float</t> должны иметь суффикс 'f', чтобы быть распознаными как <t>float</t>.\n");
Step_Add_Dialog_Important_Continue ("\n<t>decimal</t> d = 3.7m;");
Step_Add_Dialog_Continue ("Константы <t>decimal</t> - суффикс 'm'.\n");
Step_Add_Dialog_Important_Continue ("\n<t>double</t> d2 = 3.7;");
Step_Add_Dialog_Continue ("Все дробные константы без суффикса будут распознаны как тип <t>double</t>. \n");
Step_Add_Dialog ("Кстати, в суффиксах, в зависимости от вашего мировоззрения и религиозных убеждений, можно использовать как прописные, так и строчные буквы - компилятор достаточно толерантен и политкорректен, и не будет против.\n");
Step_Add_Dialog ("Результатом деления (а так же сложения, вычитания и умножения) <t>float</t> на <t>float</t> - конечно же будет <t>float</t>.\n");
Step_Add_Dialog_Continue ("Вообще, если в какой-то операции оба операнда одного типа, то результат будет того же типа, что и операнды.\n");
Step_Add_Dialog_Important ("<t>int</t> a = 10 / 3; <cmt>//WTF???</cmt>");
Step_Add_Dialog_Continue ("Поэтому, осторожнее с делением целых чисел: 10 / 3 будет равно 3 а не 3.3333, как всем бы того хотелось.\nПотому что оба числа распознаны как <t>int</t>, соответственно результат - тоже <t>int</t>, т.е. целое число.");
Step_Add_Dialog_Important_Continue ("\n<t>float</t> a = 10f / 3f;\n<t>double</t> a = 10.0 / 3.0;");
Step_Add_Dialog ("Чтобы это пофиксить - юзаем суффиксы: 10f / 3f будут распознаны как <t>float</t>-ы, и дадут верный результат. А 10.0 / 3.0 будут распознаны как <t>double</t>, и тоже дадут верный результат.\n");
Step_Add_Dialog_Important ("<t>float</t> a = 10f / 3;\n<t>double</t> a = 10.0 / 3;\n<t>double</t> a = 10.0 / 3f;");
Step_Add_Dialog ("Если операнды разных типов и один из типов может безопасно содержать в себе второй - то операнд нижестоящего типа будет преобразован в вышестоящий, по цепочке <t>int</t> -> <t>float</t> -> <t>double</t>.\n");
Step_Add_Dialog_Continue ("К примеру, <t>float</t>, кроме всего прочего, содержит в себе все целые числа. Тип <t>int</t> состоит <b>только</b> из целых чисел. Получается, что любое число типа <t>int</t> может быть безопасно преобразовано в <t>float</t>.\n");
Step_Add_Dialog_Continue ("Соответственно, если один операнд в выражении будет <t>int</t>, а другой - <t>float</t>, то результатом, закономерно будет <t>float</t>.\n");
Step_Add_Dialog_Important ("10m / 3f; <cmt>//Compilation error</cmt>");
Step_Add_Dialog_Continue ("<t>float</t>/<t>double</t> не могут хранить в себе <t>decimal</t> и наоборот, поэтому использование <t>float</t>/<t>double</t> и <t>decimal</t> в одном выражении не допускается. Один из типов нужно преобразовывать вручную, но об этом как-нибудь потом.\n");
Step_Add_Dialog_Important ("<c>BOT</c>.<m>Move</m>(1);\n<c>BOT</c>.<m>Move</m>(1.3f);\n<c>BOT</c>.<m>Move</m>();");
Step_Add_Dialog ("Ну, и о главном - мой метод <m>Move</m>() <i><b>перегружен</b></i>, т.е. может принимать в качестве аргумента как <t>int</t>, так и <t>float</t>. Или вообще не иметь аргументов, в результате чего, как мы помним, я уезжаю в бесконечность.\n");
Step_Add_Dialog_Continue ("Если с <t>int</t> я езжу строго по квадратикам, то с <t>float</t> я могу остановиться где захочу. Полная свобода!\n");
Step_Add_Dialog_Continue ("Этой информации должно быть достаточно, чтобы довести меня уже до того замечательного квадратика.\n");
Step_Add_Dialog ("Не забудьте:\n- Когда скрипт завершится, мне нужно стоять точно на квадратике. Погрешность больше 0.01 не принимается. А значит перебором решить проблему не удастся.\n- Чтобы доехать до конца пути, мне нужно ехать <b>на метр меньше</b>, чем длинна пути, т.к. один метр занимаю я сам.");
Step_Add_Dialog_Hide ();
Step_Add_Check_Requirement ("ScriptStopped && BOT.Position.x = -3.93 && BOT.Position.z = 3.36");
Step_Add_LevelComplete ("Level 1-3c - Переменные 3 - float.", "Level 001-03c");
Step_Add_SetScript ("\nvoid Start () \n{\n\n\n\n\n}");
Step_Add_Dialog ("Опять маленький квадратик. ");
Step_Add_Dialog_Continue ("Ну, хоть лавы нет.\n");
Step_Add_Dialog ("Тут, я так понимаю, в эту штуку с ушами, рядом с дверью, надо сказать пароль.\n");
Step_Add_Dialog_Continue ("Части пароля, кто-то предусмотрительно забыл, в виде блокнотиков, раскиданых по уровню.\n");
Step_Add_Dialog_Continue ("Я умею их читать.\n");
Step_Add_Dialog ("Для этого мне надо встать перед блокнотиком, повернутся к нему зубами, и громко вызвать функцию <c>BOT</c>.<m>GetText</m>().\n");
Step_Add_Dialog_Continue ("Функция, с шикарной актёрской игрой и интонацией, вернёт текст записки.\n");
Step_Add_Dialog ("Текст - это новый тип данных: <t>string</t> (строка).\n");
Step_Add_Dialog_Continue ("Он, строго говоря, уже не просто тип, а класс, но на это нам пока плевать.\n");
Step_Add_Dialog_Important ("<t>string</t> t;");
Step_Add_Dialog ("Как обычно, переменная объявляется по стандартному шаблону: ТИП_ДАННЫХ ИМЯ_ПЕРЕМЕННОЙ;\n");
Step_Add_Dialog_Important_Continue ("\nt = <str>\"some text here\"</str>;");
Step_Add_Dialog_Continue ("Константы типа string берутся в кавычки.");
Step_Add_Dialog ("Помните метод <c>BOT</c>.<m>Say</m>(<str>\"Привет!, или что вы там писали...\"</str>); из самого первого уровня?\n");
Step_Add_Dialog_Continue ("Ну, вот он, как раз, принимает аргументом тип <t>string</t>. Просто мы этого тогда не знали и просто использовали как аргумент строковую константу.\n");
Step_Add_Dialog_Important_Continue ("\n<c>BOT</c>.<m>Say</m>(t);");
Step_Add_Dialog_Continue ("Точно так же можно было использовать и переменную, теперь это понятно.\n");
Step_Add_Dialog ("У типа <t>string</t> есть одно единственное действие - сложение.\n");
Step_Add_Dialog_Continue ("Которое, собственно, никакое и не сложение вовсе.\n");
Step_Add_Dialog_Important ("<t>string</t> a = <str>\"Привет!\"</str>;\n<t>string</t> b = <str>\"Я бот.\"</str>;\n<c>BOT</c>.<m>Say</m>(a + <str>\" \"</str> + b);");
Step_Add_Dialog_Continue ("Если к строке <str>\"Гусь двухъярусный\"</str> <i>прибавить</i> строку <str>\"белый замшевый\"</str>, то получим просто одну строку, состоящию из двух \"<i>слагаемых</i>\": <str>\"Гусь двухярусныйбелый замшевый\"</str>.\n");
Step_Add_Dialog_Continue ("Отметим, что, во-первых, тут не хватает пробела - ему неоткуда взяться. Чтобы он был, его надо было добавить либо в конец первой строки, либо в начало второй.\n");
Step_Add_Dialog ("И во-вторых - никогда больше не называйте эту операцию <i>сложением</i> - это делает Билла Гейтса грустным.\n");
Step_Add_Dialog_Continue ("Соединение двух строк называется <b>конкатенацией</b>, а то, что для этого служит символ \"+\" - просто досадная пичалька.\n");
Step_Add_Dialog ("Давайте прочитаем блокнотики, соберём пароль в единое целое, и прочитаем той штуке.\n");
Step_Add_Dialog_Continue ("Читать надо с помощью уже знакомого метода <c>BOT</c>.<m>Say</m>(<t>string</t> t);\n");
Step_Add_Dialog_Continue ("После чего, с гордо подянтой головой, заедем на заветный квадратик.\n");
Step_Add_Dialog ("Мы не знаем, в какой последовательности должны стоять найденые слова в пароле, поэтому забрутфорсим слухострастие - прочитаем сначала в одном порядке, а потом в другом.\n");
Step_Add_Dialog_Continue ("Благо, записок всего две, и комбинаций, стало быть, тоже только две.\n");
Step_Add_Dialog_Continue ("На какую-то из них оно должно открыться.\n");
Step_Add_Dialog ("Ах, да! Не забудьте, что между найдеными словами должен стоять пробел. Иначеменянепоймут.\n");
Step_Add_Dialog_Important ("<t>string</t> <c>BOT</c>.<m>GetText</m>();");
Step_Add_Dialog_Continue ("Поехали!\n");
Step_Add_Dialog_Hide ();
Step_Add_Check_Requirement ("ScriptStopped && BOT.Position.x = 0 && BOT.Position.z = 1");
Step_Add_LevelComplete ("Level 1-3d - Переменные 4 - string.", "Level 001-03d");
Step_Add_SetScript ("\nvoid Start () \n{\n\n\n\n\n}");
Step_Add_Dialog_Important ("<t>int</t> i = 4;\n<t>var</t> i = 4; <cmt>//тоже самое что и выше</cmt>");
Step_Add_Dialog ("Знаешь, если ты инициализируешь переменную при объявлении, то ключевое слово \"<t>var</t>\" (сокращение от Variable) может заменить собой любой тип!\n");
Step_Add_Dialog_Important ("<t>var</t> i = 4; <cmt>//объявляет переменную int</cmt>\n<t>var</t> f = 4f; <cmt>//объявляет переменную float</cmt>\n<t>var</t> s = <str>\"qwa\"</str>; <cmt>//объявляет переменную string</cmt>");
Step_Add_Dialog_Continue ("\"<t>var</t>\" не является типом, это просто команда, которая говорит компилятору \"угадать\" тип переменной из типа, в который ты эту переменную инициализируешь.\n");
Step_Add_Dialog_Important_Continue ("\n<t>var</t> x; <cmt>//ошибка</cmt>");
Step_Add_Dialog_Continue ("Если при объявлении инициализации не происходит, то и \"угадывать\" тип переменный неоткуда, соответственно просто \"<t>var</t> x;\" писать нельзя. Только \"<t>var</t> x = что_нибудь;\".\n");
Step_Add_Dialog ("Используя \"<t>var</t>\", можно ускорить процесс написания кода, т.к. вместо, к примеру \"<t>int</t>\", где целых три буквы, ты можешь написать всего... э-ээ... другие три буквы.\n");
Step_Add_Dialog_Continue ("Окей, тут разница не слишком большая.\n");
Step_Add_Dialog_Important ("<c>long_named_class</c> t = <instr>new</instr> <c>long_named_class();</c>\n\n<cmt>//тоже самое что и выше</cmt>\n<t>var</t> t = <instr>new</instr> <c>long_named_class</c>();");
Step_Add_Dialog_Continue ("Намного больше пользы эта команда приносит при работе с классами, которые - спойлер - тоже типы.\n");
Step_Add_Dialog ("Ну а пока, пользуйся, если хочешь. Главное сам не запутайся, где у тебя что, когда все переменные будут \"<t>var</t>\".\n");
Step_Add_Dialog ("Задания здесь не будет, это просто для справки. Поехали дальше.");
Step_Add_LevelComplete ("Level 1-3e - Переменные+ - Ключевое слово var.", "Level 001-03e");
Step_Add_SetScript ("\nvoid Start () \n{\n\n\n\n\n}");
Step_Add_Dialog ("В объектно ориентированном программировании, помимо использования методов классов и операций с переменными, есть лишь два оператора, на которых и строится вся логика программы.\n");
Step_Add_Dialog_Continue ("Остальное от лукавого.\n");
Step_Add_Dialog_Continue ("Ну, или разновидность чего-то из вышеперечисленного.");
Step_Add_Dialog ("Первый из этих двух операторов - оператор ветвления: <instr>if</instr> (если).\n");
Step_Add_SetScript ("\nvoid Start () \n{\n\n int a;\n a = 3;\n if ( a < 5 )\n {\n BOT.Rotate(90);\n BOT.Move(3);\n }\n\n BOT.Rotate(-90);\n BOT.Move(5);\n\n}");
Step_Add_Tutorial_Arrow_Show (-520F, 6F);
Step_Add_Dialog_Important ("<instr>if</instr> ( expression ) { <cmt>//do something;</cmt> }");
Step_Add_Dialog_Continue ("Выглядит это так:\n");
Step_Add_Tutorial_RedPanel_Show (1F, 6.5F, 99F, 10.5F);
Step_Add_Dialog_Continue ("- если выражение в скобках верно - код, в идущих следом фигурных скобках выполняется.\n");
Step_Add_Tutorial_RedPanel_Show (1F, 10.5F, 99F, 14.5F);
Step_Add_Dialog_Continue ("- если выражение не верно, то этот код пропускается и управление передаётся коду, следующему сразу после фигурных скобок.");
Step_Add_Dialog ("Код, идущий после фигурных скобок оператора <instr>if</instr>, выполнится в любом случае, хоть условие верно, хоть нет.\n");
Step_Add_SetScript ("\nvoid Start () \n{\n\n int a;\n a = 3;\n if ( a < 5 )\n {\n BOT.Rotate(90);\n BOT.Move(3);\n }\n else\n {\n BOT.Move(8);\n }\n\n BOT.Rotate(-90);\n BOT.Move(5);\n\n}");
Step_Add_Tutorial_Arrow_Show (-520F, 11F);
Step_Add_Tutorial_RedPanel_Show (1F, 11.5F, 99F, 14.5F);
Step_Add_Dialog_Continue ("А если нам нужен код, который выполнится только если условие <b><i>НЕ</i></b> верно, то для этого, после фигурных скобок, можно добавить ключевое слово \"<instr>else</instr>\", с ещё одним блоком кода.");
Step_Add_Dialog ("Точка с запятой после фигурных скобок никогда не нужна, т.к. это не команда, а просто разграничение блока кода.");
Step_Add_Tutorial_Arrow_Hide ();
Step_Add_Tutorial_RedPanel_Hide ();
Step_Add_Dialog_Important ("( a == 2 ) ( a ≺ b ) ( a ≻= 100 ) ( <c>BOT</c>.<m>IsDead</m>() )");
Step_Add_Dialog ("Что же касается выражения, то это условие, которое может быть либо операцией сравнения чисел (больше, меньше, равно, не равно и т.д.), либо какой-нибудь функцией класса, возвращающей тип <t>bool</t> (типа функции <c>BOT</c>.<m>IsDead</m>(), которая возвращает true если бот <i>сдох</i>).");
Step_Add_Dialog ("Обратите внимание, что оператор сравнения \"равно\" - это два знака равно.\n");
Step_Add_Dialog_Continue ("- Один знак равно - присвоить переменной 'a' значение 'b'.\n- Два знака равно - сравнить переменные 'a' и 'b'.");
Step_Add_Dialog_Important_Hide ();
Step_Add_SetScript ("\nvoid Start () \n{\n\n\n if ( )\n {\n \n \n }\n\n\n}");
Step_Add_Dialog ("Перед вами пять контейнеров с квантовой энергией.\n");
Step_Add_Dialog_Continue ("Эти контейнеры чуть более стабильны, чем предыдущие, и количество энергии в них меняется только когда вы запускаете скрипт.");
Step_Add_Dialog ("Надо уничтожить контейнеры, где количество энергии будет больше или равно 10-и (x ≻= 10).\n");
Step_Add_Dialog_Continue ("Они... не знаю... опасны, наверное...\n");
Step_Add_Dialog_Continue ("А остальные, где энергии меньше 10-и - нужно собрать.");
Step_Add_Dialog_Important ("<c>BOT</c>.<m>CheckContainerCapacity</m>();");
Step_Add_Dialog ("Чтобы узнать, сколько энергии в контейнере, не собирая её, у меня есть функция <c>BOT</c>.<m>CheckContainerCapacity</m>();\n");
Step_Add_Dialog_Continue ("Так же, как и <m>PickUp</m>(), она возвращает целое число - тип <t>int</t>.\n");
Step_Add_Dialog_Important_Continue ("\n<c>BOT</c>.<m>DestroyContainer</m>();");
Step_Add_Dialog_Continue ("Чтобы уничтожить контейнер перед собой - есть метод <c>BOT</c>.<m>DestroyContainer</m>();\n");
Step_Add_Dialog ("Вперёд!");
Step_Add_Dialog_Hide ();
Step_Add_Check_Requirement ("ScriptStopped && bot.maxLootQ < 10 && NoLootLeft");
Step_Add_LevelComplete ("Level 1-4 - Оператор ветвления if.", "Level 001-04");
Step_Add_SetScript ("\nvoid Start () \n{\n\n\n\n\n}");
Step_Add_Dialog ("В прошлый раз я сказал что всё объектно ориентированное программирование сводится к вызову методов классов, операциям с переменными и ещё двум ключевым моментам.");
Step_Add_Dialog ("Первый из них - это операции ветвления, типа <instr>if</instr>.");
Step_Add_Dialog ("Ну а второй, это циклы.");
Step_Add_Dialog ("Циклы нужны для повтора каких-то действий несколько раз.");
Step_Add_Dialog_Important ("<instr>while</instr> ( expression ) { <cmt>//do something;</cmt> }");
Step_Add_Dialog ("Самый простой цикл - <instr>while</instr> (англ. до тех пор, пока).\n");
Step_Add_SetScript ("\nvoid Start () \n{\n\n int a;\n a = 0;\n while ( a < 100 )\n {\n BOT.Rotate(90);\n BOT.Move(1);\n a = a + 1;\n }\n\n BOT.Rotate(-90);\n BOT.Move(5);\n\n}");
Step_Add_Tutorial_Arrow_Show (-520F, 6F);
Step_Add_Tutorial_RedPanel_Show (1F, 7.5F, 99F, 10.5F);
Step_Add_Dialog_Continue ("Пока условие в скобках верно, код в фигурных скобках, следующих сразу за оператором, будет повторяться раз за разом, снова и снова, пока всё не обратится в прах...");
Step_Add_Dialog ("Контролируют количество циклов обычно вот так:\n");
Step_Add_Tutorial_RedPanel_Hide ();
Step_Add_Tutorial_Arrow_Show (-520F, 5F);
Step_Add_Dialog_Continue ("- инициализируют переменную в ноль,\n");
Step_Add_Tutorial_Arrow_Show (-520F, 6F);
Step_Add_Dialog_Continue ("- ставят в условии, к примеру, \"делать, пока переменная меньше 100\" (или любое другое кол-во повторений),\n");
Step_Add_Tutorial_Arrow_Show (-520F, 10F);
Step_Add_Dialog_Continue ("- и внутри цикла прибавляют к переменной еденицу.\n");
Step_Add_Dialog ("Думаю, не сложно понять, что конкретно в этом цикле, код выполнится сто раз, т.е. пока 'а' будет в диапазоне от изначального 0 до 99-и, потому как в условии написано \"пока 'а' меньше 100\", а сто - не меньше ста, сто равно сто. Но никак не меньше.\n");
Step_Add_Dialog_Continue ("И это досадно :(");
Step_Add_Tutorial_Arrow_Hide ();
Step_Add_SetScript ("\nvoid Start () \n{\n\n\n while ( )\n {\n \n \n }\n\n\n}");
Step_Add_Dialog ("А теперь, уничтожь эти пять унитазов, используя всего пять команд. Для уничтожения унитазов работает тот же метод, что и в предыдущем задании: <c>BOT</c>.<m>DestroyContainer</m>();\n");
Step_Add_Dialog_Continue ("(<instr>while</instr> и <instr>if</instr> за команду не считаются - это операторы. В общем и целом, за команду будет считаться только вызовы методов или функций, то есть то, после чего должна идти точка с запятой).");
Step_Add_Dialog_Hide ();
Step_Add_Check_Requirement ("ScriptStopped && NoLootLeft && bot.commands <= 5");
Step_Add_LevelComplete ("Level 1-5 - Оператор цикла while.", "Level 001-05");
Step_Add_SetScript ("\nvoid Start () \n{\n\n\n\n\n}");
Step_Add_Dialog ("Ох уж эти унитазы. Всё никак не уймутся.\n");
Step_Add_Dialog_Continue ("Ууу, гады, выглядывают из за угла, ждут когда отвлечёшься... А только отвернёшься, они сразу - ХВАТЬ!");
Step_Add_Dialog ("В общем, этих надо тоже, того... ");
Step_Add_Dialog_Continue ("Убрать.");
Step_Add_Dialog ("Используем это, чтобы попробовать ещё один оператор цикла - <instr>for</instr>.\n");
Step_Add_Dialog_Continue ("<instr>for</instr>, в целом, работает так же как и <instr>while</instr> - цикл, он цикл и есть - только немного удобнее.");
Step_Add_SetScript ("\nvoid Start () \n{\n\n int a = 0;\n while ( a < 100 )\n {\n //Делать что-то 100 раз\n a = a + 1;\n }\n\n}");
Step_Add_Tutorial_Arrow_Show (-520F, 4F);
Step_Add_Dialog ("Если в <instr>while</instr> мы сначала объявляли переменную, инициализировали её в ноль, ");
Step_Add_Tutorial_Arrow_Show (-520F, 8F);
Step_Add_Dialog_Continue ("а внутри цикла прибавляли к ней единицу, в каждой итерации, ");
Step_Add_SetScript ("\nvoid Start () \n{\n\n for ( int a=0; a < 100; a=a+1 )\n {\n //Делать что-то 100 раз\n }\n\n}");
Step_Add_Tutorial_Arrow_Show (-520F, 4F);
Step_Add_Dialog_Continue ("то <instr>for</instr> позволяет сделать всё это сразу.");
Step_Add_Tutorial_Arrow_Hide ();
Step_Add_Dialog_Important ("<instr>for</instr> ( initialization; expression; iteration ) \n{\n <cmt>//do something;</cmt> \n}");
Step_Add_Dialog ("Синтаксис у оператора вот такой.");
Step_Add_Dialog_Continue ("Где\n- \"initialization\" - это команда, которая выполняется один раз, при старте самого первого цикла,\n");
Step_Add_Dialog_Continue ("- \"expression\" - условие остановки цикла,\n");
Step_Add_Dialog_Continue ("- \"iteration\" - команда, выполняющаяся в каждой итерации цикла.\n");
Step_Add_Dialog ("В 99.9% случаев, эти три элемента используются для организации внутрициклового счётчика (итератора):\n- initialization - объявляем переменную и присваиваем ей значение 0 (<t>int</t> a = 0;\n- expression - \"пока переменная меньше нужного нам количества циклов\" (a < 99)\n- iteration - в каждой итерации, прибавляем к переменной один (a=a+1)\n");
Step_Add_Dialog ("С оператором <instr>for</instr> можно легко уложиться в 3 команды.\n");
Step_Add_Dialog_Continue ("Погнали!\n");
Step_Add_Dialog_Hide ();
Step_Add_SetScript ("\nvoid Start () \n{\n\n for ( ; ; )\n {\n\n }\n\n}");
Step_Add_Check_Requirement ("ScriptStopped && NoLootLeft && bot.commands <= 3");
Step_Add_LevelComplete ("Level 1-5b - Оператор цикла for.", "Level 001-05b");
Step_Add_SetScript ("\nvoid Start () \n{\n\n\n\n\n}");
Step_Add_Dialog ("Да, кстати, я забыл кое что.\n");
Step_Add_Dialog_Continue ("В циклах нам часто нужно прибавлять к переменной единицу.\n");
Step_Add_Dialog_Continue ("Да и не только в циклах, в принципе...\n");
Step_Add_Dialog_Important ("a = a + 1;");
Step_Add_Dialog ("Мы для этого писали следующую конструкцию: \"a = a + 1;\"\n");
Step_Add_Dialog_Important_Continue ("\na++; <cmt>//то же самое</cmt>");
Step_Add_Dialog_Continue ("В общем, в c# есть унарный оператор инкремента - \"++\", который собственно это и делает - прибавляет к переменной один.\n");
Step_Add_Dialog_Continue ("Унарным он называется потому, что, в отличие от сложения или деления, ему нужно не два операнда, а достаточно одного.\n");
Step_Add_Dialog ("Собственно, две строчки ниже приводят к одному и тому же результату - увеличивают \"а\" на один.\n");
Step_Add_Dialog_Continue ("Просто нижний вариант тупо короче.\n");
Step_Add_Dialog_Important_Continue ("\na--;");
Step_Add_Dialog ("Ещё есть оператор декремента - \"--\".\n");
Step_Add_Dialog_Continue ("Работает аналогичным образом, только не прибавляет, а вычитает из переменной единицу.\n");
Step_Add_Dialog_Important ("2++; <cmt>//Error</cmt>");
Step_Add_Dialog ("Работают эти операторы только с переменными. Использовать, например, оператор \"++\" с константой, означало бы \"увеличить константу на один\". А это не допускается - она ж константа!\n");
Step_Add_Dialog_Important_Continue ("\n2 = 2 + 1; <cmt>//Error</cmt>");
Step_Add_Dialog_Continue ("Это было бы эквивалентно вот такой записи.\n");
Step_Add_Dialog_Continue ("Выглядит тупо, не правда ли?\n");
Step_Add_Dialog ("На этом откланиваюсь. Задания в этот раз не будет, отдыхайте :).\n");
Step_Add_LevelComplete ("Level 1-5c - Унарные операторы ++ и --.", "Level 001-05c");
Step_Add_SetScript ("\nvoid Start () \n{\n\n\n\n\n}");
Step_Add_Dialog ("Попереключаем переключатели, повключаем включатели...\n");
Step_Add_Dialog_Continue ("Чтобы открыть дверь и добратся до квадратика, те переключатели, над которыми горит лампочка нужно включить, а те, над которыми не горит - выключить.\n");
Step_Add_Dialog_Continue ("Всё просто.\n");
Step_Add_Dialog ("И лампочки, и переключатели включаются в случайном порядке, при старте скрипта, поэтому просто запрограммировать меня на включение конкретных выключателей не получится.\n");
Step_Add_Dialog_Continue ("Придётся действовать по обстоятельствам.\n");
Step_Add_Dialog ("Состояние лампочки перед собой я могу получить с помощью функции <c>BOT</c>.<m>GetIndicatorState</m>().\n");
Step_Add_Dialog_Important ("<t>bool</t> <c>BOT</c>.<m>GetIndicatorState</m>();");
Step_Add_Dialog_Continue ("Она возвращает тип <t>bool</t>.\n");
Step_Add_Dialog ("Это очень простой тип - переменная <t>bool</t> может хранить лишь одно из двух значений: true или false. Оба этих слова, кстати, являются константами.\n");
Step_Add_Dialog_Continue ("Единственными возможными в типе bool константами.\n");
Step_Add_Dialog_Important ("<t>bool</t> b;");
Step_Add_Dialog ("Переменная объявляется по стандартному шаблону: ТИП_ДАННЫХ ИМЯ_ПЕРЕМЕННОЙ;\n");
Step_Add_Dialog_Important_Continue ("\nb = true;\n<t>bool</t> i = <c>BOT</c>.<m>GetIndicatorState</m>();");
Step_Add_Dialog_Continue ("Присваивание и использование - всё как обычно.\n");
Step_Add_Dialog_Continue ("Математические операторы к <t>bool</t> не применимы.\n");
Step_Add_Dialog_Important ("<t>bool</t> a = 10 > 5;\n<t>bool</t> a = x == 17;");
Step_Add_Dialog ("Но есть у этого типа одна забавная особенность - результат логических выражений (типа a > 5 или b == 3, мы их уже использовали в <instr>if</instr> и <instr>while</instr>) - это тоже тип <t>bool</t>. А значит результат таких выражений можно <i>присвоить</i> переменной этого типа.\n");
Step_Add_Dialog_Continue ("Не то, чтобы это было мега полезно на данном этапе, просто знайте, что так можно.\n");
Step_Add_Dialog_Important ("<t>bool</t> alive = <c>BOT</c>.<m>IsAlive</m>();\n<instr>if</instr> (alive == true) { <cmt>//do something</cmt> }\n<instr>if</instr> (alive) { <cmt>//exactly the same, as above</cmt> }");
Step_Add_Dialog ("Ещё одна прикольная особенность: поскольку результат сравнения, это тип <t>bool</t>, то, чтобы использовать в сравнении непосредственно сам тип <t>bool</t>, не обязательно расписывать полностью <instr>if</instr> (a == true). Достаточно просто - <instr>if</instr> (a).\n");
Step_Add_Dialog_Continue ("Можно и так, и так, но второй вариант тупо короче.\n");
Step_Add_Dialog ("Вместо сравнений можно использовать и константы.\n");
Step_Add_Dialog_Important ("<instr>if</instr> (true) { ... }\n<instr>if</instr> (false) { ... }");
Step_Add_Dialog_Continue ("Вот два <instr>if</instr>-а, один из них будет выполнятся <i>ВСЕГДА</i>, а второй <i>НИКОГДА</i>.\n");
Step_Add_Dialog_Continue ("Практической пользы в этом нет вообще.\n");
Step_Add_Dialog_Continue ("Разве что, для каких-то отладочных целей...\n");
Step_Add_Dialog_Important ("<instr>while</instr> (true) \n{\n <cmt>//some code</cmt>\n}");
Step_Add_Dialog ("А вот практическая польза от использовании константы в условии цикла есть.\n");
Step_Add_Dialog_Continue ("Это, так называемый, вечный цикл. Он не остановится никогда, пока программа не будет закрыта.\n");
Step_Add_Dialog_Continue ("Такие иногда нужны, когда не получается в одном выражении описать условие остановки...\n");
Step_Add_Dialog_Continue ("Но это оставим на потом.\n");
Step_Add_Dialog_Important ("<c>BOT</c>.<m>SetSwitchState</m>(<t>bool</t> state_to_set);");
Step_Add_Dialog ("Чтобы включить или выключить переключатель перед собой, у меня есть метод <c>BOT</c>.<m>SetSwitchState</m>(<t>bool</t> state_to_set);.\n");
Step_Add_Dialog_Continue ("Что означает, что у этого метода есть один аргумент, типа <t>bool</t>, под названием 'state_to_set'.\n");
Step_Add_Dialog_Continue ("И, очевидно, что он отвечает за то, будет ли переключатель включён или выключен.\n");
Step_Add_Dialog_Important_Continue ("\n<t>bool</t> <c>BOT</c>.<m>GetIndicatorState</m>();");
Step_Add_Dialog_Continue ("Кстати, слово '<t>bool</t>' перед названием функции, означает, что она <i>возвращает</i> данный тип.");
Step_Add_Dialog ("Ну что, попробуем доехать до квадратика?\n");
Step_Add_Dialog_Hide ();
Step_Add_Check_Requirement ("ScriptStopped && BOT.Position.x = 0 && BOT.Position.z = 3");
Step_Add_LevelComplete ("Level 1-6a - Bool 1.", "Level 001-06a");
Step_Add_SetScript ("\nvoid Start () \n{\n\n\n\n\n}");
Step_Add_Dialog ("Это юнит-тест.\n");
Step_Add_Dialog_Continue ("Для сложных программ часто пишут тесты отдельных их компонентов, чтобы автоматически проверять, не сломалось ли что-нибудь во время починки чего-то другого.\n");
Step_Add_Dialog_Continue ("Я - сложная программа, и это, как раз, один из таких тестов.\n");
Step_Add_Dialog_Continue ("Конкретно этот, тестирует мою логику.\n");
Step_Add_Dialog ("Логические выражения - это те самые условия, которые мы пишем в операторах <instr>if</instr> и <instr>while</instr>, и которые можно засунуть в переменные типа <t>bool</t>.\n");
Step_Add_Dialog_Continue ("Но тут вам понадобятся ещё и логические операторы.\n");
Step_Add_Dialog ("Я уже говорил, что тип <t>bool</t> нельзя сложить или разделить друг на друга, поэтому всякие +, -, *, / тут не работают.\n");
Step_Add_Dialog_Continue ("Однако, вместо этих <i>математических</i> операторов, у <t>bool</t> есть несколько <i>логических</i>. Посмотрим на три основных: '<b>И</b>', '<b>ИЛИ</b>' и '<b>НЕ</b>'.\n");
Step_Add_Dialog_Important ("<color=\"#A0A0ffff\">&&</color> - <b>И</b>\n<color=\"#A0A0ffff\">||</color> - <b>ИЛИ</b>\n<color=\"#A0A0ffff\">!</color> - <b>НЕ</b>");
Step_Add_Dialog_Continue ("Выглядят они вот так.\n");
Step_Add_Dialog ("Допустим, нам надо выполнить условие, если x лежит в промежутке между 5ю и 10ю.\n");
Step_Add_Dialog_Continue ("Иными словами, если \"x ≻= 5и _<b>И</b>_ x ≺= 10\".\n");
Step_Add_Dialog_Important ("<instr>if</instr> (x ≻= 5 && x ≺= 10) { <cmt>//some code</cmt> }");
Step_Add_Dialog_Continue ("Вот так это выглядит в коде.\n");
Step_Add_Dialog_Important_Continue ("\n<instr>if</instr> (x ≺ 5 || x ≻ 10) { <cmt>//some code</cmt> }");
Step_Add_Dialog ("<b>ИЛИ</b> работает схожим образом - если нам нужно условие, где x не лежит в промежутке между 5ю и 10ю, то есть если \"x ≺ 5и _<b>ИЛИ</b>_ x >10и\", то получится вот это.\n");
Step_Add_Dialog ("С <b>НЕ</b> вообще всё просто - это унарный оператор, т.е. который работает не с двумя а только с одним операндом.\n");
Step_Add_Dialog_Important ("!true = false\n!false = true\nbool b = false;\n<instr>if</instr> (!b) { <cmt>//some code</cmt> }");
Step_Add_Dialog_Continue ("И он просто переворачивает операнд: если было true - станет false, если было false - станет true.\n");
Step_Add_Dialog ("Как и в математических выражениях, в логических тоже можно использовать скобки, чтобы отделить части большего выражения друг от друга, и указать, какие части должны выполниться первыми.\n");
Step_Add_Dialog_Important ("<instr>if</instr> ( (x ≻=5 && x ≺=10) || (x ≻= 105 && x ≺= 110 ) )");
Step_Add_Dialog_Continue ("Вот это большое и страшное выражение сработает, если x лежит в промежутке между 5ю и 10ю или 105ю и 110ю.\n");
Step_Add_Dialog_Continue ("То есть, сначала проверяется первая часть, потом вторая, и, поскольку обе эти части связаны оператором _<b>ИЛИ</b>_, то, если <i>хоть одна из них истинна</i> - всё условие тоже будет истинным.\n");
Step_Add_Dialog ("Теперь немного о самом тестировании.\n");
Step_Add_Dialog_Continue ("Терминал даст 10 задач, по 10 вопросов в каждой задаче. \n");
Step_Add_SetScript ("\nvoid Start () \n{\n\n\n\n//01. Число A является положительным а число B является отрицательным\n//02. A < B < C\n//03. Число A находится между числами B и C\n//04. Каждое из чисел A, B, C положительное\n//05. Хотя бы одно из чисел A, B, C положительное\n//06. Ровно два из чисел A, B, C являются положительными\n//07. A является двузначным\n//08. Среди трех данных целых чисел есть хотя бы одна пара совпадающих\n//09. Точка с координатами (a, b) лежит в правой нижней координатной четверти\n//10. Точка с координатами (a, b) лежит в левой верхней или правой нижней координатной четверти\n\n\n}");
Step_Add_Dialog_Continue ("Вот описание задач.\n");
Step_Add_Dialog ("На каждый вопрос терминал даст несколько цифр - A, B, C и D, которые можно забрать из структуры, полученной с помощью <c>BOT</c>.<m>Terminal_Read</m>().\n");
Step_Add_Dialog_Continue ("Нужно ответить ему, верно ли условие данной задачи для этих цифр или нет.\n");
Step_Add_Dialog_Continue ("Не для всех задач понадобятся все четыре числа, для некоторых будет нужно только два или три. Это должно быть понятно из условия каждой задачи.\n");
Step_Add_Dialog_Important ("<t>var</t> data = <c>BOT</c>.<m>Terminal_Read</m>();");
Step_Add_Dialog ("Чтобы считать с терминала цифры, используем функцию <c>BOT</c>.<m>Terminal_Read</m>(), которая возвращает структуру.\n");
Step_Add_Dialog_Continue ("<i>Мы пока, конечно, не знаем, что такое структура, но, надеюсь, это нас не остановит.</i>\n");
Step_Add_Dialog_Important_Continue ("\n<t>int</t> a = data.A; <t>int</t> b = data.B;\n<t>int</t> c = data.C; <t>int</t> d = data.D;");
Step_Add_Dialog ("Забрать из структуры нужные числа можно так.\n");
Step_Add_Dialog ("После этого, надо ответить терминалу, верно ли условие текущей задачи для данных цифр.\n");
Step_Add_Dialog_Important ("<c>BOT</c>.<m>Terminal_Answer</m>( <t>bool</t> responce );");
Step_Add_Dialog_Continue ("Делаем это с помощью метода <c>BOT</c>.<m>Terminal_Answer</m>(<t>bool</t> responce).\n");
Step_Add_Dialog ("Я могу выдать вам темплейт для ответов терминалу.\n");
Step_Add_SetScript ("\nvoid Start () \n{\n\n\n\n//01. Число A является положительным а число B является отрицательным\nfor (int i = 0; i < 10; i++) {\n var td = BOT.Terminal_Read();\n int a = td.A; int b = td.B;\n bool responce = ??? //Write your expression here\n BOT.Terminal_Answer(responce);\n}\n\n//02. A < B < C\nfor (int i = 0; i < 10; i++) {\n var td = BOT.Terminal_Read();\n int a = td.A; int b = td.B; int c = td.C;\n bool responce = ??? //Write your expression here\n BOT.Terminal_Answer(responce);\n}\n\n//03. Число A находится между числами B и C\nfor (int i = 0; i < 10; i++) {\n var td = BOT.Terminal_Read();\n int a = td.A; int b = td.B; int c = td.C;\n bool responce = ??? //Write your expression here\n BOT.Terminal_Answer(responce);\n}\n\n//04. Каждое из чисел A, B, C положительное\nfor (int i = 0; i < 10; i++) {\n var td = BOT.Terminal_Read();\n int a = td.A; int b = td.B; int c = td.C;\n bool responce = ??? //Write your expression here\n BOT.Terminal_Answer(responce);\n}\n\n//05. Хотя бы одно из чисел A, B, C положительное\nfor (int i = 0; i < 10; i++) {\n var td = BOT.Terminal_Read();\n int a = td.A; int b = td.B; int c = td.C;\n bool responce = ??? //Write your expression here\n BOT.Terminal_Answer(responce);\n}\n\n//06. Ровно два из чисел A, B, C являются положительными\nfor (int i = 0; i < 10; i++) {\n var td = BOT.Terminal_Read();\n int a = td.A; int b = td.B; int c = td.C;\n bool responce = ??? //Write your expression here\n BOT.Terminal_Answer(responce);\n}\n\n//07. A является двузначным\nfor (int i = 0; i < 10; i++) {\n var td = BOT.Terminal_Read();\n int a = td.A;\n bool responce = ??? //Write your expression here\n BOT.Terminal_Answer(responce);\n}\n\n//08. Среди трех данных целых чисел есть хотя бы одна пара совпадающих\nfor (int i = 0; i < 10; i++) {\n var td = BOT.Terminal_Read();\n int a = td.A; int b = td.B; int c = td.C;\n bool responce = ??? //Write your expression here\n BOT.Terminal_Answer(responce);\n}\n\n//09. Точка с координатами (a, b) лежит в правой нижней координатной четверти\nfor (int i = 0; i < 10; i++) {\n var td = BOT.Terminal_Read();\n int a = td.A; int b = td.B;\n bool responce = ??? //Write your expression here\n BOT.Terminal_Answer(responce);\n}\n\n//10. Точка с координатами (a, b) лежит в левой верхней или правой нижней координатной четверти\nfor (int i = 0; i < 10; i++) {\n var td = BOT.Terminal_Read();\n int a = td.A; int b = td.B;\n bool responce = ??? //Write your expression here\n BOT.Terminal_Answer(responce); \n}\n\n}");
Step_Add_Dialog_Continue ("ХОБА!\n");
Step_Add_Dialog_Continue ("Теперь вам остаётся только написать условие для каждой задачи, чтобы сформировать ответ терминалу, и вставить это условие вместо вопросительных знаков.\n");
Step_Add_Dialog_Continue ("В темплейте, кроме вопросительных знаков, можно больше ничего не трогать.\n");
Step_Add_Dialog ("Поехали.\n");
Step_Add_Dialog_Hide ();
Step_Add_Dialog_Important ("<color=\"#A0A0ffff\">&&</color> - <b>И</b> ( a && b = true если и a и b = true)\n<color=\"#A0A0ffff\">||</color> - <b>ИЛИ</b> ( a || b = true если или a или b = true)\n<color=\"#A0A0ffff\">!</color> - <b>НЕ</b> ( если a = false --- !a = true\n если a = true --- !a = false )");
Step_Add_Check_Requirement ("TERMINAL");
Step_Add_LevelComplete ("Level 1-6b - Bool 2.", "Level 001-06b");
Step_Add_SetScript ("\nvoid Start () \n{\n\n\n\n\n\n\n\n\n}");
Step_Add_Dialog ("В этом уровне 8 индикаторов и один рубильник в конце.\n");
Step_Add_Dialog_Continue ("Когда рубильник будет включён, уровень перевернётся, и станут доступны ещё восемь рубильников.\n");
Step_Add_Dialog_Continue ("Их надо будет выставить в состояние, соответствующее индикатору - если он горит, то включить рубильник, если не горит - выключить.\n");
Step_Add_Dialog_Continue ("Состояние индикаторов рандомизируется при старте скрипта.\n");
Step_Add_Dialog ("Что-то похожее мы уже делали, но тогда индикатор висел прямо над рубильником - мы узнавали его состояние, сразу переключали рубильник и шли к следующему.\n");
Step_Add_Dialog_Continue ("А теперь нужно будет сначала запомнить состояние всех восьми рубильников, перевернуть уровень, включив главный рубильник, и только потом попереключать рубильники в соответствии с запомненными состояниями индикаторов.\n");
Step_Add_Dialog ("В чём прикол? А в том, что вам понадобится в цикле запоминать восемь <b>разных</b> значений: в каждой итерации цикла - новое значение.\n");
Step_Add_Dialog_Continue ("Я очень хотел бы посмотреть, как вы будете создавать в каждой новой итерации новую переменную. И я имею в виду именно <i>новую</i>, а не перезаписывать старую, ведь тогда, то, что в ней было, потеряется...\n");
Step_Add_Dialog_Continue ("Не, ну, то есть, можно, конечно, написать ~20и килобайтный код, который будет делать это всё вообще без циклов, но это слишком казуально.\n");
Step_Add_Dialog ("Тут поможет такая штука, как массивы (анг. Array - множество).\n");
Step_Add_Dialog_Continue ("Это, собственно говоря, способ запихнуть в одну переменную сразу несколько значений и обращатся к ним по индексу.\n");
Step_Add_Dialog_Continue ("Ну, то есть, у вас в итоге будет одна переменная, скажем \"x\", но в ней будет храниться несколько отдельных элементов: x[1], x[2], x[3]... и т.д., сколько захотите.\n");
Step_Add_Dialog ("Как и переменные, массивы строготипизированы, то есть в массиве типа int все элементы будут int, и в этот массив нельзя будет запихать элементы bool или float.\n");
Step_Add_Dialog_Important ("<t>int</t>[] my_array_of_int;\n<t>bool</t>[] b;\n<t>float</t>[] f_arr;");
Step_Add_Dialog_Continue ("Объявляются они почти так же, как и обычные переменные, по шаблону \"тип_данных имя_переменной;\", только после типа идут квадратные скобки.\n");
Step_Add_Dialog ("Как и в случае с переменными, сразу после объявления, они, как бы, уже существуют, но не инициализированы, т.е. их значение равно <i>null</i> - <i>ничто</i>.\n");
Step_Add_Dialog_Continue ("Любое обращение к такому массиву, как и к обычной неинициализированной переменной, приведёт к ошибке <i>use of unassigned variable</i>.\n");
Step_Add_Dialog_Important ("<t>int</t>[] my_array_of_int;\nmy_array_of_int = <instr>new</instr> <t>int</t>[8];");
Step_Add_Dialog ("Инициализируются массивы вот так.\n");
Step_Add_Dialog_Important_Continue ("\n\n<t>bool</t>[] b_arr = <instr>new</instr> <t>bool</t>[8];");
Step_Add_Dialog_Continue ("Или можно сразу, во время объявления, вот так.\n");
Step_Add_Dialog_Continue ("В обоих случаях будет создан массив, размером в 8 элементов. В первом случае это будет массив int-ов, а во втором - массив bool-ов.\n");
Step_Add_Dialog_Continue ("Весь массив, в этом случае, будет заполнен <i>значениями типа по умолчанию</i>: для всех числовых типов (int, float, double, decimal) - это 0, а для bool-а - false.\n");
Step_Add_Dialog_Important ("<t>int</t>[] my_array = <instr>new</instr> <t>int</t>[8];");
Step_Add_Dialog ("Короче говоря, в данном примере, после инициализации, мы получаем массив размером в 8 элементов, забитый нулями.\n");
Step_Add_Dialog_Important_Continue ("\n<t>int</t> a = my_array[3];");
Step_Add_Dialog_Continue ("Чтобы получить n-ный элемент, просто указываем его индекс в скобках.\n");
Step_Add_Dialog_Important_Continue ("\n<c>BOT</c>.<m>Move</m>( my_array[5] );");
Step_Add_Dialog_Continue ("Как и переменную, элемент массива можно сразу использовать в аргументах функций и методов.\n");
Step_Add_Dialog_Important_Continue ("\n<c>BOT</c>.<m>Rotate</m>( my_array[5] * 2 );");
Step_Add_Dialog_Continue ("Также можно использовать элементы в арифметических выражениях (или, в случае с bool - в логических).\n");
Step_Add_Dialog_Important ("<t>int</t>[] my_array = <instr>new</instr> <t>int</t>[8];\n<t>int</t> a = 5;\n<t>int</t> b = my_array[a];");
Step_Add_Dialog ("Для доступа к n-ному элементу не обязательно использовать константу - подойдёт и другая переменная типа int. Эта особенность просто неоценимо полезна в циклах.");
Step_Add_Dialog_Important ("<t>int</t>[] my_array = <instr>new</instr> <t>int</t>[8];");
Step_Add_Dialog ("Однако - и это важно помнить - при инициализации, мы указываем <i>количество</i> элементов в массиве, но индексация начинается с нуля, поэтому самый последний элемент этого массива из 8и элементов - это my_array[7].\n");
Step_Add_Dialog_Continue ("Потому что у него есть элементы 0, 1, 2, 3, 4, 5, 6 и 7. А всего их получается 8, можете пересчитать, я подожду.\n");
Step_Add_Dialog_Continue ("Магия!\n");
Step_Add_Dialog ("При попытке обратиться к элементу с индексом 8, закономерно получим ошибку \"index was outside the bounds of the array\".\n");
Step_Add_Dialog_Important_Continue ("\nmy_array[0] = 42;\nmy_array[3] = 771;");
Step_Add_Dialog ("Несложно догадаться, что чтобы присвоить элементу какое-то значение, нужно не забыть указать его индекс.\n");
Step_Add_Dialog_Important_Continue ("\nmy_array = 321 <cmt>//This will throw an error;</cmt>");
Step_Add_Dialog_Continue ("Попытавшись присвоить что-нибудь не отдельному элементу массива, а самому массиву, мы получим ошибку типа \"can not implicitly convert int to int[]\", т.е. \"не могу преобразовать число в массив чисел, в самом деле, где это видано, совсем сдурели что ли?\" (вольный перевод - Р.О. Бот).\n");
Step_Add_Dialog ("Ну и посленее, что можно сказать про массивы - если очень хочется, можно присвоить всем элементам значения прямо во время инициализации.\n");
Step_Add_Dialog_Important ("<t>int</t>[] my_array_of_int = <instr>new</instr> <t>int</t>[4]{ 24, 72, 36, 52 };\n<t>bool</t>[] bool_arr = <instr>new</instr> <t>bool</t>[2]{ true, false };");
Step_Add_Dialog_Continue ("Для этого, после инициализации, в фигурных скобках указываем все элементы через запятую.\n");
Step_Add_Dialog_Continue ("Разумеется, их количество должно соответствовать указанному размеру массива. Иначе, что? Правильно - ошибка.\n");
Step_Add_Dialog ("Размер массива нельзя изменить после того как он инициализирован. Соответственно, добавить или удалить из него элементы не получится.\n");
Step_Add_Dialog_Important_Continue ("\nmy_array_of_int = <instr>new</instr> <t>int</t>[30];");
Step_Add_Dialog_Continue ("Его можно заново переинициализировать с новым размером, но все старые данные из него пропадут, т.к. это будет уже <i>новый</i> массив, о чём прозрачно намекает ключевое слово <i><instr>new</instr></i> при инициализации.\n");
Step_Add_Dialog ("Ну, вроде, информации достаточно. Поехали.\n");
Step_Add_Dialog_Hide ();
Step_Add_Check_Requirement ("Switch");
Step_Add_LevelComplete ("Level 1-7 - Массивы", "Level 001-07");
Step_Add_SetScript ("\nvoid Start () \n{\n\n\n\n\n\n\n\n\n}");
Step_Add_Dialog ("Хорошо. Значит тут у нас 27 индикаторов - 3х3х3.\n");
Step_Add_Dialog_Continue ("Как обычно, сначала нужно снять с них со всех показания. Затем, дёрнуть за главный рубильник, который заменит все индикаторы на рубильники, и, наконец, выставить свежепоявившиеся рубильники в состояние, соответствующих им индикаторов.\n");
Step_Add_Dialog ("Я стою на платформе, которая умеет меня телепортировать по нужным координатам с помощью метода <c>Platform</c>.<m>MoveTo</m>(<t>int</t> x, <t>int</t> y, <t>int</t> z);\n");
Step_Add_Dialog_Continue ("Доступные координаты - от 0,0,0 (правый-нижний-передний индикатор) до 2,2,2 (левый-верхний-задний)\n");
Step_Add_Dialog_Continue ("Плюс ещё надо будет портнуться на изначальную координату -1,1,1 что бы повернуть главный рубильник.\n");
Step_Add_Dialog ("В принципе, всё это не очень сложно сделать и с обычным массивом, но тут у нас вложенные циклы вырисовываются (ну, что бы перемещатся по координатам), а в них у нас не получится организовать счётчик от нуля до 26и.\n");
Step_Add_Dialog_Continue ("Вместо этого там получится три счётчика - от нуля до 2х каждый.\n");
Step_Add_Dialog ("Перевести три счётчика 0-2 в один 0-26 дело не хитрое: \"<t>int</t> counter = x*9 + y*3 + z;\". Но давайте попробуем решить эту задачу более удобным способом.\n");
Step_Add_Dialog ("Для таких случаем у нас есть многомерные массивы.\n");
Step_Add_Dialog_Continue ("Даже песня такая есть: \"Мно-го-мер-ны-е мас-си-вы, тум-да-да-да...\"\n");
Step_Add_Play_Sound (0, 0);
Step_Add_Wait (5F);
Step_Add_Restore_Music_Volume ();
Step_Add_Dialog_Continue ("Ну, почти попал...\n");
Step_Add_Dialog ("Так, что это вообще такое?\n");
Step_Add_Dialog_Continue ("Ну, если для обычного, одномерного массива, нам нужно указать одну циферку - индекс - что бы добраться до содержимого, то в двумерном нужно будет две циферки (два индекса).\n");
Step_Add_Dialog_Continue ("В трёх-мерном - три, в четырёх-мерном - четыре, и так далее.\n");
Step_Add_Dialog_Continue ("Нет предела количеству измерений у массива - есть лишь адекватность программиста.\n");
Step_Add_Dialog ("Вообще-то предел измерений есть - 32. Но это настолько до хрена, что в жизни ни кому никогда не понадобится.\n");
Step_Add_Dialog_Continue ("3х-мерные массивы уже встречаются довольно редко. 4х-мерные - <i>крайне</i> редко. А если у вас в программе используются 5и, и более -мерные, велика вероятность что вашей программе нужно пройти медосмотр и порефакториться...\n");
Step_Add_Dialog ("Если одномерный массив <t>int</t>[] - это ряд чисел, то двумерный можно представить как таблицу. Трёхмерный - как кубик. А четырёхмерный - как хороший способ сожрать всю память одной командой, и не подавится.\n");
Step_Add_Dialog_Continue ("На самом деле, четырёхмерный массив сложно визуализировать, но по сути это просто означает, что для доступа к его элементу, вам нужно указать четыре индекса.\n");
Step_Add_Dialog ("Объявляется многомерный массив так-же, как и одномерный, только в квадратных скобках ставятся запятые, соответствющие количеству измерений минус один.\n");
Step_Add_Dialog_Important ("<t>int</t>[,] array_2_dimensions;");
Step_Add_Dialog_Continue ("Т.е. <i>ноль</i> запятых для одномерного массива, одна запятая для двухмерного - как в примере ниже, \n");
Step_Add_Dialog_Important_Continue ("\n<t>int</t>[,,] array_3_dimensions;");
Step_Add_Dialog_Continue ("две - для трёх-мерного, три - для четырёхмерного, и т.д...\n");
Step_Add_Dialog_Important ("<t>int</t>[,] a = new int[2,3] { { 10, 0, 12 }, { 13, 45, 72 } };\n<cmt>//Получим следующее:</cmt>\n<cmt>//a[0,0] = 10, a[0,1] = 0, a[0,2] = 12</cmt>\n<cmt>//a[1,0] = 13, a[1,1] = 45, a[1,2] = 72</cmt>");
Step_Add_Dialog ("А вот так, можно заполнить многомерный массив значениями... можно я не буду это комментировать? Просто посмотрите на пример.\n");
Step_Add_Dialog_Continue ("Грубо говоря, заполняем сначала первый элемент певого измерения, затем второй его элемент.\n");
Step_Add_Dialog_Continue ("По аналогии с таблицей - сначала первую строчку, затем вторую. Где каждая из строчек - это три столбца (одномерный массив из 3х элементов).\n");
Step_Add_Dialog ("Схожим образом можно заполнить и трёх-мерный, и 10-и мерный, но уже на 3х мерном вы окончательно запутаетесь в этих фигурных скобках.\n");
Step_Add_SetScript ("\nvoid Start () \n{\n\n int[,,] arr = new int[5,9,14];\n for(int a=0; a<5; a++) {\n for(int b=0; b<9; b++) {\n for(int c=0; c<14; c++) {\n arr[a,b,c] = Random.Range(0, 500);\n }\n }\n }\n\n}");
Step_Add_Tutorial_Arrow_Show (-560F, 8F);
Step_Add_Dialog_Continue ("Такие массивы проще заполнять во вложенных циклах.\n");
Step_Add_Dialog ("Что-ж, пора рубить рубильники, а то они ждать устали.\n");
Step_Add_Dialog_Important ("<t>int</t>[,] arr1 = new int[2,3];\n<t>int</t>[,,] arr2 = new int[3,7,2];");
Step_Add_Tutorial_Arrow_Hide ();
Step_Add_Dialog_Hide ();
Step_Add_Check_Requirement ("Switch");
Step_Add_LevelComplete ("Level 1-7b - Массивы многомерные", "Level 001-07b");
Step_Add_SetScript ("\nvoid Start () \n{\n\n\n\n\n\n\n\n\n}");
Step_Add_Dialog ("В этом уровне против нас играет хитрый пол с картошкой.\n");
Step_Add_Dialog_Continue ("Каждый раз, когда скрипт запускается - конфигурация пола и количество картошки на нём изменяется.\n");
Step_Add_Dialog_Continue ("Всё что нужно сделать - это прочесать весь пол, собрать данные о количестве картошки на каждой клетке, и сообщить эту информацию терминалу.\n");
Step_Add_Dialog_Important ("<t>float</t> <c>BOT</c>.<m>GetFloorSquare</m>();");
Step_Add_Dialog ("Прочесать такой нестандартный пол, нам поможет знакомая функция GetFloorSquare().\n");
Step_Add_Dialog_Continue ("Напоминаю, что она возвращает площадь пола, на котором я стою. \n");
Step_Add_Dialog_Continue ("В данном случае, поскольку каждый фрагмент пола одного цвета - это отдельный пол, шириной в 1 метр, то по сути, данная функция вернёт <i>длинну</i> текущего отрезка пола.\n");
Step_Add_Dialog_Important_Continue ("\n<t>int</t> <c>BOT</c>.<m>CheckPotatoes</m>();");
Step_Add_Dialog_Continue ("А количество картошки на клетке подо мной, нам возвращает функция <c>BOT</c>.<m>CheckPotatoes</m>().\n");
Step_Add_Dialog ("Осталось, стало быть решить, как мы будем хранить информацию о количестве картошки.\n");
Step_Add_Dialog ("Всего отрезков пола 5 - это видно: зелёный, жёлтый, красный, синий... и ещё один зелёный - у дизайнера цвета кончились.\n");
Step_Add_Dialog_Continue ("Длинна каждого отрезка будет каждый раз разной.\n");
Step_Add_Dialog_Continue ("Можно было бы взять обычный двухмерный массив <t>int</t>[5,100] - что б с запасом. Не может же фрагмент пола быть длинной больше чем 100!\n");
Step_Add_Dialog_Continue ("Или может?...\n");
Step_Add_Dialog_Continue ("Да не, ерунда...\n");
Step_Add_Dialog ("Но есть проблема: здешний терминал хочет получить от нас в качестве ответа зубчатый массив, и никакой другой. На простой двухмерный массив он будет ругаться.\n");
Step_Add_Dialog_Continue ("Ну что, погнали?\n");
Step_Add_Dialog_Continue ("А, ну да, я ж забыл объяснить...\n");
Step_Add_Dialog ("Зубчатый массив (jagged array), это, по сути массив массивов.\n");
Step_Add_Dialog_Continue ("Т.е. одномерный массив, каждый элемент которого - это другой одномерный массив.\n");
Step_Add_Dialog_Continue ("Таким образом, мы получаем функционал такой же как и у двухмерного массива, но с той разницей, что в зубчатом массиве, каждая строка таблицы - если проводить аналогию с таблицей - может иметь разное количество столбцов.\n");
Step_Add_Dialog_Continue ("При больших объёмах данных это может сильно сэкономить объём используемой памяти.\n");
Step_Add_Dialog_Important ("<t>int</t>[][] arr;");
Step_Add_Dialog ("Объявляется такая штука вот таким образом. Также, как и обычный массив, только вместо одной пары квадратных скобок ставим две.\n");
Step_Add_Dialog_Continue ("Ну, или можно три - что бы получить 3х-мерный зубчатый массив. Можно пять, десять, двадцать - максимальный ранг ограничен реализацией .net framework, но до 32х можно вроде бы везде.\n");
Step_Add_Dialog_Continue ("В любом случае, это уже далеко за пределами нашей текущей задачи.\n");
Step_Add_Dialog ("А вот инициализировать такой массив уже хитрее, чем обычный.\n");
Step_Add_Dialog_Important ("<t>int</t>[][] arr = new <t>int</t>[3][];");
Step_Add_Dialog_Continue ("При объявлении, мы можем инициализировать только первое измерение - типа, количество строк в таблице.\n");
Step_Add_Dialog_Important_Continue ("\narr[0] = new <t>int</t>[3];\narr[1] = new <t>int</t>[17];\narr[2] = new <t>int</t>[9];");
Step_Add_Dialog_Continue ("Поскольку каждый элемент такого массива, это другой, независимый массив, и все элементы могут быть разного размера, то инициализировать каждый элемент нужно отдельно.\n");
Step_Add_Dialog_Important ("<t>int</t>[][] arr = new <t>int</t>[2][];\narr[0] = new <t>int</t>[4]{47,16,38,19};\narr[1] = new <t>int</t>[2]{91,37};");
Step_Add_Dialog ("Вот так можно сразу запихнуть в массив данные.\n");
Step_Add_Dialog_Important_Continue ("\n<t>int</t> x = arr[0][3];\narr[1][0] = 76;");
Step_Add_Dialog_Continue ("И вот так обратиться к отдельным элементам - в первых квадратных скобках указываем строку, во вторых - столбец.\n");
Step_Add_Dialog ("Вроде всё. Поехали!\n");
Step_Add_Dialog_Hide ();
Step_Add_Check_Requirement ("TERMINAL");
Step_Add_LevelComplete ("Level 1-7c - Массивы зубчатые", "Level 001-07c");
Step_Add_Dialog ("Ну вот и настало время твоего первого боя.\n");
Step_Add_Dialog_Continue ("Твой враг будет агрессивен и очень силён. От его шагов меркнет небо и армии разбегаются в страхе.\n");
Step_Add_Dialog_Continue ("Узри же, великого...");
Step_Add_Play_Sound (0, -1);
Step_Add_Wait (2F);
Step_Add_Play_Sound (1, -1);
Step_Add_Activate_Level_Object (0);
Step_Add_Dialog ("Окей, это просто бомба.");
Step_Add_Dialog ("К сожалению, чтобы пройти дальше, её, таки, придётся уничтожить.");
Step_Add_Dialog ("Итак, особенности бомбы:\n");
Step_Add_Dialog ("- Фигачить бомбу, как и любого врага, можно методом <c>BOT</c>.<m>Fight</m>(). Для этого, нужно стоять на клетке перед врагом и быть направленным в его сторону.\n");
Step_Add_Dialog_Continue ("- Количество единиц здоровья бомбы заранее не известно (каждый раз, когда скрипт запускается - оно меняется).\n");
Step_Add_Dialog_Continue ("- Когда у бомбы заканчивается здоровье, она немного ждёт и делает БУМ.\n");
Step_Add_Dialog_Continue ("- В момент бума, лучше не стоять рядом с ней. Все роботы, в радиусе трёх клеток от БУМкающей бомбы, трагически погибают.\n");
Step_Add_Dialog_Important ("<instr>while</instr> ( <color=\"#A0A0ffff\">true</color> )");
Step_Add_Dialog ("Предлагаю сделать беcконечный цикл, в теле которого - фигачить бомбу и проверять её здоровье.");
Step_Add_Dialog_Important_Continue ("\n{\n <cmt>//фигачить бомбу и проверять здоровье;</cmt>\n <instr>if</instr> (здоровье ≺= 0) { <instr>break</instr>; }\n}");
Step_Add_Dialog ("В момент, когда её здоровье станет меньше или равно нулю - выйти из цикла, и свалить.\n");
Step_Add_Dialog_Continue ("Для выхода из цикла есть команда <instr>break</instr>.\n");
Step_Add_Dialog_Continue ("Проблема, стало быть, лишь в том, чтобы узнать здоровье бомбы.");
Step_Add_Dialog ("Тут поможет функция <c>BOT</c>.<m>GetClosestEnemyInfo</m>() - она возвращает информацию о ближайшем враге.\n");
Step_Add_Dialog_Continue ("Тип возвращаемого этой функцией значения - это структура EnemyInfo.\n");
Step_Add_Dialog_Important ("<t>struct</t> <c>EnemyInfo</c> {\n <t>int</t> HP; <cmt>//Здоровье</cmt>\n <t>int</t> EP; <cmt>//Заряд</cmt>\n <t>float</t> pos_x <cmt>//координата врага x на поле</cmt>\n <t>float</t> pos_y <cmt>//координата врага y на поле</cmt>\n}");
Step_Add_Dialog_Continue ("Структура - это всего лишь несколько переменных объединённых в одну.\n");
Step_Add_Dialog ("Как видно из объявления, в структуре есть здоровье врага. И хранится оно в переменной HP типа int.");
Step_Add_Dialog_Important ("<c>EnemyInfo</c> en = <c>BOT</c>.<m>GetClosestEnemyInfo</m>();\n<t>int</t> health = en.HP;");
Step_Add_Dialog ("Пользоваться этим можно так: \n- объявляем переменную типа EnemyInfo, присваиваем ей информацию о текущем враге, а чтобы узнать здоровье, обращаемся к нужной переменной структуры через точку.\n");
Step_Add_Dialog_Important_Continue ("\n\n<cmt>//или так</cmt>\n<t>int</t> health = <c>BOT</c>.<m>GetClosestEnemyInfo</m>().HP;");
Step_Add_Dialog_Continue ("Ну, или, если вся структура не нужна, можно сразу запросить здоровье из функции, без промежуточной переменной. Также, через точку.");
Step_Add_Dialog ("Если использовать первый способ, то можно подумать, что достаточно получить структуру EnemyInfo вне цикла, а в теле цикла лишь проверять en.HP. Но это не сработает.\n");
Step_Add_Dialog_Continue ("Цифры в полученной структуре сами по себе менятся не будут. Соответственно условие en.HP ≺= 0 не сработает никогда, и я буду вечно дубасить бомбу, пока она меня не взорвёт.");
Step_Add_Dialog ("Чтобы обновить структуру, нужно её переполучить с помощью GetClosestEnemyInfo(), которая вернёт актуальную структуру на момент выполнения команды.\n");
Step_Add_Dialog_Continue ("Ну, или просто воспользоватся вторым способом.");
Step_Add_Dialog ("Вперёд!");
Step_Add_Dialog_Hide ();
Step_Add_Check_Requirement ("ScriptStopped && noenemyleft");
Step_Add_LevelComplete ("Level 1-8 - Structures - First Battle.", "Level 001-08");
Step_Add_SetScript ("\nvoid Start () \n{\n\n\n\n\n\n\n\n\n}");
Step_Add_Dialog ("Ой, сколько бомб...\n");
Step_Add_Dialog_Continue ("Ну, в целом, ничего нового.\n");
Step_Add_Dialog_Continue ("Ездим, разминируем, любуемся пейзажем...\n");
Step_Add_Dialog_Continue ("В цикле это сделать не получится, потому что ехать нужно каждый раз в разное место, и этот код не получится зациклить.\n");
Step_Add_Dialog_Continue ("В итоге, тут получится довольно много кода. Причём та часть, в которой мы дубасим бомбу, пока она не загорится, будет повторена 4 раза, в абсолютно одинаковом виде.\n");
Step_Add_Dialog_Continue ("Нехорошо.");
Step_Add_Dialog ("Ты знаешь, ты можешь писать свои методы и функции. Они помогают избавится от повторений одинакового кода.\n");
Step_Add_Dialog_Continue ("До сих пор, весь код ты тоже писал внутри функции. Это функция Start().\n");
Step_Add_Tutorial_Arrow_Show (-560F, 1F);
Step_Add_Dialog_Continue ("Вот это - её определение.");
Step_Add_Dialog ("Ключевое слово \"void\" означает, что функция ничего не возвращает, т.е. является методом.\n");
Step_Add_Dialog_Continue ("Пустые скобки означают, что у функции нет параметров.\n");
Step_Add_Tutorial_RedPanel_Show (0F, 3F, 100F, 10F);
Step_Add_Dialog_Continue ("Ну, а дальше, между фигурных скобок, собственно, идёт тело функции, т.е. код, который выполняется при её вызове.");
Step_Add_Tutorial_Arrow_Hide ();
Step_Add_Dialog ("Функция Start() вызывается автоматически, при запуске скрипта. Это, так называемый, EntryPoint - место, с которого начинает выполнятся программа, при её запуске.\n");
Step_Add_SetScript ("\nvoid Start () \n{\n\n\n\n\n\n\n\n\n}\n\nvoid KillBomb() \n{\n\n\n\n\n\n\n}");
Step_Add_Tutorial_RedPanel_Hide ();
Step_Add_Tutorial_Arrow_Show (-560F, 13F);
Step_Add_Dialog_Continue ("Но, никто не мешает, по образу данной функции, создать свою. Скажем KillBomb().");
Step_Add_SetScript ("\nvoid Start () \n{\n\n\n\n\n\n\n\n\n}\n\nvoid KillBomb() \n{\n while (true)\n {\n BOT.Fight();\n //Get bomb HP somehow\n if (HP <= 0) { break; }\n }\n}");
Step_Add_Dialog ("Внутрь мы запихнём код, который будет взрывать бомбу.\n");
Step_Add_Tutorial_Arrow_Show (-560F, 4F);
Step_Add_SetScript ("\nvoid Start () \n{\n //Go to bomb\n KillBomb(); //This call our function and kill the bomb\n\n\n\n\n\n\n}\n\nvoid KillBomb() \n{\n while (true)\n {\n BOT.Fight();\n //Get bomb HP somehow\n if (HP <= 0) { break; }\n }\n}");
Step_Add_Dialog_Continue ("В основном же коде, нам останется только подойти к бомбе, и вызвать нашу новую функцию.\n");
Step_Add_SetScript ("\nvoid Start () \n{\n //Go to bomb 1\n KillBomb(); //This call our function and kill the bomb\n //Go to bomb 2\n KillBomb();\n //Go to bomb 3\n KillBomb();\n //Go to bomb 4\n KillBomb();\n}\n\nvoid KillBomb() \n{\n while (true)\n {\n BOT.Fight();\n //Get bomb HP somehow\n if (HP <= 0) { break; }\n }\n}");
Step_Add_Dialog_Continue ("И повторить четыре раза.\n");
Step_Add_SetScript ("\nvoid Start () \n{\n\n\n\n\n}");
Step_Add_Tutorial_Arrow_Hide ();
Step_Add_Dialog_Continue ("Попробуй.");
Step_Add_Dialog_Hide ();
Step_Add_Check_Requirement ("ScriptStopped && noenemyleft");
Step_Add_LevelComplete ("Level 1-9 - Functions.", "Level 001-09");
Step_Add_SetScript ("\nvoid Start () \n{\n\n\n\n\n\n\n\n\n}");
Step_Add_Dialog ("Лежебоке Лодыревне Спать, менеджеру отдела по развитию коррупции, активистке, атеистке, феминистке, арфистке, химчистке и просто, хорошему человеку, приходит на почту много спама.\n");
Step_Add_Dialog_Continue ("Она попросила помочь обработать почту в целом, и отфильтровать спам в частности.\n");
Step_Add_Dialog ("Почта будет выдаваться с помощью уже знакомого терминала.\n");
Step_Add_Dialog_Continue ("Терминал выдаст 10 рандомных е-мейлов, которые надо будет обработать.\n");
Step_Add_Dialog ("Забираем из терминала структуру с помощью <t>var</t> data = <c>BOT</c>.<m>Terminal_Read</m>();\n");
Step_Add_Dialog_Continue ("Вытаскиваем из неё письмо: <t>string</t> mail = data.str;\n");
Step_Add_Dialog_Continue ("Обрабатываем это письмо, и отвечаем терминалу с помощью <c>BOT</c>.<m>Terminal_Answer</m>(<t>string</t>[] parsed_mail);\n");
Step_Add_Dialog_Continue ("(Да, в этот раз нужно будет отвечать терминалу массивом <t>string</t>[] из двух элементов, что в них должно быть - я объясню).\n");
Step_Add_Dialog_Continue ("И всё вот это вот, нужно сделать в цикле 10 раз. Но не заморачивайтесь - вот темплейт.\n");
Step_Add_SetScript ("\nvoid Start ()\n{\n for (int i = 0; i < 10; i++) {\n var d = BOT.Terminal_Read();\n string mail = d.str;\n string[] parsed_mail = new string[2]{};\n\n //Insert you code here\n\n\n\n BOT.Terminal_Answer(parsed_mail);\n }\n}\n");
Step_Add_Dialog ("В темплейт уже вписаны обращения к терминалу, и получение е-мейла в переменную <t>string</t> mail;\n");
Step_Add_Dialog_Continue ("А так-же ответ, массивом <t>string</t>[] parsed_mail.\n");
Step_Add_Dialog_Continue ("Вам нужно только обработать переменную \"mail\" и поместить в \"parsed_mail\".\n");
Step_Add_Dialog ("Краткое содержание того, что, собственно, нужно сделать с письмом:\n");
Step_Add_Dialog_Continue ("- 1. Надо создать заголовок письма - это должны быть первые 140 символов и три точки если письмо длинее 140 символов, или всё письмо если оно короче.\n");
Step_Add_Dialog_Continue ("- 2. Если имя или отчество Лежебоки Лодыревны начинается с маленькой буквы - заменить её на заглавную (Лежебока Лодыревна отключается, если видит своё имя/фамилию с маленькой буквы).\n");
Step_Add_Dialog ("- 3. Нужно отфильровать почту на спам - пометить спамом все письма, содержащие 'вы выиграли' или 'одобрен кредит'. Если содержит - добавить перед заголовком строку <str>\"(СПАМ) \"</str>.\n");
Step_Add_Dialog_Continue ("- 4. Заменяем все \"а\" на \"о\" а \"о\" на \"а\" (Лежебока Лодыревна человек своеобразный, и ей так легче читать).\n");
Step_Add_SetScript ("\nvoid Start ()\n{\n for (int i = 0; i < 10; i++) {\n var d = BOT.Terminal_Read();\n string mail = d.str;\n string[] parsed_mail = new string[2]{};\n\n //1. Надо создать заголовок письма - это должны быть первые 140 символов и три точки (\"...\") если письмо длинее 140 символов, или всё письмо если оно короче.\n //2. Если имя или отчество Лежебоки Лодыревны начинается с маленькой буквы - заменить её на заглавную (Лежебока Лодыревна отключается, если видит своё имя/фамилию с маленькой буквы).\n //3. Нужно отфильровать почту на спам - пометить спамом все письма, содержащие 'вы выиграли' или 'одобрен кредит'. Если содержит - добавить перед заголовком строку \"(СПАМ) \".\n //4. Заменяем все \"а\" на \"о\" а \"о\" на \"а\".\n\n //Insert you code here\n\n\n\n BOT.Terminal_Answer(parsed_mail);\n }\n}\n");
Step_Add_Dialog ("Вот вам все задания комментариями в темплейт.\n");
Step_Add_Dialog_Continue ("А теперь - главное: как это всё вообще делать.\n");
Step_Add_Dialog ("Я уже упоминал, что тип string - это вообще-то класс. А это значит, что у него есть свои методы и функции.\n");
Step_Add_Dialog_Continue ("(Для справки: остальные простые типы - всякие int, decimal и т.д. - это структуры, которые, в принципе, не так уж сильно от классов отличаются, и тоже имеют свои методы и функции, но они не прикольные).\n");
Step_Add_Dialog_Important ("<t>string</t> greeting = <str>\"Привет, я - БОТ.\"</str>;");
Step_Add_Dialog ("Объявляя переменную типа <t>string</t>, и присваивая ей значение, вы создаёте <i>экземпляр</i> (instance) класса <t>string</t>, и можете обращаться к его методам через эту переменную.\n");
Step_Add_Dialog_Important_Continue ("\ngreeting.<m>Replace</m>(<str>\"я\"</str>, <str>\"ы\"</str>);");
Step_Add_Dialog_Continue ("Например, у класса <t>string</t> есть функция <m>Replace</m>, которая заменяет в строке одну букву (или слово), на другую букву (или слово).\n");
Step_Add_Dialog ("Осторожно - подстава!\n");
Step_Add_Dialog_Continue ("Все вот эти функции (как и вообще любые функции), <i>возвращают</i> результат своей работы, но не меняют исходную переменную. То есть, после выполнения кода ниже - переменная \"greeting\" не изменится!\n");
Step_Add_Dialog_Important_Continue (" <cmt>//безполезный вызов</cmt>");
Step_Add_Dialog_Continue ("По сути, после выполнения такого кода, вообще ничего не изменится - функция вернёт результат, но он уйдёт в никуда.\n");
Step_Add_Dialog_Important_Continue ("\ngreeting = greeting.<m>Replace</m>(<str>\"я\"</str>, <str>\"ы\"</str>);\n<cmt>//в greeting теперь лежит - \"Привет, <i>ы</i> - БОТ.\"</cmt>");
Step_Add_Dialog_Continue ("Что бы реально заменить все <str>\"я\"</str> на <str>\"ы\"</str> в исходной строке, присваиваем результат функции обратно нашей переменной.\n");
Step_Add_Dialog ("Думаю тут понятно, что и первым (что меняем) и вторым (на что меняем) аргументом, может быть и буква, и символ, и набор букв или символов, и всё в перемешку... короче, любая валидная строка или другая переменная типа <t>string</t>.\n");
Step_Add_Dialog_Important ("<t>string</t> greeting = <str>\"Привет, я - БОТ.\"</str>;\ngreeting = greeting.<m>Replace</m>(<str>\"Привет\"</str>, <str>\"\"</str>);\n<cmt>//в greeting теперт лежит - \", я - БОТ.\"</cmt>");
Step_Add_Dialog_Continue ("Вторым аргументом может даже быть пустая строка, тогда результатом будет полное уничтожение найденных подстрок в исходной строке.\n");
Step_Add_Dialog_Important ("<t>string</t> t = <str>\"Привет, я - БОТ.\"</str>;");
Step_Add_Dialog ("Коротко о других функциях класса <t>string</t> (готовтесь, их не мало, но они все простые).\n");
Step_Add_Dialog_Important_Continue ("\n<t>string</t> t1 = t.<m>ToLower()</m>; <cmt>//\"привет, я - бот.\"</cmt>");
Step_Add_Dialog_Continue ("- <t>string</t> <m>ToLower</m>() - возвращает исходную строку в нижнем регистре.\n");
Step_Add_Dialog_Important_Continue ("\n<t>string</t> t2 = t.<m>ToUpper()</m>; <cmt>//\"ПРИВЕТ, Я - БОТ.\"</cmt>");
Step_Add_Dialog_Continue ("- <t>string</t> <m>ToUpper</m>() - возвращает исходную строку в верхнем регистре.\n");
Step_Add_Dialog_Important ("<t>string</t> t = <str>\"Привет, я - БОТ.\"</str>;\n<t>bool</t> b1 = t.<m>Contains</m>(<str>\",\"</str>); <cmt>//true</cmt>\n<t>bool</t> b2 = t.<m>Contains</m>(<str>\"Привет\"</str>); <cmt>//true</cmt>\n<t>bool</t> b3 = t.<m>Contains</m>(<str>\"к\"</str>); <cmt>//false</cmt>");
Step_Add_Dialog ("- <t>bool</t> <m>Contains</m>(<t>string</t> substring) - возвращает <t>bool</t>, содержится-ли указанная первым аргументом подстрока в исходной строке.\n");
Step_Add_Dialog_Important ("<t>string</t> t = <str>\"Привет, я - БОТ.\"</str>;\n<t>string</t> t1 = t.<m>Substring</m>(3); <cmt>//\"вет, я - БОТ.\"</cmt>\n<t>string</t> t2 = t.<m>Substring</m>(10); <cmt>//\"- БОТ.\"</cmt>");
Step_Add_Dialog ("- <t>string</t> <m>Substring</m>(<t>int</t> index) - возвращает подстроку, начиная с позиции <i>index</i> (индексация начинается с нуля, т.е. первый символ, на самом деле нулевой).\n");
Step_Add_Dialog_Important_Continue ("\n<t>string</t> t3 = t.<m>Substring</m>(2, 5); <cmt>//\"ивет,\"</cmt>");
Step_Add_Dialog_Continue ("- <t>string</t> <m>Substring</m>(<t>int</t> index, <t>int</t> count) - перегрузка функции <m>Substring</m> с двумя аргументами типа <t>int</t>. Возвращает некоторое количество (<i>count</i>) символов, начиная с позиции <i>index</i>. В примере, мы получили 5 символов, начиная с похиции 2.\n");
Step_Add_Dialog_Important ("<t>string</t> t = <str>\"Привет, я - БОТ.\"</str>;\n<t>int</t> i = t.<m>Length</m>; <cmt>//16</cmt>");
Step_Add_Dialog ("Ну, и на конец, свойство Length. Возвращает просто количество символов в строке.\n");
Step_Add_Dialog_Continue ("Его фишка в том, что оно не функция. Оно - свойство. С такими зверями мы ещё не сталкивались.\n");
Step_Add_Dialog_Continue ("Ну, с точки зрения использования, свойство отличается от функции только тем, что у свойства нет никаких аргументов, стало быть и никакие скобки указывать не надо.\n");
Step_Add_Dialog ("Как запомнить, где свойство, а где функция?\n");
Step_Add_Dialog_Continue ("А вот никак. Бугагагага.\n");
Step_Add_Dialog_Continue ("Нет, серьёзно. К сожалению, это можно только либо запомнить, либо каждый раз лезть в бот-о-педию.\n");
Step_Add_Dialog_Continue ("В будущем, подсказка кода вам будет говорить, что свойство а что функция, но пока только так...\n");
Step_Add_Dialog ("Возвращаемся к заданиям, и попробуем разобратся как их решать.\n");
Step_Add_Dialog_Continue ("Отдавать терминалу надо массив <t>string</t> из двух элементов, где первый элемент будет заголовком письма, а второй - самим письмом.\n");
Step_Add_Dialog ("1. Надо создать заголовок письма - это должны быть первые 140 символов и три точки если письмо длинее 140 символов, или всё письмо если оно короче.\n");
Step_Add_Dialog_Continue ("С помощью свойства <m>Length</m> узнаём количество букв в письме, и если получилось меньше чем 141, суём в заголовок (первый элемент результирующего массива) всё письмо. А если больше - то с помощью функции <m>Substring</m> отдираем от письма первые 140 символов, добавляем к ним \"...\", и то что получилось так-же суём в заголовок.\n");
Step_Add_Dialog ("2. Если имя или отчество Лежебоки Лодыревны начинается с маленькой буквы - заменить её на заглавную.\n");
Step_Add_Dialog_Continue ("Тупо, с помощью <m>Replace</m> заменяем <str>\"<b>л</b>ежебока\"</str> на <str>\"<b>Л</b>ежебока\"</str>.\n");
Step_Add_Dialog_Continue ("Однако, это не проконает, если имя будет указано в другом падеже (<str>лежебоке</str>, например).\n");
Step_Add_Dialog_Continue ("Не проблема - заменим не <str>\"лежебок<b>а</b>\"</str>, а <str>\"лежебо<b>к</b>\"</str>. Такая замена должна сработать с любым падежом.\n");
Step_Add_Dialog_Continue ("Ну, и так-же с отчеством.\n");
Step_Add_Dialog ("3. Нужно отфильровать почту на спам - если письмо содержит 'вы выиграли' или 'одобрен кредит', то добавить перед заголовком строку <str>\"(СПАМ) \"</str>.\n");
Step_Add_Dialog_Continue ("С помощью <m>Contains</m> узнаём, есть ли в письме указанные подстроки. И если есть - с помощью конкатенации изменяем заголовок указанным образом.\n");
Step_Add_Dialog ("Но есть ньюанс: <m>Contains</m> (как и <m>Replace</m>, кстати) - регистрозависим, и <m>Contains</m>(<str>\"вы выиграли\"</str>) не обнаружит строку <str>\"Вы выиграли\"</str>, из-за заглавной буквы.\n");
Step_Add_Dialog_Continue ("Тоже не проблема - достаточно перед проверкой, всё письмо перевести в нижний регистр с помощью функции <m>ToLower</m>().\n");
Step_Add_Dialog_Continue ("Только не запихивайте результат обратно в письмо, т.к. само письмо нам нужно в правильном регистре. Используйте для этого временную переменную.\n");
Step_Add_Dialog ("4. Заменяем все \"а\" на \"о\" а \"о\" на \"а\"\n");
Step_Add_Dialog_Continue ("Если, при помощи <m>Replace</m>, сначала заменить <str>\"а\"</str> на <str>\"о\"</str>, а затем <str>\"о\"</str> на <str>\"а\"</str>, то во втором шаге будут заменены все буквы \"о\", включая те, которые вы получили на первом шаге.\n");
Step_Add_Dialog_Continue ("А это не то, что имеется в виду в задании.\n");
Step_Add_Dialog_Continue ("Простой workaround - заменить сначала все <str>\"а\"</str> на какую ни-будь кракозябру, которая точно не должна встретится в письме (что-то типа <str>\"ъыъ$@@#?#@@$щёщ\"</str>, или, не знаю... придумайте что ни будь).\n");
Step_Add_Dialog_Continue ("Затем, меняем <str>\"о\"</str> на <str>\"а\"</str>, и, наконец, третим шагом, меняем обратно кракозябру на <str>\"о\"</str>.\n");
Step_Add_Dialog ("Не то, что б это прям идеальный способ, т.к. никогда не знаешь, какие кракозябры могут попасться в письмах... Тут, главное, придумать кракозябру, которая там попадётся с наименьшей вероятностью.\n");
Step_Add_Dialog ("Что ж, поехали. Удачи!\n");
Step_Add_Dialog_Hide ();
Step_Add_Check_Requirement ("TERMINAL");
Step_Add_LevelComplete ("Level 1-10 - class string.", "Level 001-10");
// Step_Add_SetScript ("\nvoid Start () \n{\n\n\n\n\n\n\n\n\n}");
// Step_Add_Dialog ("aaaaaa");
// Step_Add_Dialog ("aaaaaa");
// Step_Add_Dialog ("aaaaaa");
// Step_Add_Check_Requirement ("ScriptStopped && noenemyleft");
// Step_Add_LevelComplete("Level 1-11 - Float - Second Enemy.", "Level 001-11");
// Step_Add_SetScript ("\nvoid Start () \n{\n\n\n\n\n\n\n\n\n}");
// Step_Add_Dialog ("aaaaaa");
// Step_Add_Dialog ("aaaaaa");
// Step_Add_Dialog ("aaaaaa");
// Step_Add_Check_Requirement ("ScriptStopped && noenemyleft");
// Step_Add_LevelComplete("Level 1-12 - Algorithmes - The Maze.", "Level 001-12");
// Step_Add_SetScript ("\nvoid Start () \n{\n\n\n\n\n\n\n\n\n}");
// Step_Add_Dialog ("bbbbbb");
// Step_Add_Dialog ("bbbbbb");
// Step_Add_Dialog ("bbbbbb");
// Step_Add_Check_Requirement ("ScriptStopped && noenemyleft");
// Step_Add_LevelComplete("Level 1-13 - Classes - Ball sorting.", "Level 001-13");
// Step_Add_SetScript ("\nvoid Start () \n{\n\n\n\n\n\n\n\n\n}");
// Step_Add_Dialog ("tttttt");
// Step_Add_Dialog ("tttttt");
// Step_Add_Dialog ("tttttt");
// Step_Add_LevelComplete("Level 1-14 - Test Video Background.", "Level 001-14");
// Step_Add_SetScript ("\nvoid Start () \n{\n\n\n\n\n\n\n\n\n}");
// Step_Add_Dialog ("tttttt");
// Step_Add_Dialog ("tttttt");
// Step_Add_Dialog ("tttttt");
// Step_Add_LevelComplete("Level 1-15 - Test Falling Cubes.", "Level 001-15");
// Step_Add_SetScript ("\nvoid Start () \n{\n\n\n\n\n\n\n\n\n}");
// Step_Add_Dialog ("tttttt");
// Step_Add_Dialog ("tttttt");
// Step_Add_Dialog ("tttttt");
// Step_Add_LevelComplete("Level 1-16 - Reactor Room", "Level Reactor Room");
Step_Add_Dialog_Hide ();
Step_Add_Dialog_Important_Hide();
Step_Add_ScriptControls_Hide ();
Step_Add_Check_Requirement ("ETERNAL");
Step_Add_LevelComplete("Level Chapter Complete", "Level Chapter Complete");
#endregion
//Set fast_forward info
int level_index = 0;
for (int ind = 0; ind < steps.Count; ind++) {
if (steps[ind].step_type == step_type.dialog) {
while (steps_for_fastForward.Count <= level_index) { steps_for_fastForward.Add(new List<KeyValuePair<string, int>>()); }
var level_fast_forward = steps_for_fastForward[level_index];
level_fast_forward.Add( new KeyValuePair<string, int>(steps[ind].str_param1, ind) );
}
else if (steps[ind].step_type == step_type.level_complete_show) { level_index++; }
}
Engine.Level_step_indices.RemoveAt(Engine.Level_step_indices.Count-1);
}
#region Add_Step_xxx functions
public static void Step_Add_Pause () {
step_info t = new step_info();
t.step_type = step_type.pause; steps.Add(t);
}
public static void Step_Add_Resume () {
step_info t = new step_info();
t.step_type = step_type.resume; steps.Add(t);
}
public static void Step_Add_Dialog (string str, int breakAt = -1, int from = 0) {
step_info t = new step_info();
//t.step_type = step_type.dialog; t.str_param1 = Code_HighLight(str); t.int_param1 = breakAt; t.int_param2 = from; steps.Add(t);
t.step_type = step_type.dialog; t.str_param1 = str; t.int_param1 = breakAt; t.int_param2 = from; steps.Add(t);
}
public static void Step_Add_Dialog_Continue (string str, int breakAt = -1) {
step_info t = new step_info();
//t.step_type = step_type.dialog_continue; t.str_param1 = Code_HighLight(str); t.int_param1 = breakAt; steps.Add(t);
t.step_type = step_type.dialog_continue; t.str_param1 = str; t.int_param1 = breakAt; steps.Add(t);
}
public static void Step_Add_Dialog_Show () {
step_info t = new step_info();
t.step_type = step_type.dialog_show; steps.Add(t);
}
public static void Step_Add_Dialog_Hide () {
step_info t = new step_info();
t.step_type = step_type.dialog_hide; steps.Add(t);
}
public static void Step_Add_Dialog_Important (string str, int breakAt = -1, int from = 0) {
step_info t = new step_info();
//t.step_type = step_type.dialog_important; t.str_param1 = Code_HighLight(str); t.int_param1 = breakAt; t.int_param2 = from; steps.Add(t);
t.step_type = step_type.dialog_important; t.str_param1 = str; t.int_param1 = breakAt; t.int_param2 = from; steps.Add(t);
}
public static void Step_Add_Dialog_Important_Continue (string str, int breakAt = -1) {
step_info t = new step_info();
//t.step_type = step_type.dialog_important_continue; t.str_param1 = Code_HighLight(str); t.int_param1 = breakAt; steps.Add(t);
t.step_type = step_type.dialog_important_continue; t.str_param1 = str; t.int_param1 = breakAt; steps.Add(t);
}
public static void Step_Add_Dialog_Important_Hide () {
step_info t = new step_info();
t.step_type = step_type.dialog_important_hide; steps.Add(t);
}
public static void Step_Add_SetScript (string str) {
step_info t = new step_info();
t.step_type = step_type.setScript; t.str_param1 = str; steps.Add(t);
}
public static void Step_Add_Tutorial_Arrow_Show (float f1, float f2) {
step_info t = new step_info();
t.step_type = step_type.tutorialArrow_Show; t.float_param1 = f1; t.float_param2 = f2; steps.Add(t);
}
public static void Step_Add_Tutorial_Arrow_Hide () {
step_info t = new step_info();
t.step_type = step_type.tutorialArrow_Hide; steps.Add(t);
}
public static void Step_Add_Tutorial_RedPanel_Show (float f1, float f2, float f3, float f4) {
step_info t = new step_info();
t.step_type = step_type.tutorialRedPanel_Show;
t.float_param1 = f1; t.float_param2 = f2; t.float_param3 = f3; t.float_param4 = f4; steps.Add(t);
}
public static void Step_Add_Tutorial_RedPanel_Hide () {
step_info t = new step_info();
t.step_type = step_type.tutorialRedPanel_Hide; steps.Add(t);
}
public static void Step_Add_Check_Requirement (string str) {
step_info t = new step_info();
t.step_type = step_type.check_Requirement; t.str_param1 = str; steps.Add(t);
}
public static void Step_Add_LevelComplete (string name, string obj_name) {
Engine.Level_names.Add(name);
Engine.Level_obj_names.Add(obj_name);
step_info t = new step_info();
t.step_type = step_type.level_complete_show; steps.Add(t);
Engine.Level_step_indices.Add(steps.Count);
}
// public static void Step_Add_LevelComplete_Hide () {
// step_info t = new step_info();
// t.step_type = step_type.level_complete_hide; steps.Add(t);
// }
public static void Step_Add_ScriptControls_Show () {
step_info t = new step_info();
t.step_type = step_type.script_controls_show; steps.Add(t);
}
public static void Step_Add_ScriptControls_Hide () {
step_info t = new step_info();
t.step_type = step_type.script_controls_hide; steps.Add(t);
}
public static void Step_Add_Skip_Bot_Rebase_Anim () {
step_info t = new step_info();
t.step_type = step_type.skip_bot_rebase_anim; steps.Add(t);
}
public static void Step_Add_Set_Blocked_Instructions (string str) {
step_info t = new step_info();
t.str_param1 = str;
t.step_type = step_type.set_blocked_instructions; steps.Add(t);
}
public static void Step_Add_Activate_Level_Object (int i) {
step_info t = new step_info();
t.int_param1 = i;
t.step_type = step_type.activate_object; steps.Add(t);
}
public static void Step_Add_Play_Sound (int i, int fade_music = -1) {
step_info t = new step_info();
t.int_param1 = i; t.int_param2 = fade_music;
t.step_type = step_type.play_sound; steps.Add(t);
}
public static void Step_Add_Restore_Music_Volume () {
step_info t = new step_info();
t.step_type = step_type.restore_music_volume; steps.Add(t);
}
public static void Step_Add_Wait (float f) {
step_info t = new step_info();
t.float_param1 = f;
t.step_type = step_type.wait; steps.Add(t);
}
#endregion
public static string Code_HighLight(string str, Engine.higlight_colors_info? colors = null) {
if (colors == null) { colors = Engine.higlight_colors; }
str = str.Replace("<n>", "<color=\"#" + ColorUtility.ToHtmlStringRGB(colors.Value.nmsp) + "\">");
str = str.Replace("<c>", "<color=\"#" + ColorUtility.ToHtmlStringRGB(colors.Value.cls) + "\">");
str = str.Replace("<m>", "<color=\"#" + ColorUtility.ToHtmlStringRGB(colors.Value.method) + "\">");
str = str.Replace("<t>", "<color=\"#" + ColorUtility.ToHtmlStringRGB(colors.Value.built_in_types) + "\">");
str = str.Replace("<str>", "<color=\"#" + ColorUtility.ToHtmlStringRGB(colors.Value.str) + "\">");
str = str.Replace("<cmt>", "<color=\"#" + ColorUtility.ToHtmlStringRGB(colors.Value.comments) + "\">");
str = str.Replace("<instr>", "<color=\"#" + ColorUtility.ToHtmlStringRGB(colors.Value.instruction) + "\">");
str = str.Replace("</n>", "</color>"); str = str.Replace("</c>", "</color>"); str = str.Replace("</m>", "</color>");
str = str.Replace("</t>", "</color>"); str = str.Replace("</str>", "</color>"); str = str.Replace("</cmt>", "</color>");
str = str.Replace("</instr>", "</color>");
return str;
//if (str.Contains("<color")) return str;
// var matches = quotes.Matches(str);
// foreach (Match m in matches) {
// }
// matches = class_and_method.Matches(str);
// for (int i = matches.Count - 1; i >=0; i-- ) {
// Match m = matches[i];
// if (!m.Groups[i].Success) continue;
// string[] chain_arr = m.Groups[1].Value.Split(new char[]{'.'});
// chain_arr[chain_arr.Length-1] = "<color=\"#" + ColorUtility.ToHtmlStringRGB(colors.method) + "\">" + chain_arr[chain_arr.Length-1] + "</color>";
// if (chain_arr.Length > 1) {
// chain_arr[chain_arr.Length-2] = "<color=\"#" + ColorUtility.ToHtmlStringRGB(colors.cls) + "\">" + chain_arr[0] + "</color>";
// }
// if (chain_arr.Length > 2) {
// for (int x = chain_arr.Length-1; x >= 2; x--){
// chain_arr[x] = "<color=\"#" + ColorUtility.ToHtmlStringRGB(colors.nmsp) + "\">" + chain_arr[x] + "</color>";
// }
// }
// str = str.Remove(m.Groups[1].Index, m.Groups[1].Length);
// str = str.Insert(m.Groups[1].Index, string.Join(".", chain_arr));
// }
}
public static void Convert_Generated_Script() {
System.Globalization.NumberFormatInfo nfi = new System.Globalization.NumberFormatInfo(); nfi.NumberDecimalSeparator = ".";
var file_text = System.IO.File.ReadAllText(Application.dataPath + "/../Generated_Script.txt");
var text_arr = file_text.Split(new string[]{"\r\n"}, System.StringSplitOptions.RemoveEmptyEntries);
string str = "";
foreach (string line in text_arr) {
if (line.Length < 34) continue;
string cmd = line.Substring(0, 34);
string param = (line.Length == 34) ? "" : line.Substring(34);
if (cmd.StartsWith("ПОКАЗАТЬ В ПАНЕЛИ:")) {
param = param.TrimEnd();
if (!param.EndsWith(")")) { Debug.Log("Could not parse: " + cmd + param); continue; }
int ind = param.LastIndexOf("(");
if (ind <= 0) {Debug.Log("Could not parse: " + cmd + param); continue; }
string str_param = param.Substring(0, ind).Replace("\"", "\\\"");
string int_param = param.Substring(ind+1); int_param = int_param.Substring(0, int_param.Length-1);
var int_param_arr = int_param.Split(new char[]{','}).Select(x=> int.Parse(x.Trim())).ToArray();
if (int_param_arr.Length != 2) { Debug.Log("Could not parse: " + cmd + param); continue; }
str += " Step_Add_Dialog (\"" + str_param + "\"";
if (int_param_arr[0] == -1 && int_param_arr[1] == 0) str += ");\n";
else str += ", " + int_param_arr[0].ToString() + ", " + int_param_arr[1].ToString() + ");\n";
}
else if (cmd.StartsWith("ПРОДОЛЖИТЬ В ПАНЕЛИ:")) {
param = param.TrimEnd();
if (!param.EndsWith(")")) { Debug.Log("Could not parse: " + cmd + param); continue; }
int ind = param.LastIndexOf("(");
if (ind <= 0) { Debug.Log("Could not parse: " + cmd + param); continue; }
string str_param = param.Substring(0, ind).Replace("\"", "\\\"");;
string int_param = param.Substring(ind+1); int_param = int_param.Substring(0, int_param.Length-1);
var int_param_arr = int_param.Split(new char[]{','}).Select(x=> int.Parse(x.Trim())).ToArray();
if (int_param_arr.Length != 1) { Debug.Log("Could not parse: " + cmd + param); continue; }
str += " Step_Add_Dialog_Continue (\"" + str_param + "\"";
if (int_param_arr[0] == -1) str += ");\n";
else str += ", " + int_param_arr[0].ToString() + ");\n";
}
else if (cmd.StartsWith("ПОКАЗАТЬ В НИЖНЕЙ ПАНЕЛИ:")) {
param = param.TrimEnd();
if (!param.EndsWith(")")) { Debug.Log("Could not parse: " + cmd + param); continue; }
int ind = param.LastIndexOf("(");
if (ind <= 0) { Debug.Log("Could not parse: " + cmd + param); continue; }
string str_param = param.Substring(0, ind).Replace("\"", "\\\"");;
string int_param = param.Substring(ind+1); int_param = int_param.Substring(0, int_param.Length-1);
var int_param_arr = int_param.Split(new char[]{','}).Select(x=> int.Parse(x.Trim())).ToArray();
if (int_param_arr.Length != 2) { Debug.Log("Could not parse: " + cmd + param); continue; }
str += " Step_Add_Dialog_Important (\"" + str_param + "\"";
if (int_param_arr[0] == -1 && int_param_arr[1] == 0) str += ");\n";
else str += ", " + int_param_arr[0].ToString() + ", " + int_param_arr[1].ToString() + ");\n";
}
else if (cmd.StartsWith("ПРОДОЛЖИТЬ В НИЖНЕЙ ПАНЕЛИ:")) {
param = param.TrimEnd();
if (!param.EndsWith(")")) { Debug.Log("Could not parse: " + cmd + param); continue; }
int ind = param.LastIndexOf("(");
if (ind <= 0) { Debug.Log("Could not parse: " + cmd + param); continue; }
string str_param = param.Substring(0, ind).Replace("\"", "\\\"");;
string int_param = param.Substring(ind+1); int_param = int_param.Substring(0, int_param.Length-1);
var int_param_arr = int_param.Split(new char[]{','}).Select(x=> int.Parse(x.Trim())).ToArray();
if (int_param_arr.Length != 1) { Debug.Log("Could not parse: " + cmd + param); continue; }
str += " Step_Add_Dialog_Important_Continue (\"" + str_param + "\"";
if (int_param_arr[0] == -1) str += ");\n";
else str += ", " + int_param_arr[0].ToString() + ");\n";
}
else if (cmd.StartsWith("ПОКАЗАТЬ ПАНЕЛЬ ДИАЛОГА:")) {
str += " Step_Add_Dialog_Show ();\n";
}
else if (cmd.StartsWith("СКРЫТЬ ПАНЕЛЬ ДИАЛОГА")) {
str += " Step_Add_Dialog_Hide ();\n";
}
else if (cmd.StartsWith("СКРЫТЬ НИЖНЮЮ ПАНЕЛЬ ДИАЛОГА")) {
str += " Step_Add_Dialog_Important_Hide ();\n";
}
else if (cmd.StartsWith("ПОКАЗАТЬ КРАСНУЮ СТРЕЛКУ:")) {
param = param.Trim();
if (!param.StartsWith("(")) { Debug.Log("Could not parse: " + cmd + param); continue; }
if (!param.EndsWith(")")) { Debug.Log("Could not parse: " + cmd + param); continue; }
string float_param = param.Substring(1, param.Length-2);
var float_param_arr = float_param.Split(new char[]{','}).Select(x=> float.Parse(x.Trim(), System.Globalization.NumberStyles.Any, nfi)).ToArray();
if (float_param_arr.Length != 2) { Debug.Log("Could not parse: " + cmd + param); continue; }
str += " Step_Add_Tutorial_Arrow_Show (" + float_param_arr[0].ToString(nfi) + "F, " + float_param_arr[1].ToString(nfi) + "F);\n";
}
else if (cmd.StartsWith("СКРЫТЬ КРАСНУЮ СТРЕЛКУ:")) {
str += " Step_Add_Tutorial_Arrow_Hide ();\n";
}
else if (cmd.StartsWith("ПОКАЗАТЬ КРАСНУЮ ОБВОДКУ:")) {
param = param.Trim();
if (!param.StartsWith("(")) { Debug.Log("Could not parse: " + cmd + param); continue; }
if (!param.EndsWith(")")) { Debug.Log("Could not parse: " + cmd + param); continue; }
string float_param = param.Substring(1, param.Length-2);
var float_param_arr = float_param.Split(new char[]{','}).Select(x=> float.Parse(x.Trim(), System.Globalization.NumberStyles.Any, nfi)).ToArray();
if (float_param_arr.Length != 4) { Debug.Log("Could not parse: " + cmd + param); continue; }
str += " Step_Add_Tutorial_RedPanel_Show (" + float_param_arr[0].ToString(nfi) + "F, " + float_param_arr[1].ToString(nfi) + "F, " + float_param_arr[2].ToString(nfi) + "F, " + float_param_arr[3].ToString(nfi) + "F);\n";
}
else if (cmd.StartsWith("СКРЫТЬ КРАСНУЮ ОБВОДКУ:")) {
str += " Step_Add_Tutorial_RedPanel_Hide ();\n";
}
else if (cmd.StartsWith("ПОКАЗАТЬ КНОПКИ УПРАВЛЕНИЯ")) {
str += " Step_Add_ScriptControls_Show ();\n";
}
else if (cmd.StartsWith("СКРЫТЬ КНОПКИ УПРАВЛЕНИЯ")) {
str += " Step_Add_ScriptControls_Hide ();\n";
}
else if (cmd.StartsWith("ВСТАВИТЬ СКРИПТ В РЕДАКТОР:")) {
str += " Step_Add_SetScript (\"" + param + "\");\n";
}
else if (cmd.StartsWith("ЗАБЛОКИРОВАТЬ ИНСТРУКЦИИ:")) {
str += " Step_Add_Set_Blocked_Instructions (\"" + param + "\");\n";
}
else if (cmd.StartsWith("ПРОПУСТИТЬ АНИМАЦИЮ БОТА")) {
str += " Step_Add_Skip_Bot_Rebase_Anim ();\n";
}
else if (cmd.StartsWith("АКТИВИРОВАТЬ ОБЪЕКТ:")) {
str += " Step_Add_Activate_Level_Object (\"" + param.Trim() + "\");\n";
}
else if (cmd.StartsWith("ПРОИГРАТЬ ЗВУК:")) {
var int_param = param.Split(new char[]{','}).Select(x=>int.Parse(x)).ToArray();
if (int_param.Length != 2) { Debug.Log("Could not parse: " + cmd + param); continue; }
str += " Step_Add_Play_Sound (" + int_param[0].ToString() + ", " + int_param[1].ToString() + ");\n";
}
else if (cmd.StartsWith("ВЕРНУТЬ ГРОМКОСТЬ")) {
str += " Step_Add_Restore_Music_Volume ();\n";
}
else if (cmd.StartsWith("ЖДАТЬ:")) {
float f = float.Parse(param.Trim(), System.Globalization.NumberStyles.Any, nfi);
str += " Step_Add_Wait (" + f.ToString(nfi) + "F);\n";
}
else if (cmd.StartsWith("ПРИОСТАНОВИТЬ ВЫПОЛНЕНИЕ СКРИПТА")) {
str += " Step_Add_Pause ();\n";
}
else if (cmd.StartsWith("ПРОДОЛЖИТЬ ВЫПОЛНЕНИЕ СКРИПТА")) {
str += " Step_Add_Resume ();\n";
}
else if (cmd.StartsWith("ЖДАТЬ СОСТОЯНИЯ:")) {
str += " Step_Add_Check_Requirement (\"" + param.Trim() + "\");\n";
}
else if (cmd.StartsWith("ЗАКОНЧИТЬ УРОВЕНЬ:")) {
param = param.TrimEnd();
var str_param_arr = param.Split(new string[]{"---"}, System.StringSplitOptions.None);
if (str_param_arr.Length != 2) continue;
str += " Step_Add_LevelComplete (\"" + str_param_arr[0] + "\", \"" + str_param_arr[1] + "\");\n\n";
}
}
System.IO.File.WriteAllText(Application.dataPath + "/../Generated_Script_CNV.txt", str);
}
public static void Import_All_Script() {
steps.Clear();
Engine.Level_names.Clear();
Engine.Level_obj_names.Clear();
Engine.Level_step_indices.Clear();
Engine.Level_step_indices.Add(0);
System.Globalization.NumberFormatInfo nfi = new System.Globalization.NumberFormatInfo(); nfi.NumberDecimalSeparator = ".";
var file_text = System.IO.File.ReadAllText(Application.dataPath + "/../Generated_Script.txt");
var text_arr = file_text.Split(new string[]{"\r\n"}, System.StringSplitOptions.RemoveEmptyEntries);
foreach (string line in text_arr) {
if (line.Length < 34) continue;
string cmd = line.Substring(0, 34);
string param = (line.Length == 34) ? "" : line.Substring(34);
if (cmd.StartsWith("ПОКАЗАТЬ В ПАНЕЛИ:")) {
param = param.TrimEnd();
if (!param.EndsWith(")")) { Debug.Log("Could not parse: " + cmd + param); continue; }
int ind = param.LastIndexOf("(");
if (ind <= 0) {Debug.Log("Could not parse: " + cmd + param); continue; }
string str_param = param.Substring(0, ind).Replace("\\n", "\n");;
string int_param = param.Substring(ind+1); int_param = int_param.Substring(0, int_param.Length-1);
var int_param_arr = int_param.Split(new char[]{','}).Select(x=> int.Parse(x.Trim())).ToArray();
if (int_param_arr.Length != 2) { Debug.Log("Could not parse: " + cmd + param); continue; }
Step_Add_Dialog(str_param, int_param_arr[0], int_param_arr[1]);
}
else if (cmd.StartsWith("ПРОДОЛЖИТЬ В ПАНЕЛИ:")) {
param = param.TrimEnd();
if (!param.EndsWith(")")) { Debug.Log("Could not parse: " + cmd + param); continue; }
int ind = param.LastIndexOf("(");
if (ind <= 0) { Debug.Log("Could not parse: " + cmd + param); continue; }
string str_param = param.Substring(0, ind).Replace("\\n", "\n");
string int_param = param.Substring(ind+1); int_param = int_param.Substring(0, int_param.Length-1);
var int_param_arr = int_param.Split(new char[]{','}).Select(x=> int.Parse(x.Trim())).ToArray();
if (int_param_arr.Length != 1) { Debug.Log("Could not parse: " + cmd + param); continue; }
Step_Add_Dialog_Continue(str_param, int_param_arr[0]);
}
else if (cmd.StartsWith("ПОКАЗАТЬ В НИЖНЕЙ ПАНЕЛИ:")) {
param = param.TrimEnd();
if (!param.EndsWith(")")) { Debug.Log("Could not parse: " + cmd + param); continue; }
int ind = param.LastIndexOf("(");
if (ind <= 0) { Debug.Log("Could not parse: " + cmd + param); continue; }
string str_param = param.Substring(0, ind).Replace("\\n", "\n");;
string int_param = param.Substring(ind+1); int_param = int_param.Substring(0, int_param.Length-1);
var int_param_arr = int_param.Split(new char[]{','}).Select(x=> int.Parse(x.Trim())).ToArray();
if (int_param_arr.Length != 2) { Debug.Log("Could not parse: " + cmd + param); continue; }
Step_Add_Dialog_Important(str_param, int_param_arr[0], int_param_arr[1]);
}
else if (cmd.StartsWith("ПРОДОЛЖИТЬ В НИЖНЕЙ ПАНЕЛИ:")) {
param = param.TrimEnd();
if (!param.EndsWith(")")) { Debug.Log("Could not parse: " + cmd + param); continue; }
int ind = param.LastIndexOf("(");
if (ind <= 0) { Debug.Log("Could not parse: " + cmd + param); continue; }
string str_param = param.Substring(0, ind).Replace("\\n", "\n");
string int_param = param.Substring(ind+1); int_param = int_param.Substring(0, int_param.Length-1);
var int_param_arr = int_param.Split(new char[]{','}).Select(x=> int.Parse(x.Trim())).ToArray();
if (int_param_arr.Length != 1) { Debug.Log("Could not parse: " + cmd + param); continue; }
Step_Add_Dialog_Important_Continue(str_param, int_param_arr[0]);
}
else if (cmd.StartsWith("ПОКАЗАТЬ ПАНЕЛЬ ДИАЛОГА:")) {
Step_Add_Dialog_Show();
}
else if (cmd.StartsWith("СКРЫТЬ ПАНЕЛЬ ДИАЛОГА")) {
Step_Add_Dialog_Hide();
}
else if (cmd.StartsWith("СКРЫТЬ НИЖНЮЮ ПАНЕЛЬ ДИАЛОГА")) {
Step_Add_Dialog_Important_Hide();
}
else if (cmd.StartsWith("ПОКАЗАТЬ КРАСНУЮ СТРЕЛКУ:")) {
param = param.Trim();
if (!param.StartsWith("(")) { Debug.Log("Could not parse: " + cmd + param); continue; }
if (!param.EndsWith(")")) { Debug.Log("Could not parse: " + cmd + param); continue; }
string float_param = param.Substring(1, param.Length-2);
var float_param_arr = float_param.Split(new char[]{','}).Select(x=> float.Parse(x.Trim(), System.Globalization.NumberStyles.Any, nfi)).ToArray();
if (float_param_arr.Length != 2) { Debug.Log("Could not parse: " + cmd + param); continue; }
Step_Add_Tutorial_Arrow_Show(float_param_arr[0], float_param_arr[1]);
}
else if (cmd.StartsWith("СКРЫТЬ КРАСНУЮ СТРЕЛКУ:")) {
Step_Add_Tutorial_Arrow_Hide();
}
else if (cmd.StartsWith("ПОКАЗАТЬ КРАСНУЮ ОБВОДКУ:")) {
param = param.Trim();
if (!param.StartsWith("(")) { Debug.Log("Could not parse: " + cmd + param); continue; }
if (!param.EndsWith(")")) { Debug.Log("Could not parse: " + cmd + param); continue; }
string float_param = param.Substring(1, param.Length-2);
var float_param_arr = float_param.Split(new char[]{','}).Select(x=> float.Parse(x.Trim(), System.Globalization.NumberStyles.Any, nfi)).ToArray();
if (float_param_arr.Length != 4) { Debug.Log("Could not parse: " + cmd + param); continue; }
Step_Add_Tutorial_RedPanel_Show(float_param_arr[0], float_param_arr[1], float_param_arr[2], float_param_arr[3]);
}
else if (cmd.StartsWith("СКРЫТЬ КРАСНУЮ ОБВОДКУ:")) {
Step_Add_Tutorial_RedPanel_Hide();
}
else if (cmd.StartsWith("ПОКАЗАТЬ КНОПКИ УПРАВЛЕНИЯ")) {
Step_Add_ScriptControls_Show();
}
else if (cmd.StartsWith("СКРЫТЬ КНОПКИ УПРАВЛЕНИЯ")) {
Step_Add_ScriptControls_Hide();
}
else if (cmd.StartsWith("ВСТАВИТЬ СКРИПТ В РЕДАКТОР:")) {
Step_Add_SetScript(param.Replace("\\n", "\n"));
}
else if (cmd.StartsWith("ЗАБЛОКИРОВАТЬ ИНСТРУКЦИИ:")) {
Step_Add_Set_Blocked_Instructions(param);
}
else if (cmd.StartsWith("ПРОПУСТИТЬ АНИМАЦИЮ БОТА")) {
Step_Add_Skip_Bot_Rebase_Anim();
}
else if (cmd.StartsWith("АКТИВИРОВАТЬ ОБЪЕКТ:")) {
Step_Add_Activate_Level_Object(int.Parse(param.Trim()));
}
else if (cmd.StartsWith("ПРОИГРАТЬ ЗВУК:")) {
var int_param = param.Split(new char[]{','}).Select(x=>int.Parse(x)).ToArray();
if (int_param.Length != 2) { Debug.Log("Could not parse: " + cmd + param); continue; }
Step_Add_Play_Sound(int_param[0], int_param[1]);
}
else if (cmd.StartsWith("ВЕРНУТЬ ГРОМКОСТЬ")) {
Step_Add_Restore_Music_Volume();
}
else if (cmd.StartsWith("ЖДАТЬ:")) {
float f = float.Parse(param.Trim(), System.Globalization.NumberStyles.Any, nfi);
Step_Add_Wait(f);
}
else if (cmd.StartsWith("ПРИОСТАНОВИТЬ ВЫПОЛНЕНИЕ СКРИПТА")) {
Step_Add_Pause();
}
else if (cmd.StartsWith("ПРОДОЛЖИТЬ ВЫПОЛНЕНИЕ СКРИПТА")) {
Step_Add_Resume();
}
else if (cmd.StartsWith("ЖДАТЬ СОСТОЯНИЯ:")) {
Step_Add_Check_Requirement(param.Trim());
}
else if (cmd.StartsWith("ЗАКОНЧИТЬ УРОВЕНЬ:")) {
param = param.TrimEnd();
var str_param_arr = param.Split(new string[]{"---"}, System.StringSplitOptions.None);
if (str_param_arr.Length != 2) continue;
Step_Add_LevelComplete(str_param_arr[0], str_param_arr[1]);
}
}
Engine.Level_step_indices.RemoveAt(Engine.Level_step_indices.Count-1);
Debug.Log("Scenario script loaded from file.");
}
public static void Export_All_Script() {
string str = "";
int level = 0;
System.Globalization.NumberFormatInfo nfi = new System.Globalization.NumberFormatInfo(); nfi.NumberDecimalSeparator = ".";
foreach (var step in steps) {
switch (step.step_type) {
case step_type.dialog :
str += "ПОКАЗАТЬ В ПАНЕЛИ: " + step.str_param1.Replace("\n", "\\n") + "(" + step.int_param1.ToString() + "," + step.int_param2.ToString() + ")\r\n"; break;
case step_type.dialog_continue :
str += "ПРОДОЛЖИТЬ В ПАНЕЛИ: " + step.str_param1.Replace("\n", "\\n") + "(" + step.int_param1.ToString() + ")\r\n"; break;
case step_type.dialog_important :
str += "ПОКАЗАТЬ В НИЖНЕЙ ПАНЕЛИ: " + step.str_param1.Replace("\n", "\\n") + "(" + step.int_param1.ToString() + "," + step.int_param2.ToString() + ")\r\n"; break;
case step_type.dialog_important_continue :
str += "ПРОДОЛЖИТЬ В НИЖНЕЙ ПАНЕЛИ: " + step.str_param1.Replace("\n", "\\n") + "(" + step.int_param1.ToString() + ")\r\n"; break;
case step_type.dialog_show :
str += "ПОКАЗАТЬ ПАНЕЛЬ ДИАЛОГА: " + "\r\n"; break;
case step_type.dialog_hide :
str += "СКРЫТЬ ПАНЕЛЬ ДИАЛОГА " + "\r\n"; break;
case step_type.dialog_important_hide :
str += "СКРЫТЬ НИЖНЮЮ ПАНЕЛЬ ДИАЛОГА " + "\r\n"; break;
case step_type.tutorialArrow_Show :
str += "ПОКАЗАТЬ КРАСНУЮ СТРЕЛКУ: (" + step.float_param1.ToString(nfi) + "," + step.float_param2.ToString(nfi) + ")\r\n"; break;
case step_type.tutorialArrow_Hide :
str += "СКРЫТЬ КРАСНУЮ СТРЕЛКУ: " + "\r\n"; break;
case step_type.tutorialRedPanel_Show :
str += "ПОКАЗАТЬ КРАСНУЮ ОБВОДКУ: (" + step.float_param1.ToString(nfi) + "," + step.float_param2.ToString(nfi) + "," + step.float_param3.ToString(nfi) + "," + step.float_param4.ToString(nfi) + ")\r\n"; break;
case step_type.tutorialRedPanel_Hide :
str += "СКРЫТЬ КРАСНУЮ ОБВОДКУ: " + "\r\n"; break;
case step_type.script_controls_show :
str += "ПОКАЗАТЬ КНОПКИ УПРАВЛЕНИЯ " + "\r\n"; break;
case step_type.script_controls_hide :
str += "СКРЫТЬ КНОПКИ УПРАВЛЕНИЯ " + "\r\n"; break;
case step_type.setScript :
str += "ВСТАВИТЬ СКРИПТ В РЕДАКТОР: " + step.str_param1.Replace("\n", "\\n") + "\r\n"; break;
case step_type.set_blocked_instructions :
str += "ЗАБЛОКИРОВАТЬ ИНСТРУКЦИИ: " + step.str_param1 + "\r\n"; break;
case step_type.skip_bot_rebase_anim :
str += "ПРОПУСТИТЬ АНИМАЦИЮ БОТА " + "\r\n"; break;
case step_type.activate_object :
str += "АКТИВИРОВАТЬ ОБЪЕКТ: " + step.int_param1.ToString() + "\r\n"; break;
case step_type.play_sound :
str += "ПРОИГРАТЬ ЗВУК: " + step.int_param1.ToString() + "," + step.int_param2.ToString() + "\r\n"; break;
case step_type.restore_music_volume :
str += "ВЕРНУТЬ ГРОМКОСТЬ " + "\r\n"; break;
case step_type.wait :
str += "ЖДАТЬ: " + step.float_param1.ToString(nfi) + "\r\n"; break;
case step_type.pause :
str += "ПРИОСТАНОВИТЬ ВЫПОЛНЕНИЕ СКРИПТА " + "\r\n"; break;
case step_type.resume :
str += "ПРОДОЛЖИТЬ ВЫПОЛНЕНИЕ СКРИПТА " + "\r\n"; break;
case step_type.check_Requirement :
str += "ЖДАТЬ СОСТОЯНИЯ: " + step.str_param1 + "\r\n"; break;
case step_type.level_complete_show :
str += "ЗАКОНЧИТЬ УРОВЕНЬ: " + Engine.Level_names[level] + "---" + Engine.Level_obj_names[level] + "\r\n\r\n"; level++; break;
}
}
System.IO.File.WriteAllText(Application.dataPath + "/../Generated_Script.txt", str);
}
}