02.01. БЕЗ НАЗВАНИЯ

Перейти вниз

02.01. БЕЗ НАЗВАНИЯ

Сообщение автор Gudleifr в Пт Дек 08, 2017 10:52 am

ТОМ II. ЧЕЛОВЕК ИГРАЕТ С МАШИНОЙ
Строим игру из того, что есть.

ГЛАВА ПЕРВАЯ. БЕЗ НАЗВАНИЯ

Мои любимые произведения о воистину компьютерных играх:
ВЛАДИМИР ПИРОЖНИКОВ / НА ПАЖИТЯХ НЕБЕСНЫХ / 1982
МАРЕК БАРАНЕЦКИЙ / ПРАВО АЛЬТЕРНАТИВЫ / 1984
ДЭВИД БИШОФ / НЕДЕТСКИЕ ИГРЫ / 1983
Обратите внимание на даты. То ли публикация этих произведений пришлась на то время, когда я как раз решал, стоит ли мне становится программистом. И поэтому они у меня отложились все вместе. То ли это было осознание писательским сообществом того факта, что кибернетика умерла и можно быстренько подвести итоги?

ТЕКСТОВОЕ ПРОГРАММИРОВАНИЕ

В первой части заметок, я попытался рассмотреть вопрос создания простых игр на основе простых идей.
Конечно, мы видим, что, если какая-либо простая игра приобретает популярность, на ее основе делают сложную (и не одну). Причем сложность здесь подразумевается в виде т.н. "контента". Т.е. практически не имеет отношения к, собственно, игре, а выполняет лишь украшашательно-завлекательную функцию.
Тут, главное, не перепутать, что считать сложным. Да, нарисовать целый мир, в котором будет бегать герой, сложно. Но это сложность художника. А засунуть в этот мир трехмерную куклу игрока - сложность аниматора. А выдавать всю эту живую картинку со всеми тенями, бликами и брызгами на экран с приемлемой скоростью - сложность... да, программиста, но не того программиста, который сам играет в то, что делает, а несчастного работяги, погрязшего в технических описаниях "новейшего аппаратно-программного обеспечения, без использования которого ваша игра будет третьесортной".
Если мы хотим погрузится во все эти сложности, то играть придется, в первую очередь, в манагера, а не творца.
Я же хочу поиграть в программирование игр: придумать мир игры, в котором мне будет интересно творить; определить правила своей игры с будущим игроком; ограничить свои хотелки компьютерными возможностями (и, как сказано выше, гораздо более скромными своими возможностями).
Т.е. допустим, что простенькая игра-концепция нас не устраивает, мы хотим целый мир "на пределе собственной сложности". (Это такой закон кибернетики: управляющий должен быть сложнее управляемого).
***

При такой постановке вопроса сразу же возникает проблема: а что делать-то?
С простыми играми было просто: работали проходы и сверху-вниз (раз задача понятна, ее вполне можно разбить на подзадачи) и снизу-вверх (мы были вправе ожидать, что работа понятных нам процедур будет предсказуема).
А тут? Например, напрягая все свои слабые художественные способности, я нарисую какого-нибудь гвардейского сержанта татуинских бабуинов. Или придумаю замечательный алгоритм его поведения на поле боя. И что? Либо весь остаток жизни я буду рисовать подобных чудиков и их алгоритмы, и до самой игры дело так и не дойдет, либо я все-таки сделаю макет игры, но для бравого сержанта там, уверен, не будет места...
И наоборот, начав с общих мест, я буду все добавлять и добавлять варианты, которых будет так много, что я так и не начну писать...
В итоге, сложная программа обычно оказывается гениально не работающей или работающей тривиально. Так появляются многочисленные "компьютерные офисы", которые могут все, но... при условии, что пользователь знает, как это сделать без помощи офиса.
***

Так что, единственный способ начать создавать что-то сложное,- сформулировать задачу просто. А т.к. она сложная, то просто ее можно сформулировать лишь сложными словами (в сложных типах данных).
Для этого у нас есть естественное средство - человеческий язык. На нем мы можем выразить все, что понимаем. Поэтому мы принимаем первое решение - в рамках нашего проекта будем работать только с текстовыми данными. Исполняемые файлы, музыка, картинки - это лишь простые данные, которые можно записать проще, чем словами.
***

Для примера я выбрал, пожалуй, одно из самых неблагородных занятий - перенос настольной (сложной!) игры на компьютер (На тот момент, когда я это писал, почти все тексты той игры уже были практически переведены/отсортированы. Оставалось только начать да кончить... И где оно?- G.). При этом, обычно, теряется все полиграфическое обаяние и удовольствие от общения, но взамен ничего не дается. Однако, мне деваться некуда: слишком уж необходима "игра в написание игры". Буду, правда, надеяться, что в какой-то момент произойдет переход количества в качество, и откроется какая-то возможность создания, действительно, игры компьютерной.
avatar
Gudleifr
Admin

Сообщения : 908
Дата регистрации : 2017-03-29

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: 02.01. БЕЗ НАЗВАНИЯ

Сообщение автор Gudleifr в Пт Дек 08, 2017 10:55 am

ПОСТАНОВКА ЗАДАЧИ

В наличии имеются кое-как распознанные, структурированные и местами переведенные правила "тактических" игровых систем (категория #3 настольных игр - "шашки", тип 1а военных игр - "абстрактные с миниатюрами"): StarGrunt II (уровень взвода), DirtSide II (уровень батальона) и FullThrust (космические схватки). Кроме того, есть "недостающее" дивизионное звено - правила BOOTS, TRACKS, AND HOVERSKIRTS (BOOTS, TRACKS, AND ROTORS), выдранные из Сети, как есть.
Надо:

1. Перевести правила и привести их в удобочитаемую форму.
2. По мере возможности снабдить правила "калькуляторами" для большего удобства компьютерной игры (в т.ч. подумать над компьютерным игроком).
3. Организовать органайзер для игры в целом (заодно, и для пп.1-2).
4. Подумать, не получится ли в процессе компьютерная игра.

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

1. Обычный текст. Снабженный гиперссылками, позволяет визуализировать практически что угодно. Обязательна возможность макроподстановок. С другой стороны, с текстом могут быть связаны некие соглашения о его верстке - отступы, выравнивание, шрифты, буквицы, иллюстрации и т.д.
2. ЭЛектронная Таблица (ЭЛТ). Объединяет в себе универсальную экранную форму и способ пересчета данных при изменении одного из них.
3. Реляционная База Данных (БД). Позволяет хранить множества данных в виде таблиц и выдавать их в виде виртуальных таблиц. Кроме того, может визуализировать/редактировать данные согласно их типам.
4. Иерархический документ. Годится не только для построения оглавлений (каталогов), но и для построения списковых БД. Желательна возможность хранения альтернативных путей к данным. И хранения макропеременных. И наличия операции сравнения поддеревьев - унификации.

Конечно, свойства этих объектов сильно зависят от размера данных, например, БД начинают жутко тормозить при больших размерах таблиц, ЭЛТ становятся совершенно неудобными, когда данные не влезают в экран, а хранение списков маленьких фрагментов в иерархических документах и вовсе выглядит страшно... Но, надеюсь, в нашем случае (формализации смысла, заложенного в одном-двух мегабайтах текста) их мощностей хватит.


Последний раз редактировалось: Gudleifr (Пт Фев 09, 2018 12:32 am), всего редактировалось 1 раз(а)
avatar
Gudleifr
Admin

Сообщения : 908
Дата регистрации : 2017-03-29

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: 02.01. БЕЗ НАЗВАНИЯ

Сообщение автор Gudleifr в Пт Дек 08, 2017 11:14 am

ИСТОРИЧЕСКАЯ СПРАВКА

Я очень люблю древнюю компьютерную литературу. Хотя она и гораздо требовательнее к уровню подготовки читателей (заставляя иногда исчирикивать по паре-другой листов бумаги при очередном "далее - очевидно"), но это окупается. Размышления с позиции "что нам надо от компьютера" вместо "берите, что дают" привлекают гораздо сильнее.
Поэтому просто сошлюсь на книгу: В.М.Брябрин, Программное обеспечение персональных ЭВМ, 1988 - ТЕМА #15, АБЗАЦ #386. Точнее, на подробное описание там системы Framework (с. 187-193). Пусть это и "давно обычные для нас вещи". Ведь, первая версия этой программы была создана в 1984 для процессора 8086 и монохромного дисплея и занимала в памяти всего три сотни килобайт (т.е. в тысячи раз меньше современных программ). Так что надо удивляться не примитивности и обычности тех программ, а беспомощности современного программирования, не способного создать ничего нового.
***

...
Далее приводится более подробное описание системы Framework, в которую встроено несколько замечательных свойств, позволяющих создавать на ее основе как простые проблемно-ориентированные системы, предназначенные для применения в деловой сфере, так и сложные автоматизированные рабочие места.

ОСНОВНЫЕ СВОЙСТВА СИСТЕМЫ FRAMEWORK. Система Framework (произносится "фреймворк") обеспечивает следующие основные возможности: создание и обработку текстовых материалов, структурное представление документов, использование электронных таблиц и баз данных реляциоиного типа, графическое представление данных. Пользователю, обладающему программистской квалификацией, система предоставляет специальный язык программирования - Fred, с помощью которого можно описать сложные алгоритмы управления процессом обработки данных.

Отличительной чертой системы Framework является принцип, согласно которому все создаваемые пользователем информационные объекты рассматриваются с единой точки зрения: все они объявляются фреймами. Фрейм - это некоторый универсальный носитель информации, который, в свою очередь, может состоять из фреймов или же содержит конкретные данные, представленные в виде текста, таблиц, записей базы данных илн графиков разного вида.

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

ВЫЗОВ СИСТЕМЫ И НАЧАЛО РАБОТЫ С НЕЙ. При вызове системы на экране выделяется несколько рабочих зон. Главное меню располагается в верхней части вкраиа н содержит девять слов, являющихся командами верхнего уровня:

Disk Create Edit Locate Frames Words Numbers Graphs Print

Эти команды соответствуют основным режимам работы. Выбор команды в этом меню осуществляется одновременным нажатием клавиши Ctrl и клавиши с первой буквой имени команды. При этом выделяется соответствующая позиция меню, и вслед за этим появляется вспомогательное меню, которое как бы "выпадает" из главного. Вспомогательное меню имеет вид столбца, в строчках которого расположены слова, поясняющие отдельные операции. Выбор позиции вспомогательного меню осуществляется с помощью стрелок "Вверх", "Вниз" с последующим нажатием клавиши "Исполнение" (рис.5.16).

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

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

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

Список имен внешних накопителей - А:, С:, D:, Е: - размещается в правой части экрана в виде узкого столбца.


Рис.5.16. Вид экрана в начале работы с системой Framework

В правом нижнем углу экрана во время работы возникает столбец с именами активизированных фреймов - это список рабочих фреймов. На рис.5.16, являющемся графической копией экрана, в этом списке видны рабочие фреймы с именами "Оглавление", "Таблица", "Текст", "График".

МЕТАФОРА РАБОЧЕГО КАБИНЕТА. При работе с системой человек может представить себя находящимся в рабочем кабинете. Обстановка этого "кабинета", имитируемого системой, включает "шкафы", в которых лежат "папки" с документами. Кроме того, имеется "рабочий стол", который можно использовать, во-первых, для того, чтобы сложить на углу нужные папки, во-вторых, для того, чтобы на его рабочей поверхности можно было раскладывать папки и вынимаемые из иих документы и работать с ними.

Сначала пользователь видит лишь "шкафы", роль которых играют накопители с именами А:, С:, D:, Е: (рис.5.17). Первое действие, которое совершает пользователь,- "открыть шкаф". Для этого он выбирает с помощью курсора имя соответствующего накопителя, например, С:, и нажимает клавишу "Исполнение". В рабочей области возникает вертикальное окно-столбец с именами фреймов (файлов), находящихся на данном внешнем накопителе. Это "папки", лежащие в "шкафу".


Рис.5.17. Вид экрана при выборе рабочих фреймов

Далее из выведенного списка можно выбрать один или несколько фреймов, нажимая клавишу "Исполнение" в соответствующих позициях. Выбранные фреймы, точнее, их имена перемещаются в список рабочих фреймов в правом нижнем углу экрана. Эту операцию можно представить как вынимание нужных "папок" из "шкафа" и складывание их в стопку на углу стола. На рис. 5.17 видна стопка фреймов с именами Tabl, tx1, DB1.

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

Папка "открывается", если на нее указать курсором и нажать "Исполнение". При этом в рабочем поле появляется раскрытый фрейм с соответствующим содержимым. На рис.5.17 виден раскрытый фрейм типа "база данных". Его имя - DB1.

Далее можно "погрузиться" в данный фрейм и начать работу с его содержимым. Способ работы определяется типом фрейма. Текстовый фрейм можно редактировать. Электронную таблицу можно просматривать и заполнять информацией. Базу данных можно просматривать, заполнять, сортировать и производить в ней поиск по значениям выделенных полей. Графики, диаграммы и гистограммы можно строить по данным, выбираемым из электронной таблицы или базы данных. Можно создавать, просматривать и модифицировать структурированные документы. Это и есть основные типы фреймов.


Рис.5.18. Внд экрана с перекрывающими друг друга фреймами

Дисплейное окно, в которое выводится фрейм, можно перемещать по экрану и изменять его размеры. Один особый случай изменения размеров фрейма реализуется нажатием клавиши F9, после чего активизированный в данный момент фрейм показывается во весь экран. Эта операция называется Zoom (укрупнение). Повторное нажатие клавиши F9 возвращает окно с фреймом к прежнему размеру и ставит его на прежнее место в рабочей области экрана. Раскрытые в рабочей области фреймы могут частично или полностью перекрывать друг друга - точно так же, как лежащие на столе раскрытые папки с документами (рис.5.18).

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

Для выполнения таких операций, как удаление или сохранение фрейма на диске, нужно использовать главное управляющее меню, т.е. нажать клавиши Ctrl+<первая буква команды> и затем в соответствии с выведенным списком вспомогательного меню выполнить требуемую операцию. По ходу выполнения возможен небольшой диалог между пользователем и системой - по поводу имен файлов и пр.

Подобный способ действий сравнительно легко и быстро осваивается любым пользователем. Когда у пользователя появляются проблемы, он всегда может обратиться к системной "подсказке": нажатие специальной клавиши выводит на экран подробный текст с разъяснениями. Текст подсказки структурирован по разделам и содержит пояснения по всем возможным операциям.

"ОБРАБОТКА ИДЕЙ". Одна из замечательных возможностей в системе Framework связана с так называемой обработкой идей. Пользователь может начать работать с фреймом типа структурированный документ. При этом первое, что появляется в соответствующем дисплейном окне, это пронумерованный и пока безымянный перечень разделов. Пользователь может начать с того, что для каждой позиции этого перечня указать сначала только имя и тип соответствующего подраздела.

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


Рнс.5.19. Вид экрана при создании структурного документа

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

Структурный документ можно дополнять новыми разделами. Можно копировать информацию из одного раздела в другой. Можно заставить систему сделать полное (текстовое) оглавление по созданным перечням разделов. Можно, наконец, вывести на печать любой раздел или весь структурный документ. При этом отдельные содержательные компоненты - текстовые, табличные и графические фреймы - будут выводиться на печать по соответствующим правилам.

Описанное свойство выгодно отличает систему Framework от других интегрированных систем, поскольку стимулирует работу "сверху вниз" и позволяет легко создавать иерархические модели и документы.

Каждый фрейм в системе отображается в отдельный файл ДОС. Это очень важное свойство, позволяющее создавать информационные модели и документы произвольной сложности (ограничением является лишь доступный объем внешних устройств).

При работе в системе Framework пользователь может временно прервать основной процесс и обратиться к ДОС, а затем вновь вернуться к прерванной работе. Следуя общему принципу, обращение к ДОС оформляется просто как вызов специального фрейма с именем DOS. Выйдя в ДОС, можно, например, запустить какую-либо программу и результаты ее работы передать назад в систему - в другой фрейм. Чтобы вернуться нз ДОС в Framework, достаточно дать команду EXIT. Эта возможность делает систему очень близкой по свойствам к операционным оболочкам, основной целью которых является интегрирование автономных программ.

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

Нас в этом отрывке должны интересовать не пользовательский интерфейс и (не)удобство офисного применения (например, столь же древний Multi-Edit может делать все тоже самое, но другими методами). Мы видим три очень важных для дальнейших экспериментов решения:
1. набор основных типов информационных блоков/фреймов - текст, ЭЛТ, таблица БД;
2. дополнение этого набора "связующим" иерархическим фреймом;
3. использование единого для всех блоков языка программирования - Fred. В рамках этого языка любой фрейм/часть фрейма имеет значение, которое можно вычислить и подставить в другой фрейм (практически соответствует обычным формулам ЭЛТ).
***


MindJet - более современный "интегратор". Работает с обычными "офисными" документами.

Кстати, я честно пытался применить этот самый Mindjet для чего-то интересного:
- DIRTSIDE II & STARGRUNT II. Т.к. в то время работа над переводом правил этих игр была вынужденно приостановлена на самом переломном месте – переосмыслении представления на моей страничке, то карта создавалась с целью сохранить как можно больше информации до момента восстановления работ. Формат входных данных – текстовая база данных моего формата (ГЛЮКВА, см. далее). Ветви естественно расползлись влево и вправо. Слева накопилось 4 очевидных уровня: "Первоисточники" – <Книга> – <Глава> – <Параграф>, и пара более коротких ветвей "Мои комментарии" и "Огрызки из других источников". Справа – ветвление определялось моим новым видением правил изложения правил (до 5 уровней вложения). Процесс дальнейшего переформатирования т.о. состоял в переносе кусков текста слева-направо. Никаких специальных узлов с концепциями/памятками не появилось (не до того было).
- VOID. Входные данные – аналогичные: мои переводы (описания вселенной игр этой серии) в той же ГЛЮКВЕ. Но построение карты осуществлялось с совершенно с другой целью. Файл ГЛЮКВЫ вырос до таких размеров, что я сам потерял за этими деревьями лес. Захотелось наглядности, а писать для этого очередной неудачный визуализатор ГЛЮКВЫ не хотелось. Работа успехом не увенчалась. Т.к. ГЛЮКВА обладает гораздо большими возможностями перекрестных ссылок, при прямом переносе голого текста в карту очень большая часть информации была потеряна. Обозримости достигнуть не удалось – карта влезает в экран только в масштабе 28%.
- H1.RU. Карта создавалась с целью отследить необходимые мероприятия по обновлению моей странички. Наученный горьким опытом VOID, сразу отказался от копирования в структуре карты структуры странички. Разбил все мероприятия по темам: проекты с громкими названиями, замеченные опечатки, пока бесхозные куски и т.д. Карта пока (здесь и далее "сейчас" - лет десять назад.- G.) обозрима. Активно используются "циферблаты" - это такие иконки, показывающие как я оцениваю готовность фрагментов. Однако, проявились и ограничения модели: привязка некоторых узлов спорна, также пришлось использовать "поперечные" связи.
- ВСЕЛЕННАЯ. Входные данные – совершенно разнородные фрагменты с описаниями моей "тренировочной" вселенной. Основной источник данных – текст, разбитый на нумерованные абзацы. Получилось интересно. В карте совмещены как данные разных типов (тексты, картинка, таблицы), так и узлы различных типов: информационные фрагменты, наметки будущих концепций, замечания о дальнейших направлениях работы. К сожалению, как только карта стала интересной, она перестала влезать в экран.
- ФРАГМЕНТ. Карта создавалась как подспорье в разработке некоторой системы интерактивной обработки, единица которой и была названа "фрагментом". Гордо воткнув "Фрагмент" в центр карты я честно потянул от него связи к сущностям, которые должны были участвовать в обработке. Очередной раз убедился, что ветвям карты заказано соответствовать каким-либо связям реального мира. Во-первых, оказался совершенно никак не отраженным в карте тот факт, что многие сущности, связанные с фрагментом, сами являются фрагментами (рекурсия). Во-вторых, если узлы еще можно кое-как откомментировать (иконками или навешиванием узлов специального вида), то связи между узлами откомментировать практически невозможно. В-третьих, Для ветвей "Теория [, философия, аксиоматика]", "Операции [и предикаты над фрагментами]" и "Вопросы [, подлежащие решению]" места не нашлось совершенно и их пришлось раскидать экрану, не привязывая к "корню".
- ПРОЕКТЫ. Только начал, в попытке как-то упорядочить текущие проблемы. Пока развесил по веткам только содержимое пары файлов, аналогичных файлу ВСЕЛЕННОЙ, содержащих старые заметки. В перспективе, надо связать эту карту со всеми остальными.
Т.е. весь опыт свелся к тому, что проще было переформатировать (или написать для этого программку) данные самому, чем таскать их в MindMap и обратно. Тем более, что я так и не понял, может ли MindMap как-то помочь автоматизировать обработку.


Последний раз редактировалось: Gudleifr (Сб Июн 16, 2018 11:40 am), всего редактировалось 2 раз(а)
avatar
Gudleifr
Admin

Сообщения : 908
Дата регистрации : 2017-03-29

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: 02.01. БЕЗ НАЗВАНИЯ

Сообщение автор Gudleifr в Пт Дек 08, 2017 12:06 pm

ЗАДАЧА 1 ("ПРАВИЛА"). ЭТАП 0 ("РУЧНЫЕ ОПЕРАЦИИ")

Сами по себе все эти замечательные текстовые "кирпичики" никакой задачи не решат.

Надо решить:
1. Как этими данными описать то, что нам надо?
2. Какие программы нужны для манипулирования ими?
3. Как запустить эти программы на нашей машине?



По сути, это те cамые три части задачи, которые постоянно решает программист ТЕМА #15, АБЗАЦ #388. И аксиома #3 говорит нам, что решаются эти три части почти независимо друг от друга.

Лучше, конечно, начать с первой, т.к. она, все-таки, главная.
***

Какие форматы данных нам понадобятся для записи "ПРАВИЛ" и организации к ним "РУЧНОГО ДОСТУПА"?

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

В идеале, конечно текст хорошо бы упаковать в БД. (Подходит агент Малдер к компьютеру и вбивает: "Найди что-нибудь интересное". А тот ему в ответ: "Заметка из газеты за 1934-й год... Заметка за 1962-й... Вампир на фотографии - тот же самый... Четвертый справа в кепке...") Однако, такое возможно только когда мы уже пересчитали все возможные варианты текстов, выделили и классифицировали все их признаки и параметры... Этот подход действительно встречается - в "простых книгах-играх" ТЕМА #20, для которых написаны многочисленные редакторы/проигрыватели, держащие автора в достаточно жестких шорах, не позволяя писать того, что не предусмотрено.

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

После экспериментов с введением в БД дополнительных таблиц-справочников и попыток свести все к XML, я остановился на чисто текстовом формате:
1. Описываются только "листья" нашего "дерева".
2. При описании каждого "листа" указываются все пути - "ветви" - которые к нему ведут от самого "корня".
Это напоминает дисковую систему Unix, где один файл может быть привязан к нескольким директориям одновременно.

Исторически примером этого метода служит эта "база компонентов" (табуляцию эаменил на #):

Спойлер:
\Конденсаторы\Кривые от Пети\ELV
\Конденсаторы\Электролитические алюмининиевые\Для поверхностного монтажа\ELV
ТАБЛИЦА
C, мкФ

6,3В
10В
16В
25В
35В
50В
63В
100В

0,1 # - # - # - # - # - # - # A\1,0 # - # -
0,22 # - # - # - # - # - # - # A\2,0 # - # -
0,33 # - # - # - # - # - # - # A\2,8 # - # -
0,47 # - # - # - # - # - # - # A\4,0 # - # -
1 # - # - # - # - # - # - # A\8,4 # - # -
2,2 # - # - # - # - # - # - # A\13 # - # -
3,3 # - # - # - # - # - # - # A\17 # - # -
4,7 # - # - # - # - # A\16 # A\18 # B\20 # - # E\80
10 # - # - # - # A\23 # B\27 # B\29 # C\33 # - # E\90
22 # - # A\28 # B\33 # B\37 # C\42 # C\46 # D\80 # E\75 # E\130
33 # A\28 # B\37 # B\41 # C\49 # C\52 # C\58 # E\200 # E\160 # F\170
47 # A\33 # B\45 # C\52 # C\58 # C\60 # D\115 # E\240 # E\170 # -
100 # B\56 # C\70 # C\76 # C\86 # D\160 # E\280 # F\500 # F\240 # -
220 # C\96 # D\150 # D\190 # E\290 # E\300 # F\570 # - # - # -
330 # - # D\210 # E\330 # E\330 # F\680 # - # - # - # -
470 # - # E\380 # F\680 # F\690 # - # - # - # - # -
1000 # - # F\700 # - # - # - # - # - # - # -

F ELV: C=\V, U=\С, Корпус=\0, Iп=\1
V \RмкФ

\Конденсаторы\Подстроечные\Для поверхностного монтажа\TZVY2
ЗАПИСИ
-
Емкость.min
Емкость.max
Темпер.коэфф.
Q
Цвет

TVY2Z030A110 # 1,5 # 3,0 # NP0 # 300 # св.-зел.
TVY2Z060A110 # 2,5 # 6,0 # NP0 # 500 # св.-зел.
TVY2Z100A110 # 3,0 # 10,0 # NP0 # 500 # св.-зел.
TVY2Z200A110 # 4,5 # 20 # N750 # 500 # кор.
TVY2Z250A110 # 5,5 # 25,0 # N750 # 300 # кор.
TVY2Z450A110 # 8,0 # 45,0 # N1000 # 300 # св.-кор.

F TVY2Z\0A110: C=\V
V \2

\Конденсаторы\Подстроечные\Для поверхностного монтажа
ЗАПИСИ

030 # 1,5 # 3,0 # NP0 # 300 # св.-зел.
060 # 2,5 # 6,0 # NP0 # 500 # св.-зел.
100 # 3,0 # 10,0 # NP0 # 500 # св.-зел.
200 # 4,5 # 20 # N750 # 500 # кор.
250 # 5,5 # 25,0 # N750 # 300 # кор.
450 # 8,0 # 45,0 # N1000 # 300 # св.-кор.

F TVY2Z\0A110: C=\V
V \2

\Тарифы телефонной кампании\Вариант 3
ТАБЛИЦА
Никому не нужная, тренировочная таблица
-
ВЫСОКИЙ ТАРИФ
# 1-я м.
# доп.м.
СРЕДНИЙ ТАРИФ
# 1-я м.
# доп.м.
НИЗКИЙ ТАРИФ
# 1-я м.
# доп.м.

Плата за соединение # Прямой вызов # .30 #  # .20 # .22 #  # .15 # .12 #  # .09
\'' #  #  #  # Оператор #  # 1.20 #  # \'' # 1.12 #  # \'' # 1.02 #  # \''
ПЛЮС # \-
Плата за расстояние # \, #  #  # .12\100m # \, # .10\100m # \, # .06\100m # \,

F \R (\C): \V
V \0

\Pro'sKit\Отвертки\8PK-509
ТЕКСТ
Набор состоит из \3\-х плоских и \3\-х крестовых отверток. Отвертки имеют длинный стержень и удобны для работы с глубоко утопленными винтами. Рукоятки выполнены из литого пластика, стержень выполнен из сплава никеля, хрома и молибдена.

F Набор отверток \N
V \0 плоских + \1 крестовых

\Pro'sKit\Кусачки
ТЕКСТ
Широкий выбор высококачественного инструмента, изготовленного из специальной стали, подвергнутой высокотемпературной обработке, с прекрасной режущей способностью и длительным сроком службы.

F Кусачки \N (\M) \L
M сталь

\Сан Саныч
\Тарифы телефонной кампании\Сан Саныч
ТАБЛИЦА

САМ ДУРАК! # \-
Плата за соединение # Прямой вызов # .30 #  # .20 # .22 #  # .15 # .12 #  # .09
\'' #  #  #  # Оператор #  # 1.20 #  # \'' # 1.12 #  # \'' # 1.02 #  # \''
ПЛЮС # \-
Плата за расстояние # \, #  #  # .12\100m # \, # .10\100m # \, # .06\100m # \,

F Вещь от Сан Саныча: \N

\Сан Саныч\Кусачки
\Тарифы телефонной кампании\Сан Саныч\Кусачки

F Кусачки от Сан Саныча: \N

\Pro'sKit\Кусачки\Инструмент для точных работ
\Сан Саныч\Кусачки\Инструмент для точных работ
\Тарифы телефонной кампании\Сан Саныч\Кусачки\Инструмент для точных работ
ТЕКСТ
Длинные, однако!
Очен-но длинные.
Однако!

L 125мм

\Pro'sKit\Кусачки\Инструмент для точных работ\1PK-727
\Сан Саныч\Кусачки\Инструмент для точных работ\1PK-727
\Тарифы телефонной кампании\Сан Саныч\Кусачки\Инструмент для точных работ\1PK-727

\Pro'sKit\Кусачки\Инструмент для точных работ\1PK-717
ТЕКСТ
Сами таким инструментом работайте!

\Pro'sKit\Кусачки\Инструмент для точных работ\1PK-704

За время использования этого формата, я перепробовал разные способы применения:
- Когда лепил дополнительные библиотеки к PCAD, активно использовал разные флаги и пометки, т.к. база редактировалась в этой версии очень активно: выделенные элементы, копирование блоков, сравнение множеств.
- Когда хранил блоки информации для одного забавного прибора шифрования, ничего интересного не встретилось, за исключением  многочисленных операций клонирования.
- Применяя для анализа модулей/подпрограмм BIOS, отказался от наследования параметров, т.к. использовал их для определения типов переходов между узлами.
- При описании вселенной игры VOID получилось но лес - библиотека имела несколько входов: содержание, упорядочение по первоисточникам, словарь...

Какие полезные свойства я обнаружил у этого способа за годы его использования?
1. Для любой порции информации без труда находится место.
2. Поиск по базе производится очень удобно.
3. Избыточность минимальна.
4. Перенос, копирование, клонирование и прочие операции над "узлами дерева" сводятся к операции замены подстрок в путях.
5. Можно управлять показом содержимого листа в зависимости от пути, по которому к нему пришли.

Какие выявились недостатки?
Требуется придумывать дополнительные дисциплины управления путями в каждом новом проекте. Иначе существует что вновь вводимые пути вызовут неожиданные последствия.

Впрочем, игровое применение данного способа, как раз, и требует изобретение такой дисциплины как части правил игры.


Последний раз редактировалось: Gudleifr (Вс Авг 12, 2018 10:44 am), всего редактировалось 9 раз(а)
avatar
Gudleifr
Admin

Сообщения : 908
Дата регистрации : 2017-03-29

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: 02.01. БЕЗ НАЗВАНИЯ

Сообщение автор Gudleifr в Пт Дек 08, 2017 12:09 pm

Перейдем ко второй части задачи - "программированию". Не столько потому, что первую мы уже решили, сколько потому, что тут есть хоть какой-никакой задел.

Приняв текст как способ хранения данных, мы имеем выбор, которого у нас не было, если бы мы использовали специализированные/бинарные/архивированные данные. Если данные нельзя "просто прочитать" из файла, то любая операция их редактирования должна состоять из трех частей: считываем текст/файл в структуры данных, преобразуем, загоняем структуры обратно в текст/файл. Назовем такие операции ОБЩИМИ.

Пример решения, состоящего из оконного скрипта на Tcl/Tk с вызовом Perl-скриптов (одного большого, обеспечивающего выполнение ОБЩИХ операций, и кучи маленьких - на одну операцию):



Если же мы оперируем текстом, нам доступны еще два вида операций: ПОСЛЕДОВАТЕЛЬНЫЕ (прогоняем текст/файл через какой-либо фильтр, как это всегда делалось в Unix) и ЧАСТНЫЕ (вырезаем из текста/файла нужный фрагмент, правим его в обычном
текстовом редакторе, записываем обратно).

Тут очень трудно провести четкую границу между "ручным редактированием" и "автоматической обработкой", ведь, даже, простое считывание текстового файла в память (в обычном редакторе) уже требует программирования операций работы с памятью, файловой системой и т.д. Не будем над этим думать, главное, чтобы работало.
***

Надо сразу понять связь между этитми тремя видами операций:
1. Считывание файла в память для проведения ОБЩЕЙ операции само по себе практически является ПОСЛЕДОВАТЕЛЬНОЙ операцией.
2. Вырезание из файла куска для ЧАСТНОЙ операции может являться ПОСЛЕДОВАТЕЛЬНОЙ операцией.
***

Т.о. программирование ПОСЛЕДОВАТЕЛЬНЫХ операций должно предшествовать программированию ОБЩИХ и ЧАСТНЫХ просто потому, что первые обеспечивают последним среду обитания.

Для моих "деревьев" существует простейшая "пустая" ПОСЛЕДОВАТЕЛЬНАЯ операция - перебрать весь список листов, отслеживая тип читаемой информации. Т.е. т.к. описания "листов" в файле состоят из описаний путей, типов, заголовков и содержимого, операция должна в каждый момент понимать, что из этого она в данный момент читает.

Написав программу этой операции мы без труда получим нужные нам ПОСЛЕДОВАТЕЛЬНЫЕ операции просто подставляя нужный код в ее "пустые" места.

По сути это почти "Машина Тьюринга", программа которой, как известно, представляет из себя таблицу

Символ * Состояние = (Нов.Символ, Нов.Состояние, Сдвиг.Курсора).

Наша машина проще, за единственным исключением: "Символы"-строки определяются регулярными выражениями.
Зато, "Нов.Символ" не используется. А "Сдвиг.Курсора" означает, лишь, ввести новую строку или оставить текущей старую.

Всего используется семь "Символов":
- пустая строка;
- строка, начинающаяся с "обратной косой" ("путь");
- строка с единственным словом ТЕКСТ;
- ... ТАБЛИЦА;
- ... ЗАПИСИ;
- строка начинающаяся с пары "латинская буква" и "пробел" ("параметр");
- любая другая строка.

И пять "Состояний":
- Garbage (мусор) - информация вне "листов";
- Path (путь) - путь к листу;
- Head (заголовок) - текст заголовка для "листов" типов ТАБЛИЦА и ЗАПИСИ;
- Text (текст) - текст "листа";
- Param (параметр) - параметры "листа".

СостояниеСимволНов.Состояние, строкаСокращение
GarbageОбратная косаяPath, сохраняетсяG\P
GarbageПустаяGarbage, новаяG0GI
GarbageВсе остальныеGarbage, новаяGXGI
PathОбратная косаяPath, новаяP\PI
PathТАБЛИЦАHead, новаяP#PI
PathЗАПИСИHead, новаяPRPI
PathТЕКСТText, новаяPTTI
PathЛитера и пробелParam, сохраняетсяPLL
PathПустаяParam, новаяP0LI
PathВсе остальныеGarbage, сохраняетсяPXG
HeadПустаяText, новаяH0TI
HeadВсе остальныеHead, новаяHXHI
TextПустаяParam, новаяT0LI
TextВсе остальныеText, новаяTXTI
ParamОбратная косаяPath, сохраняетсяL\P
ParamЛитера и пробелParam, новаяLLLI
ParamПустаяGarbage, новаяL0GI
ParamВсе остальныеGarbage, сохраняетсяLXG

Можно заметить, что новую строку требуется ввести, если текущая заведомо обработается этим Состоянием (Нов.Состояние равно старому), или текущая строка не несет никакой дополнительной информации, кроме "переключательной" (пустая, тип "листа"). Сохраняется непустая строка, если осуществляется переход из "чужого" для нее Состояния, в Нов.Состояние, способное ее обработать.


Последний раз редактировалось: Gudleifr (Пт Авг 10, 2018 8:28 am), всего редактировалось 11 раз(а)
avatar
Gudleifr
Admin

Сообщения : 908
Дата регистрации : 2017-03-29

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: 02.01. БЕЗ НАЗВАНИЯ

Сообщение автор Gudleifr в Пт Дек 08, 2017 12:32 pm

Теперь, запрограммировав нашу задачу, мы можем ее запустить, переписав на одном из доступных нам языков.

Что выбрать?
1. Ранее я чаше всего применял только один способ реализации этой машины - на Perl, визуализируя полученный результат на Html своей странички (реже на Tcl/Tk - см.выше).
По тем временам это был почти идеальный способ программирования "на голом Windows". Заведи себе бесплатный хостинг и программируй свои CGI-программы на Perl или даже C, не имея на своей машине ничего, кроме текстового редактора и средств доступа к Сети. К сожалению, эта холява кончилась - ТЕМА #7.


Отработала ОБЩАЯ операция преобразования comp.txt в HTML путем построения в памяти полного "дерева".
(Обратите внимание на то, что кусачки 1PK-727 висят сразу на двух "ветках"):

Что можно сказать о "красоте" этой реализации? Она короткая и, по сравнению с другими, имеет минимальную избыточность и минимум ограничений на формат строк и размер файла. (Хотя, конечно, даже минимальная Perl-избыточность раздражает сильнее любой другой, т.к. язык-то позиционируется, как наиболее лексически совершенный).

2. Оставшись без халявного хостинга, я вынужден опять поднять тему совместимости, переносимости и прочей машинной независимости.
Эта тема выглядит совершенно по-разному для программистов-пользователей и системщиков. Первые любят порассуждать о программах, которые могут  одинаково правильно компилироваться/интерпретироваться для/на любом железе и операционной системе. Вторые же вынуждены считать, что нет чего-то заранее универсального и переносимого, есть только системы совершенно по-разному устроенные, но работающие внешне схожим образом.

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

Поэтому я переписал свою машину в виде командного файла Windows. Конечно, страшно. Некоторые вещи приходится делать "из-за угла", использовать побочный эффект конструкций. Лишний раз прогонять целый файл для исправления в нем какой-нибудь мелочи. Еще большая неприятность, это чувствительность оболочек ОС к специальным литерам и их комбинациям.
Из плюсов такой реализации можно отметить удобство объединения в скрипте самых разных команд, написанных на чем угодно.

Спойлер:
@ECHO OFF

SET status=garbage
FOR /F "usebackq delims=: tokens=1,*" %%i IN (`FINDSTR /N .* COMP.TXT`) DO CALL :%%status%% %%i "%%j"
EXIT /B

:GARBAGE
IF ""==%2 GOTO GRB_PST
SET line=%2
IF "\"=="%line:~1,1%" GOTO GRB_OBR
:GRB_GRB
ECHO %1 GXGI
ECHO %2
EXIT /B
:GRB_PST
ECHO %1 G0GI
EXIT /B
:GRB_OBR
ECHO %1 G\P
SET status=paths
GOTO PTH_OBR

:PATHS
IF ""==%2 GOTO PTH_PST
SET line=%2
IF "\"=="%line:~1,1%" GOTO PTH_OBR
FOR %%l IN (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z) DO IF /I "%%l "=="%line:~1,2%" GOTO PTH_PAR
IF "ТЕКСТ"=="%line:~1,5%" GOTO PTH_TXT
IF "ЗАПИСИ"=="%line:~1,6%" GOTO PTH_SAP
IF "ТАБЛИЦА"=="%line:~1,7%" GOTO PTH_TAB
:PTH_GRB
ECHO %1 PXG
SET status=garbage
GOTO GRB_GRB
:PTH_PST
ECHO %1 P0LI
SET status=param
EXIT /B
:PTH_PAR
ECHO %1 PLL
SET status=param
GOTO PAR_PAR
:PTH_OBR
ECHO %1 P\PI
ECHO %2
EXIT /B
:PTH_TXT
ECHO %1 PTTI
ECHO %2
SET status=text
EXIT /B
:PTH_TAB
ECHO %1 P#HI
ECHO %2
SET status=header
EXIT /B
:PTH_SAP
ECHO %1 PRHI
ECHO %2
SET status=header
EXIT /B

:HEADER
IF ""==%2 GOTO HDR_PST
:HDR_HDR
ECHO %1 HXHI
ECHO %2
EXIT /B
:HDR_PST
ECHO %1 H0TI
SET status=text
EXIT /B

:TEXT
IF ""==%2 GOTO TXT_PST
:TXT_TXT
ECHO %1 TXTI
ECHO %2
EXIT /B
:TXT_PST
ECHO %1 T0LI
SET status=param
EXIT /B

:PARAM
IF ""==%2 GOTO PAR_PST
SET line=%2
IF "\"=="%line:~1,1%" GOTO PAR_OBR
FOR %%l IN (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z) DO IF /I "%%l "=="%line:~1,2%" GOTO PAR_PAR
:PAR_GRB
ECHO %1 LXG
SET status=garbage
GOTO GRB_GRB
:PAR_PST
ECHO %1 L0GI
SET status=garbage
EXIT /B
:PAR_OBR
ECHO %1 L\P
SET status=paths
GOTO PTH_OBR
:PAR_PAR
ECHO %1 LLLI
ECHO %2
EXIT /B

3. Наиболее же наглядной реализацией остается старый добрый GW-BASIC.
- BASIC был основным языком первой части заметок.
- Как ни крути, различные BASIC-и являются основными языками программирования на IBM PC. Их достаточно легко найти: скачать GWBASIC.EXE (и, если захочется графики - dosbox, который обычно используют для запуска DOS-овских игр); или скачать любой из MS Visual Basic-ов (например, Visual Basic 3.0); или воспользоваться VBA из MS Office; или просто воспользоваться имеющимся в наличии WHS...
- Из всех BASIC-ов, GW-BASIC самый простой. Если уж на нем удастся написать все, что нам надо, то переписать на чем угодно не будет проблемой. В нем нет такого обилия мусора, как в более поздних версиях, и программы могут остаться читаемыми.

1000 REM GARBAGE
1010 IF LEN(R$)=0 THEN 2100
1020 IF LEFT$(R$,1)="\" THEN 2000
1030 GOTO 2200
1100 REM PATH
1110 IF LEN(R$)=0 THEN 2300
1120 IF MID$(R$,2,1)=" " THEN 2400
1130 IF LEFT$(R$,1)="\" THEN 2500
1140 IF LEFT$(R$,5)="ТЕКСТ" THEN 2600
1150 IF LEFT$(R$,7)="ТАБЛИЦА" THEN 2700
1160 IF LEFT$(R$,6)="ЗАПИСИ" THEN 2800
1170 GOTO 2900
1200 REM HEAD
1210 IF LEN(R$)=0 THEN 3000
1220 GOTO 3100
1300 REM TEXT
1310 IF LEN(R$)=0 THEN 3200
1320 GOTO 3300
1400 REM PARAM
1410 IF LEN(R$)=0 THEN 3600
1420 IF LEFT$(R$,1)="\" THEN 3500
1430 IF MID$(R$,2,1)=" " THEN 3400
1440 GOTO 3700

2000 REM GARBAGE - ОБРАТНАЯ КОСАЯ - PATH
2090 GOTO 2500
2100 REM GARBAGE - ПУСТО - GARBAGE
2190 LINE INPUT#1, R$: GOTO 1000
2200 REM GARBAGE - ПРОЧЕЕ - GARBAGE
2290 LINE INPUT#1, R$: GOTO 1000
2300 REM PATH - ПУСТО - PARAM
2390 LINE INPUT#1, R$: GOTO 1400
2400 REM PATH - БУКВА+ПРОБЕЛ - PARAM
2490 GOTO 3400
2500 REM PATH - ОБР.КОСАЯ - PATH
2590 LINE INPUT#1, R$: GOTO 1100
2600 REM PATH - "ТЕКСТ" - TEXT
2690 LINE INPUT#1, R$: GOTO 1300
2700 REM PATH - "ТАБЛИЦА" - HEAD
2790 LINE INPUT#1, R$: GOTO 1200
2800 REM PATH - "ЗАПИСИ" - HEAD
2890 LINE INPUT#1, R$: GOTO 1200
2900 REM PATH - ПРОЧЕЕ - GARBAGE
2990 GOTO 2200
3000 REM HEAD - ПУСТО - TEXT
3090 LINE INPUT#1, R$: GOTO 1300
3100 REM HEAD - ПРОЧЕЕ - HEAD
3190 LINE INPUT#1, R$: GOTO 1200
3200 REM TEXT - ПУСТО - PARAM
3290 LINE INPUT#1, R$: GOTO 1400
3300 REM TEXT - ПРОЧЕЕ - TEXT
3390 LINE INPUT#1, R$: GOTO 1300
3400 REM PARAM - БУКВА+ПРОБЕЛ - PARAM
3490 LINE INPUT#1, R$: GOTO 1400
3500 REM PARAM - ОБР.КОСАЯ - PATH
3590 GOTO 2500
3600 REM PARAM - ПУСТО - GARBAGE
3690 LINE INPUT#1, R$: GOTO 1000
3700 REM PARAM - ПРОЧЕЕ - GARBAGE
3790 GOTO 2200

Данная реализация имеет ограничение на длину строк и, при использовании в ОБЩЕЙ операции, на размер файла, но, зато, самая понятная из всех, невзирая на все эти GOTO.

ОБЩАЯ операция  построения полного "дерева" в памяти выглядит тогда так:

100 OPTION BASE 1:DIM P$(1024),L(1024): P=1024
110 DEF FNH(H,I)=((H*17+ASC(MID$(R$,I,1)))AND 1023)+1
200 DIM T(1024),C(1024),B(1024): Z=1

2510 GOSUB 6000

4000 REM ВСТАВКА ПОДСТРОКИ MID$(R$,N..K) В ХЭШ-ТАБЛИЦУ
4010 H=0
4020 FOR I=N TO K
4030 H=FNH(H,I)
4040 NEXT I
4050 Y=H
4060 IF MID$(R$,N,K-N+1)=P$(H) THEN RETURN
4070 H=L(H): IF H GOTO 4060
4080 IF P$(P)<>"" THEN P=P-1: GOTO 4080
4090 P$(P)=MID$(R$,N,K-N+1)
4100 L(P)=L(Y): L(Y)=P: H=P: RETURN

5000 REM ДОБАВЛЕНИЕ H К УЗЛУ T
5010 GOSUB 4000: C=C(T): B=0
5020 IF C GOTO 5060
5030 Z=Z+1: X=Z: T(X)=H
5040 IF B THEN B(X)=B(B): B(B)=X: T=X: RETURN
5050 B(X)=C(T): C(T)=X: T=X: RETURN
5060 IF T(C)=H THEN T=C: RETURN
5070 IF P$(T(C))<P$(H) THEN B=C: C=B(C): GOTO 5020
5080 GOTO 5030

6000 REM РЕГИСТРАЦИЯ ПУТИ
6010 T=1: N=2
6020 K=INSTR(N,R$,"\")
6030 IF K=0 THEN K=LEN(R$) ELSE K=K-1
6040 GOSUB 5000: N=K+2
6050 IF K<LEN(R$) GOTO 6020
6060 RETURN

Т.е. "дерево" строится в момент получения очередной "ветви" ("обратная косая" в состоянии Path). Дополнительные процедуры хранения строк (4000) и ветвей (5000) в ассоциативных массивах (и, особенно, большое количество связанных с этим служебных массивов - P$(), L(), T(), C(), B()) - на совести несовершенства GW-BASIC-а (и нашего желания писать на нем "правильно"). Очевидно, что более одной-двух таких "операций" BASIC-программа "не потянет" - станет слишком сложной для нашей игры.

Начало-конец программы:

500 OPEN "I",#1,"COMP.TXT"
510 ON ERROR GOTO 7000
520 LINE INPUT#1, R$

7000 CLOSE#1: END

Никакого диагностического вывода я не предусмотрел. Если вы, вдруг, вздумаете эту программу запускать, добавьте по вкусу.

4. Т.к. мне придется встраивать эту машину в НTML, уже без возможности нормального хостинга, то потребуется реализация на самом дебильном из всех известных мне языков программирования - на Java Script. Не хочу об этом говорить.


Последний раз редактировалось: Gudleifr (Вс Авг 12, 2018 11:44 am), всего редактировалось 11 раз(а)
avatar
Gudleifr
Admin

Сообщения : 908
Дата регистрации : 2017-03-29

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: 02.01. БЕЗ НАЗВАНИЯ

Сообщение автор Gudleifr в Ср Дек 20, 2017 8:06 pm

ОСНОВНАЯ ПОСЛЕДОВАТЕЛЬНАЯ ОПЕРАЦИЯ - ВЫРЕЗАТЕЛЬ

Просто так, приведенная пустая ПОСЛЕДОВАТЕЛЬНАЯ операция никому не интересна. Каким полезным смыслом ее можно наполнить?

Присмотревшись к проблемной части своей задачи, я обратил внимание на возможность наличия универсальной ПОСЛЕДОВАТЕЛЬНОЙ операции. Этот "кирпичик" - операция вырезания из файла куска информации. На входе - полный файл, а на выходе - остаток файла и вырезанный кусок. Это кажется естественным,  ведь разбиение информации по отдельным файлам в этой задаче встречалось постоянно (объединение заметок, сделанных на разных машинах, ускорение загрузки в сеть, попытки реорганизации материала). Возражения против постоянного перелопачивания файла при вырезании/слиянии не существенны. При современных объемах/скоростях это все почти ничего не весит.

Наблюдается некоторая аналогия с SQL - там тоже операция SELECT выполняет львиную долю работы. Только ее результат не может быть слит с общим файлом. Приходится для его изменения использовать другие операции.

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

Вторая машина, которая будет сортировать/вырезать строки (выдаваемые нашей первой машиной), тоже достаточно проста. Она должна уметь исполнять операции:
U - рассматривать текущую строку, как заведомо полезную;
S - рассматривать текущую строку, как заведомо бесполезную;
A - добавить текущую строку к потенциально полезным;
C - перевести потенциально полезные строки в заведомо полезные;
B - перевести потенциально полезные строки в заведомо бесполезные;
E - добавить пустую к заведомо полезным;
X - добавить пустую к  потенциально полезным;
T - добавить пустую к заведомо бесполезным.

Сложность заключается не в командах, а в условиях их выполнения. Какая команда выполняется, зависит от...
... текущего Состояния и Символа (18 описанных выше ситуаций), в т.ч. обрабатывается ли текущая строка или передается для обработки далее,
... того, куда засунули предыдущую строку - команды U (C или E), A (X), S (B или T),
... того, закончен ли предыдущий блок пустой строкой - три флага: для E, A и T,
... того, подходит ли текущая строка (в ситуации A) под условие "вырезания" (*).

Например, рассмотрим случай поиска блока мусора или "листа", содержащих некоторую строку (в заголовке или тексте).
После "очевидных" преобразований (разумеется, настоящие программисты так не делают, они честно просчитывают логику программы, но это слишком сложно) получилось что-то вроде таблицы:

СитуацияU*ASНовый флаг
G\P, G0GIE-BT-A
GXGI, HXHI, TXTIUCUA-По операции
P0LI, PLL--BT-По операции
P\PI, PTTI, P#HI, PRHI--A-По операции
PXG--BT-A
H0TIE-X-По операции
T0LIE-BT-По операции
LLLIU--SПо операции
L0GI, L\P, LXGE--TA
КонецE-BTT-

В хороших языках программирования, конечно вполне можно определить эту таблицу средствами адресной арифметики и, даже, определением специального языка "тасования строк". Учитывая, что я только рассмотрел примерную задачу, этот "язык" придется реализовать даже на GW-BASIC. Придется "компилировать на бумажке".
По сути, нам надо свести все наши "обработчики ситуаций" к тому, что мы виделе в главе про платформеры:

ОТРИСОВАТЬ(фигулька, условие, флаг)

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

5000 REM OБРАБОТКА КОМАНД
5010 IF F<>384 THEN 5040 'СТОЛБЕЦ УСЛОВИЯ U
5020 IF O AND 256 THEN GOSUB 4500: GOTO 5120 'E
5030 IF O AND 128 THEN GOSUB 4000: GOTO 5120 'U
5040 IF F<>120 THEN 5100 'СТОЛБЕЦ УСЛОВИЯ A
5050 IF O AND 64 THEN IF INSTR(R$,"однако") THEN GOSUB 4300: GOTO 5120 '*
5060 IF O AND 32 THEN GOSUB 4200: GOTO 5120 'A
5070 IF O AND 16 THEN GOSUB 4600: GOTO 5120 'X
5070 IF O AND 8 THEN GOSUB 4400: GOTO 5120 'BT
5100 IF F<>6 THEN 5120 'СТОЛБЕЦ УСЛОВИЯ S
5110 IF O AND 4 THEN GOSUB 4100: GOTO 5120 'S
5120 IF O AND 2 THEN GOSUB 4700 'T
5120 IF O AND 1 THEN F=120 ' УСТАНОВКА УСЛОВИЯ A
5130 RETURN

Т.е. в примере будем искать слово "однако".

Сами операции - ровно то, что мы хотим сделать со строками. Константы в комментариях - те, что использованы в коде обработки.

4000 REM ОПЕРАЦИЯ U. ГРУППА 384(U). ФЛАГ 128.
4010 PRINT#2,R$: EI=1: F=384: RETURN
4100 REM ОПЕРАЦИЯ S. ГРУППА 6(S). ФЛАГ 4.
4110 PRINT#3,R$: TI=0: F=6: RETURN
4200 REM ОПЕРАЦИЯ A. ГРУППА 120(A). ФЛАГ 32. ФЛАГ УСТАНОВКИ 1.
4210 A=A+1: A$(A)=R$: AI=1: F=120: RETURN
4300 REM ОПЕРАЦИЯ CU. УСЛОВИЕ 120(A). ФЛАГ 64.
4310 IF A=0 GOTO 4000
4320 FOR I=1 TO A: PRINT#2,A$(I): NEXT I
4330 A=0: EI=AI: AI=0: GOTO 4000
4400 REM ОПЕРАЦИЯ BT. ГРУППА 120(A). ФЛАГ 8.
4410 IF A=0 GOTO 4700
4420 FOR I=1 TO A: PRINT#3,A$(I): NEXT I
4430 A=0: TI=AI: AI=0: GOTO 4700
4500 REM ОПЕРАЦИЯ E. ГРУППА 384(U). ФЛАГ 256.
4510 IF EI THEN PRINT#2,"": EI=0
4520 F=384: RETURN
4600 REM ОПЕРАЦИЯ X. ГРУППА 120(A). ФЛАГ 256.
4610 IF AI THEN A=A+1: A$(A)="": AI=0
4620 F=120: RETURN
4700 REM ОПЕРАЦИЯ T. ГРУППА 6(S). ФЛАГ 2.
4710 IF TI THEN PRINT#3,"": TI=0
4720 F=6: RETURN

Остается только для каждой строчки таблицы вставить в код "пустой" машины нужную шкалу:

2010 O=265: GOSUB 5000: REM G\P
2110 O=265: GOSUB 5000: REM G0GI
2210 O=224: GOSUB 5000: REM GXGI
2310 O=8: GOSUB 5000: REM P0LI
2410 O=8: GOSUB 5000: REM PLL
2510 O=32: GOSUB 5000: REM P\PI
2610 O=32: GOSUB 5000: REM PTTI
2710 O=32: GOSUB 5000: REM P#HI
2810 O=32: GOSUB 5000: REM PRHI
2910 O=9: GOSUB 5000: REM PXG
3010 O=272: GOSUB 5000: REM H0TI
3110 O=224: GOSUB 5000: REM HXHI
3210 O=264: GOSUB 5000: REM T0LI
3310 O=224: GOSUB 5000: REM TXTI
3410 O=132: GOSUB 5000: REM LLLI
3510 O=259: GOSUB 5000: REM L\P
3610 O=259: GOSUB 5000: REM L0GI
3710 O=259: GOSUB 5000: REM LXG

и начало-конец

100 DIM A$(100)
110 TI=0: EI=0: AI=0
120 A=0: F=120

500 OPEN "I",#1,"COMP2.TXT"
510 OPEN "O",#2,"COMP3.TXT"
520 OPEN "O",#3,"COMP4.TXT"
530 ON ERROR GOTO 7000
540 LINE INPUT#1, R$

7000 O=266: GOSUB 5000: REM КОНЕЦ

7010 CLOSE#1,#2,#3: END

Конечно, можно упростить, перенести безусловную установку флага A в блок "вызовов", поджать разреженные шкалы... Но, здесь, нам важнее понять, что "табличное" решение гораздо проще "елочек" if-then-else и case... Пусть, даже и придется исписать пару салфеток в "Метрополе".
***

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

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

Однако, обычно полезны гораздо более ограниченные "вырезатели": точно этого (выбранного) листа, всего мусора, некой подстроки в любом месте листа, всех листов с русским текстом...

Наоборот, для выдачи полной информации о листе: всех его предках и потомках по всем путям, наследовании параметров по текущему пути, одной ПОСЛЕДОВАТЕЛЬНОЙ операции мало. Проще использовать ту же ОБЩУЮ операцию с построением полного дерева.
***

Как работает вырезатель, когда под рукой нет BASIC:



Из книги Акентьев В.С. Механизация инженерно-технического и управленческого труда.


Последний раз редактировалось: Gudleifr (Чт Авг 16, 2018 8:27 pm), всего редактировалось 13 раз(а)
avatar
Gudleifr
Admin

Сообщения : 908
Дата регистрации : 2017-03-29

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: 02.01. БЕЗ НАЗВАНИЯ

Сообщение автор Gudleifr в Чт Дек 21, 2017 10:55 pm

ЕЩЕ ОДНА УТИЛИТА

Выше были рассмотрены простейшие "навигатор" и "вырезатель" из базы данных.
Осталось чисто формально добавить к ним "добавлятор".
Теперь полный цикл работы ОБЩИХ, ПОСЛЕДОВАТЕЛЬНЫХ и ЧАСТНЫХ операций будет замкнут.
***
Программа развешивания на "ветвях" базы-"дерева" фрагментов-"листьев", очевидно, должна состоять из двух частей: буфера редактирования, куда будет загружаться очередной фрагмент (возможно использование дополнительной подпрограммы-вырезателя для подгрузки из другой части базы), и некоторого генератора путей (я убедился на своем опыте, что копирование и модификация путей от листа к листу составляет значительную часть работы).


На заднем плане - просмотрщик базы, слева - "эрзац-вырезатель" - Perl-скрипт вырезал кусок, который я засунул в текстовый редактор,
справа - "добавлятор". Кроме того, текстовый редактор, сам играет роль ОБЩЕГО супер-управлятора (пока база мала, его хватает).
Пока это очень мало похоже на игру.


Последний раз редактировалось: Gudleifr (Пт Фев 09, 2018 1:05 am), всего редактировалось 1 раз(а)
avatar
Gudleifr
Admin

Сообщения : 908
Дата регистрации : 2017-03-29

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: 02.01. БЕЗ НАЗВАНИЯ

Сообщение автор Gudleifr в Чт Дек 28, 2017 12:54 pm

ПРИМЕР УНИВЕРСАЛЬНОЙ НАВИГАЦИИ В БАЗЕ ДАННЫХ

Оставшись без сервера, я остался и без естественного способа визуализации - HTML. Но, нет худа без добра. Появился повод подумать и о том, что и как выводить на экран.
***

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

Во-вторых, отказ от очевидности WYSIWYG требует изобретения некоторой системы выдачи ровно того, что нас в данный момент интересует, в наиболее удобной форме. И чем беднее наши визуальные возможности, тем более формализованной должна быть эта система. По крайней мере, мне нравится так думать и изобретать такие штуки.

ПРИМЕР
Для больших баз данных я давно придумал систему "точек зрения". Т.е. сеть запросов, между которыми возможны переходы согласно логики работы с данными. На SQL-баз оказалось достаточным добавить к любой базе данных всего две таблицы:

9. Общие сведения.
Система интерактивной навигации в базе данных ГЛЮК основана на использовании двух служебных таблиц - СОСТОЯНИЙ и СВЯЗЕЙ. В каждый момент времени пользователь имеет какую-то информацию о текущей точки зрения на базу, список сущностей, видимых из этой точки,  возможность получить доступ к любой из этих сущностей и, наконец, возможность изменить точку зрения, обычно, опираясь на текущую сущность. Таблица СОСТОЯНИЙ содержит описания этих точек зрения а таблица СВЯЗЕЙ - переходы между ними. Здесь приведен пример реализации системы ГЛЮК в рамках ВАСЕЦ-Jet.

10. Таблица СОСТОЯНИЙ.
ЗАГ - заголовок точки зрения.
ТИП - наличие иерархии в списке сущностей (поля ИЕР в запросе ВЫБ).
ВЫБ - SELECT *,... AS ИД, ... AS ИМЯ [, ... AS ИЕР] FROM ... - начало запроса для получения списка объектов (ИД - первичный ключ;
ИМЯ - терминал - имя сущности; ИЕР - внутренняя ссылка).
ГДЕ - WHERE ... - внутренние условия.
ПРД - ORDER BY имя поля ИМЯ или ИЕР - упорядочение списка сущностей.
ОБЪ - запрос для получения доступа к выбранной сущности.

11. Таблица СВЯЗЕЙ.
СТАР - точка зрения - родитель (номер в СОСТОЯНИЯХ).
НОВ - точка зрения - потомок (номер в СОСТОЯНИЯХ).
ЗАГ - новый заголовок потомка.
ТИП - сохранит ли потомок иерархию.
ИЗ - довесок к ВЫБ - имена промежуточных таблиц.
ДОБ - довесок к ГДЕ - условия порождения.
ПВБ - запрос вспомогательной выборки.

12. Пример кортежа из таблицы СВЯЗЕЙ.
Идя от сотрудника подразделения, получить список сотрудников всех подчиненных подразделений:
ЗАГ = "СОТРУДНИКИ ПОДЧИНЕННЫХ ПОДРАЗДЕЛЕНИЙ";
СТАР = СОТРУДНИКИ;
ТИП = безразлично, т.к.  СОТРУДНИКИ.ТИП=НЕТ;
НОВ = СОТРУДНИКИ;
ИЗ = "ПОДРАЗДЕЛЕНИЯ,СТАВКИ";
ДОБ = "СТАВКИ.СОТРУДНИК=СОТРУДНИКИ.СОТРУДНИК AND СТАВКИ.ПОДРАЗДЕЛЕНИЯ=ПОДРАЗДЕЛЕНИЯ.ПОДРАЗДЕЛЕНИЕ AND ПОДРАЗДЕЛЕНИЯ.ИЕРАРХИЯ LIKE '<ВРМ>*'";
ПВБ = "SELECT ПОДРАЗДЕЛЕНИЯ.ИЕРАРХИЯ AS ВРМ FROM ПОДРАЗДЕЛЕНИЯ, СТАВКИ WHERE ПОДРАЗДЕЛЕНИЯ.ПОДРАЗДЕЛЕНИЕ=СТАВКИ.ПОДРАЗДЕЛЕНИЕ AND СТАВКИ.СОТРУДНИК=<СОТРУДНИК>".

Результаты запрсов легко втюхивались в универсальную форму-просмотрщик:

16. ВЗГЛЯД - окно просмотра БД, базирующееся на ГЛЮКЕ.
Взгляд на БД с какой-лиюо позиции, может быть, ограниченный ранее сделанным выбором, выглядит как список сущностей. ТЕМЫ - список связанных СОСТОЯНИЙ; выбор темы из списка помещает ссылку на текущую точку зрения в стек ПУТЬ и выполняет процедуру ВВЕРХ. ПУТЬ - пройденные точки зрения -  экранное отображение КОЛЛЕКЦИИ без последней строки; выбор из списка приводит к возврату к одной из старых точек зрения и удалению хвоста списка (и, соответственно КОЛЛЕКЦИИ, из которой и берутся данные, необходимые для возврата). ОБЪЕКТЫ - экранное отображение СПИСКА сущностей; выбор текущей сущности. СВОЙСТВА - список атрибутов текущей сущности. Кнопки <Открыть> - передать менеджеру пожелание что-либо сделать с текущей сущностью (обычно открыть соответствующую КАРТОЧКУ) или всем списком. Кнопки <Новая> и <Удалить> -  конечно сущность. ВЗГЛЯД может также применятся для расширенного выбора сущности.

Оказалось, что схожая механика работает и для описанного выше формата данных (кстати, он называется ГЛЮКВА). ПУТЬ - он и там, и там путь, ОБЪЕКТЫ - листьев-наследников, СВОЙСТВА - текст и параметры листа, ТЕМЫ - альтернативные пути к этому листу... Эта штука работала у меня на страничке. Правда, кроме удобства навигации, она с успехом служила эффективной "защитой от дурака"...

Дальнейшее совершенствование этого подхода должно бы привести к фукциональному разделению экранных форм, навроде "комнатной модели" ТЕМА #34...


Последний раз редактировалось: Gudleifr (Ср Фев 14, 2018 12:06 pm), всего редактировалось 2 раз(а)
avatar
Gudleifr
Admin

Сообщения : 908
Дата регистрации : 2017-03-29

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: 02.01. БЕЗ НАЗВАНИЯ

Сообщение автор Gudleifr в Пн Фев 12, 2018 11:28 am

ДЕЛАЕМ ИЗ МУХИ СЛОНА И НАОБОРОТ

Посмотрим на "блок-схему" игры, приведенную в первой главе записок. По идее, ЗАДАЧА 1, это преобразование "Идеи" в "Правила", пока без какой-либо спецификации "отдельных Машин".
В чем состоит наша "игра"?
Например, в X-Com игрок совершает некоторые игровые действия, по результатам которых ему постепенно открывается "полная энциклопедия инопланетян" - параграф за параграфом.
Для того, чтобы у нас получилось что-то подобное, нам надо... (далее - "поток сознания"):

I. Сформировать процедуру выбора "неготовых листьев". Этакая "Формализация Идеи". Как последовательно вырезать из огромного куска текста маленькие "карточки"? Одного разбиения на части, главы и прочие параграфы, как показывает мой опыт перевода, явно недостаточно. Мне не хватает знаний иностранного языка, чтобы делать все честно от начала до конца и с постоянной скоростью. Постоянно возвращаюсь к пройденным кускам, чтобы подправить перевод терминов или даже целых кусков, понятых задним числом. После долгих перерывов в работе очень часто хочется переделать "все".
- Проще всего брать листья подряд (но это совсем не интересно);
- Выбирать листья путем ручного перебора дерева, как в просмотрщике из прошлой главы (боюсь, что без какого-либо художественного "переосмыслятора" это будет занудно);

Для этого надо в т.ч. придумать какие-либо очевидые начальные пути. Например, у меня было такое разделение материалов (именно для STARGRUNT II):
1) Антуражные иллюстрации - очень "маловысокохудожественные". Кто-то из "художников" самовыражался, кто-то "для прикола" ретушировал реальные фотографии, кто-то явно творил, сидя на скучном заседании или лекции. Пропускаем. Интереснее создавать свой антураж.
2) Пояснительные иллюстрации - отрисованы получше, да и смысла в них побольше будет, надо их вырезать и вставлять в перевод.
3) Антуражные тексты - моих знаний английского языка явно недостаточно не только для литературного перевода, но даже для оценки качества и полезности этих художественных вставок. Пропускаем.
4) Сопроводительные тексты, в которых авторы пытаются обосновать оригинальность игры, рассказать о ее истории, посоветовать, какими модельками в нее играть... передают приветы родственникам, в конце концов. Пропускаем без вопросов.
5) Собственно правила. Надо переводить. С поправкой на то, что английский язык (в отличие от русского/немецкого) совершенно не приспособлен для передачи технических знаний, и после выливания обязательной воды размер текста уменьшается на порядок.
6) Типовые сценарии игры. Переводить, но - потом, если руки дойдут.
7) Конструирование подразделений и техники - самые для меня интересные разделы правил. Конечно, переводить.
8 ) Таблицы, краткие памятки-шпаргалки, примеры. Очень удобная для переводчика вещь. Почти билингва. По ним можно проверить правильность перевода правил. Сюда же можно отнести пояснительные иллюстрации и подписи под ними.
9) Описания типовой вселенной. Ничего интересного, за исключением некоторых примеров, относящихся к предыдущему разделу.

-  Искать листья по упоминающимся терминам (это и делают "вырезатели");
- Каким-либо образом сохранять информацию о предыдущих выборах пользователя и пытаться действовать "разумно";
- - Это нужно, чтобы программа могла "отвечать нам по-умному" или "выдавать нам что-то интересное". На язык кибернетики это можно перевести, соответственно, как "выдать то, что игрок ожидает" и "выдать игроку нечто неожиданное". Первое ограничивается способностью программы к построению модели игрока, второе - размером базы данных и непредсказуемостью генератора случайных чисел. Третья необходимая способность - (авторская) фильтрация, не допускающая выдачи белиберды. Две первых способности, в основном, реализуются "Оценками", а третья - "Логикой".
- - А где хранить "память"? Очевидно - в путях к просмотренным листьям.

II. Придумать подходящее "оглавление" для готовых листьев. Например, у меня получилось следующее (я даже попытался таким образом перетасовать пару своих переводов):

Что в первую очередь интересует игроков? Общие слова о том, что модель покрывает наземно-воздушные тактические боестолкновения 2000-2500гг.? Это только слова. Игроков интересует, какими фишками играть, как ходить и как побеждать? Первое, что приходит в голову: какова общая последовательность игры (настольная пошаговая, она, в конце концов, или компьютерная реального времени)? Так и запишем:

1) ПОСЛЕДОВАТЕЛЬНОСТИ - подготовки к игре, хода игры, фаз одного хода... Т.е. алгоритмы, которые можно жестко привязать к общему алгоритму игры. Последовательности указывают нам, какие действия следует предпринять в каждый конкретный момент времени, но не конкретизируют точный вид этих самых действий, ограничиваясь общими терминами. Конкретные действия зависят от конкретной обстановки на игровом поле и конкретных сил игрока, вовлеченных в это действие. Самая главная последовательность - алгоритм проведения партии. От подготовки к игре - до присуждения победы одному из игроков. Понятно, эта последовательность может быть разделена на совершенно разнородные фрагменты - последовательности подготовки поля боя и армий; разбиения игры на раунды, а раундов - на ходы; методы подсчета трофеев... "Глубина" вложения одних последовательностей в другие может быть совершенно различной в разных частях игры. Где-то формализмы практически полностью определяют действия игроков одно за другим, а где - все делается "по договоренности". Например, шахматы. Основная последовательность - расставить фигуры и играть. Собственно игра распадается на последовательность поочередных ходов, а те - на фазы, так же жестко определенные правилами: "взялся - ходи", "напал на короля - скажи: "Шах""... Последовательность же расстановки фигур жестко не определяется, например, игроки обычно сами решают, кому играть белыми. В Го в основную последовательность добавляется фаза подсчета очков по завершении партии. Возможны и "надпоследовательности", например, в шахматных турнирах, где в них описываются правила чередования партий, подсчет очков, шахматного этикета. Описывать последовательности естественно так же, как алгоритмы вычислений - блок-схемами или в виде пронумерованных абзацев.
***

Уже на этом этапе становится очевидным, какими мы должны играть фишками. Ведь, если мы встречаем фразу "походить тылом дивизии", то становится понятным, что отдельных фишек-танков не будет. Однако, встретив фразу "выстрелить из танка", игрок вправе задать вопрос: "А как?",-  значит надо конкретизировать, как стреляют все типы танков, допустимых в игре.

2) ЗАВИСИМОСТИ, конкретизирующие алгоритмы действий игрока, при обращении им с разными частями комплекта игры и/или нахождения в конкретном состоянии последовательности. Описание зависимости должно включать указание на конкретное ее место в игровой последовательности, условия ее применения и требования к фишкам (или другим частям игрового комплекта), в ней задействованных. Шахматный пример: "ход лошадью" - во время фазы перемещения, при отсутствии шаха, конем - далее описание буквы "Г". Конечно, нельзя не отметить, что в большинстве игр подобные описания называются просто "правилами".
***

В большинстве военных игр, бой происходит на нескольких уровнях. Например, основной - сражение танковых взводов, тогда уровнем выше отыгрываются арт- и авианалеты, способные уничтожить взвод разом, а уровнем ниже - действия спешенных пехотинцев, бросающихся на танки с гранатами и бутылками с зажигательной смесью. При скачках с уровня на уровень приходится прерывать основную последовательность игры и разрешать возникшую ситуацию.

3) ИСКЛЮЧЕНИЯ, т.е. описания случаев, когда следование конкретным алгоритмам приводит к нарушению последовательностей действий. Здесь мы сталкиваемся с разновидностью последовательностей, которые привязываются не столько к какому-либо состоянию более общей последовательности, но к какому либо условию.
***

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

4) УСЛОВИЯ, определяющие изменения состояния сил игрока или состояния игры, которые невозможно привязать к конкретной последовательности. Формат описания подобных правил по необходимости сильно отличается от перечисленных выше. В условиях описывается лишь результат действия, но не его алгоритм. Например: "королева любит свой цвет".
***

Вот, наконец, я добрался и до параметров. При данном подходе к описанию игр, параметры различных предметов из игрового комплекта и/или состояний игры выступают не как нечто самоценное, но только как значения, которые передаются от одного алгоритма другому.

5) ПАРАМЕТРЫ - переменные, используемые в алгоритмах игры. Важнейшая характеристика параметра - список алгоритмов, его использующих. Т.о. их описание должно обязательно включать ссылки на правила их использующие. Обычно, авторы этим пренебрегают. Это вполне объяснимо -  сразу становится наглядной ненужность многих параметров. Гораздо "наукообразней" подробно расписывать, в какую графу "паспорта" фишки нужное число крестиков поставить.
***

Что осталось? Только некоторые вопросы использования параметров в описанных выше алгоритмах. Очень часто к значению какого-нибудь параметра надо прибавить число, выпавшее на кубике, какие-то два числа надо сравнить и т.д. Причем, эти действия повторяются во многих игровых ситуациях и повторять их описания в алгоритмах не хочется.

6) ФОРМУЛЫ, жестко привязанные к параметрам и описывающие конкретные алгоритмы их связей и применения, использующиеся в разных контекстах/ситуациях игры.
***

К сожалению, прямолинейное следование изложенной системе до добра не доведет: во-первых, последовательности очень быстро заканчиваются, уступая место жуткому змеиному клубку условных условий, во-вторых, должен же где-то учитываться тот факт, что мы имеем дело не с обобщенной моделью непонятно чего, а с конкретной военной и, более того, сугубо тактической. Т.е. как ни крути, где-то должны быть правила перемещения, стрельбы, рукопашного боя и т.д. Возникает вопрос об однородности модели. На одном конце шкалы расположены модели однородные (как шахматы), где атака одной фишки другой происходит независимо от типов фишек (в шахматах - просто взятие, с двумя исключениями - атака короля и взятие на проходе). На другом конце - модели полностью неоднородные, где число видов схваток двух фишек разного типа примерно равно квадрату количества типов. (Тут надо заметить, что данная шкала, скорее всего, замкнута в кольцо, ведь, если каждые две фишки сражаются по своим правилам, то подобная исключительность становится правилом, только другого уровня). Очень часто встречаются квазиоднородные модели - в них бой проходит одинаково для всех фишек, но расчет боевой силы фишек отличается от фишки к фишке (как в игре BTH). Еще более интересны комплексные модели, где даже одиночный бой проходит не между отдельными фишками, но между некими их конгломератами, в которых каждому типу фишек отведено отдельное место. (Как в модели раздела Практики, где сила пехоты, танков и артиллерии учитывается в разных местах формулы.) Впрочем, все приведенные примеры достаточно сильно "притянуты за уши", т.к. чистые решения в играх встречаются крайне редко. Гораздо чаще в военных играх используется "объектно-ориентированный" подход: все важные правила оперируют некими "классами", а для каждой фишки подробно указывается, каким классам она принадлежит. В простейшем случае, почти все правила используют единую систему классов (например: пехота, пушка, танк, самолет...). В сложном, свои классы в правилах стрельбы (винтовки, пулеметы, пушки,), свои в правилах перемещения (пехота, колесные, гусеничные...), свои в правилах защиты (небронированные, бронированные...) и т.д. Часто, даже в простом случае, наблюдается уж воистину "объектно-ориентированная" иерархия классов. Что-то вроде: "Казаки относятся к кавалерии, а кавалерия движется как танки и воюет как пехота". Итак, добавляем:

7) НЕОДНОРОДНОСТИ в составе армий противников - особые рода войск, спецподразделения и т.д. И, соответственно, различные виды боя.

III. Каким-либо образом оформить привязку листьев к новым путям (красивый "добавлятор"). Собственно, "Построение Правил": как размещать переведенные куски таким образом, чтобы самому было интересно? Более того, чтобы создавалось впечатление, что машина что-то делает сама, радуя нас неожиданным результатом?
***

Хочется надеяться, что все эти "проблемы" не выходят за пределы манипулирования путями листьев. Надо только собрать коллекцию нужных "вырезателей", "просмотрщиков" и "добавляторов", и научиться собирать их в наборы "по смыслу".
avatar
Gudleifr
Admin

Сообщения : 908
Дата регистрации : 2017-03-29

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: 02.01. БЕЗ НАЗВАНИЯ

Сообщение автор Gudleifr в Сб Мар 17, 2018 11:20 am

Я ОПЯТЬ ЗАБЕЖАЛ ВПЕРЕД

Посмотрев на мои BASIC-огрызки выше, любой скажет, что порядочные люди так не пишут.
Ведь, со времен FORTRAN программы умели только две вещи: считать числа и распечатывать их, снабжая текстовыми заголовками. Ну, в BASIC добавилась возможность рисовать на экране линии и бибикать динамиком...

К чему все эти кодировки-раскодировки и стройные ряды GOTO?

Для обеспечения вашей программе трех возможностей, без которых она не поумнеет:
1. работать с текстовыми данными,
2. работать со структурами данных,
3. работать с программой как с данными.

Те языки, в которых такие возможности представлены изначально, всегда считались "для искусственного интеллекта", например, LISP. Встраивание же элементов этих "высоких технологий" в "обычные" языки часто подается как "прорыв, открывающий бескрайние горизонты". Например, работы того же Вирта, вроде "Алгоритмы + структуры данных = программы".

На самом деле, ничего сложного тут нет (об этом еще Кнут писал) и, даже, если доступа к этим возможностям нет в "классическом описании" языка, то он наверняка есть в конкретной машинной реализации.
***

ТЕКСТ

Сколько есть языков работы с текстом, столько есть методик этой самой работы.

Вариант первый: текст - это просто массив, массив символов.
Это не просто, но очень просто. Поэтому программы работы со строками на языке C выглядят зачастую проще, чем аналогичные программы на его потомках, имеющих специальный "строковый тип".

Единственный подводный камень - длина строк может быть разной, поэтому приходится разрабатывать для работы с ними специальную дисциплину работы с памятью, вплоть до введения полноценной "сборки мусора". Однако, в частном случае можно обойтись "малой кровью". Например, в FORTH строки можно хранить на тех же правах, как и остальные слова словаря.

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

Вариант второй. Строки, разбитые на поля фиксированной длины. Как это обычно практикуют в базах данных. Этот вариант даже проще первого, т.к. строки произвольной длины не допускаются. Но, все равно, его умудряются еще немного упростить, подменяя строковые значения числовыми (индексы в тех же базах данных), т.к. обычно разнообразие строк ограничено.

Вариант третий. Регулярные выражения. Если во втором варианте строки описывались списком полей, то здесь они описываются специальной "регулярной формулой". Это понятие математическое и разобраться с сопутствующей математикой гораздо проще, чем запомнить подробности конкретной реализации (например, в Perl). Знание математики сводится к построению конечного автомата, соответствующего данному выражению, что настолько просто, что может быть поручено самой программе. Что дают регулярные выражения? Одно из двух: либо разбор строки на значимые части (как выше поля, но гораздо гибче), либо изменение состояния программы, в зависимости от ввода (например, распознать текущий символ как префикс другого, сложного символа, см. выше многобайтовые символы).

Вариант четвертый.  Макроподстановки. Самый, что ни на есть классический. Строим машину, единственной функцией которой будет замена некоторых слов строки на другие. И получается самая настоящая вычислительная машина. Есть даже забавный язык программирования, на этом основанный - Trac, в котором макроподстановка вполне заменяет подстановку фактических параметров при вызове процедур. Дополнительным бонусом идет возможность сравнения строк "из которых выкинуто все лишнее", т.н. унификация в языках искусственного интеллекта (например Planner).

Отдельно идет возможность распознать начало строки и оставить остаток на потом. Например, прочесть одно слово (до пробела) и исполнить его - в FORTH. Или читать от скобки до скобки - в LISP.

Что из всего этого нам надо прямо сейчас, и что умеет наш BASIC?

В своем формате хранения данных я попытался развести разные ипостаси строк по разным частям моих информационных единиц.
Само разбиение текстового файла на единицы происходит по правилам регулярных выражений, в котором "символами" являются строки целиком: "начинающаяся с обратной косой", "пустая", "ТЕКСТ" и т.д.
Затем, если надо, сам строки разбиваются на части путем простейших псевдо-регулярных конструкций: "пути, разделенные обратными косыми", "поля таблиц, разделенные табуляциями", "имена и значения параметров, разделенные пробелом"...
Для строк - значений параметров - активно используется аппарат макроподстановок.

Несмотря на такую простоту, возможностей GWBASIC не хватает, вместо честного конечного автомата, распознающего тип строк, пришлось ограничиться набором примерно подходящих по смыслу условий с применением корявых вырезателей символов из строк - и GOTO для перехода от состояния к состоянию.

1100 REM PATH
1110 IF LEN(R$)=0 THEN 2300
1120 IF MID$(R$,2,1)=" " THEN 2400
1130 IF LEFT$(R$,1)="\" THEN 2500
1140 IF LEFT$(R$,5)="ТЕКСТ" THEN 2600
1150 IF LEFT$(R$,7)="ТАБЛИЦА" THEN 2700
1160 IF LEFT$(R$,6)="ЗАПИСИ" THEN 2800

Строковые операции GWBASIC рассчитаны на строки, разбитые на поля и немножко, на макроподстановку. Две основные: MID$ - извлечение и подстановка подстроки, считая по символам и INSTR - поиск подстроки. Плюс - танцы с бубном для нетривиальных случаев. К счастью, не надо беспокоиться об управлении памятью, но, к несчастью, ограничения ресурсов не позволяют полностью разместить распознанный текст в памяти.
***

СТРУКТУРЫ ДАННЫХ

В наследство от Машины Тьюринга нам достался вывод о том, что, в принципе, данные и код взаимозаменяемы. Что сложная программа с простыми данными, что простая со сложными. Например, навигация по нашей базе путем перебора всех строк и накопления результатов во временных файлах (последовательные операции) гораздо сложнее, чем перемещение по представляющему ее в памяти дереву (общая операция). Однако, ограниченные возможности GWBASIC не позволяют сложных данных. Приходится компенсировать кодом. Какие тут хитрости?

1. Любая сложная структура моделируется массивами.

В общей операции построения дерева

100 OPTION BASE 1:DIM P$(1024),L(1024): P=1024
200 DIM T(1024),C(1024),B(1024): Z=1

Здесь массивы P$ и L - это ассоциативное хранилище строк (массив структур с полями "строка" и "ссылка на следующую").
T, C и B - "дерево узлов" (массив структур с полями "ссылка на строку", "ссылка на старшего сына", "ссылка на младшего брата").

2. Никаких структур про запас. Все промежуточные результаты скидывать в файлы (только последовательные операции).

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

Отсюда и пошли у меня все эти вырезатели и добавляторы.

3. Заменять структуры операциями, операции обозначать кодами, коды сохранять в данных.

5040 IF F<>120 THEN 5100 'СТОЛБЕЦ УСЛОВИЯ A
5050 IF O AND 64 THEN IF INSTR(R$,"днако") THEN GOSUB 4300: GOTO 5120 '*
5060 IF O AND 32 THEN GOSUB 4200: GOTO 5120 'A
5070 IF O AND 16 THEN GOSUB 4600: GOTO 5120 'X
5070 IF O AND 8 THEN GOSUB 4400: GOTO 5120 'BT

Т.е. я не поддерживаю структуру файлов строк, следящих за правильным порядком узлов, а вызываю нужные для правильной записи узлов команды, "прошитые" в переменную О.
***

КОД КАК ДАННЫЕ

К сожалению, возможности BASIC тут совсем ограничены. Впрочем, как и многих других языков программирования.

Есть две основные возможности:

1. Добавлять код в программу по мере надобности (может, руками, может, автоматически).

В BASIC этот прием используется очень широко: в программе легко зарезервировать номера строк, куда программист будет вставлять свой код.

2300 REM PATH - ПУСТО - PARAM
2390 LINE INPUT#1, R$: GOTO 1400
2400 REM PATH - БУКВА+ПРОБЕЛ - PARAM
2490 GOTO 1400
2500 REM PATH - ОБР.КОСАЯ - PATH
2590 LINE INPUT#1, R$: GOTO 1100
2600 REM PATH - "ТЕКСТ" - TEXT
2690 LINE INPUT#1, R$: GOTO 1300
2700 REM PATH - "ТАБЛИЦА" - HEAD
2790 LINE INPUT#1, R$: GOTO 1200
2800 REM PATH - "ЗАПИСИ" - HEAD
2890 LINE INPUT#1, R$: GOTO 1200
2900 REM PATH - ПРОЧЕЕ - GARBAGE
2990 GOTO 1000

Т.е. нужный "пользовательский" код вставляется здесь между строками 2x00 и 2x90. С таким приемом мы уже встречались в главе про "искусственный интеллект"ТЕМА #63, АБЗАЦ #691 (там можно посмотреть и примеры работы со строками).

2. Создать свой простой "язык", который можно прошить в обычный массив.

В языках с адресной арифметикой (например, C) можно хранить адреса функций, но в BASIC приходится ограничиться набором IF-ов.

См. выше "чтение программы" из переменной O.
***

Вот, как-то так...
А в "настоящих" языках? Да, так же...


Последний раз редактировалось: Gudleifr (Чт Авг 16, 2018 8:11 pm), всего редактировалось 8 раз(а)
avatar
Gudleifr
Admin

Сообщения : 908
Дата регистрации : 2017-03-29

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: 02.01. БЕЗ НАЗВАНИЯ

Сообщение автор Gudleifr в Чт Мар 29, 2018 6:06 pm

К сожалению, жонглирование информационными структурами - это только часть проблемы. Точнее, это то, что относится, собственно, к программированию. Но нам надо еще это и запустить на своей машине. И тут начинается самое неприятное. Цепочка действий тут совершенно не такая, как в программировании. Не надо никакой математики. Не надо видения задачи. Надо только обвесить программу кучей всякой лабуды. Это не то, чтобы сложно, но очень нудно - по причине применения метода постепенной отладки.
Т.е. начинаем с пустой программы или примера из учебника. Добавляем какой-нибудь новый интерфейс. Валится? Лезем в Сеть, узнаем, почему. Исправляем. Работает? Добавляем еще один. Валится?.. Например, желание прицепить к этому форуму картинку с возможностью ее редактирования (чтобы обойти ограничения форума на хранение информации) вызвало три большие JavaScript-проблемы: как прицепить внешний файл, как работать с байтами, как создать картинку из текста. Вроде, работает, но не везде и не поручусь, что работает правильно.
Кроме нудности и неопределенности процесса, мешает и еще одно неприятное свойство системных интерфейсов - их нельзя выделить в компактные модули, которые можно написать один раз и потом просто прицеплять к разным программам. Например, когда вы пишете WIN-программу на MS Visual Studio C++, вас сначала долго мучают вопросами о необходимых интерфейсах (как и каким местом вы будете прицеплять вашу программу к MustDie). Затем вы получите набор файлов, в которые нужно вставлять вашу программу по кускам в специально выделенные места. И основное назначение "обезьянников" - скрыть от программиста код интерфейсов, который трогать нельзя. В случае с цеплянием файла к HTML оказалось, что все запихивать прочитанное из файла в документ можно только из той же функции, которая этот файл читает (из-за асинхронности чтения).

Итак, (написанная ранее) программа, из которой я буду делать JavaScript просмотрщик базы данных, состоит из плясок с бубном вокруг пяти интерфейсов:
1. XMLHttpRequest - открытие файла для чтения.
2. DataView - работы с байтовым массивом.
3. data:image/gif;base64 - вывода картинки прямо из текста.
4. base64 - перекодировки байтов картинки в этот формат.
5. Свойства объекта document - формирование нового содержимого документа.

Для просмотрщика (3) и (4) пока не нужны. Отрезаю. Вместо них вставляю
6. Самописный перекодировщик байтов из файла в кодировку utf-8.

Ну, пока можно остановиться и переписать на JavaScript, то, что мы писали на BASIC.
Конечно, после каждой новой строки перевыводил HTML для проверки. Стоило изменить зараз несколько строк, все падало замертво, и приходилось откатывать назад.
Попытался, заодно, почитать книжку по JavaScript, но меня быстро вытошнило.

Пришлось вспомнить как рисовать в HTML деревья:
7. Всякие style, onmouseover, onclick и прочая фигня (когда-то очень давно выломал из какой-то гостевой).

Вроде, дерево грузится. Можно грузить остальной HTML-обвес.
8. Все делаю самым простым способом - HTML-рамочками.

Макросы, таблицы и картинки пока реализовывать не буду (хотя, все, что для этого нужно, уже есть).

Осталось самое последнее - засунуть всю базу данных в GIF-формат. К сожалению в процессе обнаружилось, что хранилище картинок, которое на халяву прицеплено к моему форуму, не жрет GIF-ы более 1Mb.
9. Пока шифровать не буду, поэтому нужен только сам GIF-формат.

И что? Мы видим, что одно только перечисление технологий, нужных для встраивания программы в нашу операционную систему, весит столько же, сколько сама программа. По нынешним временам - это самое серьезное препятствие на пути изучения программирования. Более того, оно практически непреодолимо, т.к. "программист", войдя во вкус изучения этих чисто оформительских "технологий", забывает о самом программировании. Тем более, что единого универсального учебника на все очень простые, но очень разнообразные случаи нет.

Для наглядности "словаря интерфейсов" использовал для своих переменных, функций и меток только однобуквенные имена.
Посмотрим же на этого Шалтай-Болтая, прооперированного доктором Франкенштейном. Не забываем, что я здесь выступаю не как программист, а как "ерундит по интерфейсам".

<!-- ТЕХНОЛОГИЯ #8 - HTML-рамочки. Обратите внимание, весь этот текст набран в Юникоде, дальше это будет важно -->

<html><head>
<meta http-equiv="Content-Type"; content="text/html; charset=utf-8"></head>
<body bgcolor=#ccac9c text=#000000>

<!-- ТЕХНОЛОГИЯ #7 - стили для сокрытия/показа выпадающих списков -->

<style type="text/css">.S1 { display: none }</style>
<style type="text/css">.S2 { }</style>

<!-- ТЕХНОЛОГИИ #8 и #5 - HTML-рамочки, в которых метками I1-I3 отмечены места для вставки текста -->

<hr><table border=0 width=100%><tr><td valign=top>
<span id=I1>Файл будет грузится долго...</span>
</td><td align=right><table border=1><tr><td bgcolor=#9c8c7c>
<div id=I2>Ждите...</div>
</td></tr></table></td></tr></table><hr>
<div id=I3></div>

<SCRIPT language=javascript>
var A, B, D, F, G, J, K, L, O, P, Q, R, U, U, W, X, Y, Z;

// ТЕХНОЛОГИЯ #5 - свойства объекта document

F=String(document.location).match(/F=([^&]*)/);
document.title=F[1];

// ТЕХНОЛОГИЯ #1 - пляски с бубном. Привожу так, как выдрал из Сети.
// Насколько хорошо и в каких версиях разных Браузеров это работает - не знаю.

try { X = new ActiveXObject("Msxml2.XMLHTTP") } catch (E) {
try { X = new ActiveXObject("Microsoft.XMLHTTP") } catch (E) {
X = false }}
if (!X && typeof XMLHttpRequest!='undefined') {
X = new XMLHttpRequest() }

// Собственно то, что было в BASIC

function A1 () {
P = 0;
W = R.split("\\");
for (var V=1; V<W.length; V++) {
if (!Y[P][3]) Y[P][3] = {};
if (Y[P][3][W[V]]) P = Y[P][3][W[V]]
else {
Y.push([P, W[V], 0, 0]);
Y[P][3][W[V]] = Y.length-1;
P = Y.length-1 } }
Y[P][2] = L;
L[0][R] = P }

A = [[[/^\\/, function () { L = [{}, 0, [], [], {} ]; }, 1, 0],
[/^\s*$/, function () { }, 0, 1],
[0, function () { J.push(R) }, 0, 1]],
[[/^\s*$/, function () { }, 4, 1],
[/^[A-Za-z] /, function () { }, 4, 0],
[/^\\/, function () { A1() }, 1, 1],
[/^ТЕКСТ/, function () { L[1] = 1 }, 3, 1],
[/^ТАБЛИЦА/, function () { L[1] = 2 }, 2, 1],
[/^ЗАПИСИ/, function () { L[1] = 3 }, 2, 1],
[0, function () { }, 0, 0]],
[[/^\s*$/, function () { }, 3, 1],
[0, function () { L[2].push(R) }, 2, 1]],
[[/^\s*$/, function () { }, 4, 1],
[0, function () { L[3].push(R) }, 3, 1]],
[[/^[A-Za-z] /, function () { L[4][R[0]] = R.slice(2) }, 4, 1],
[/^\\/, function () { L = [{}, 0, [], [], {} ]; }, 1, 0],
[/^\s*$/, function () { }, 0, 1],
[0, function () { }, 0, 0]]];

// ТЕХНОЛОГИЯ #3 - хранение GIF-ов в тексте HTML

O = ["<img src=\"data:image/gif;base64,"+
"R0lGODlhEAAQANIAABw8ADxsDGyMANzMvP///7ysnAAAAAAAAC"+
"H5BAlkAAQALAAAAAAQABAAAAM4SLrc/pCIKYKIdIb9ZinaFjTe"+
"F27XUlIip2ZVO75sANzArMg2njM8HyC1kPl0QBEOSWoRI9AoIw"+
"EAOw==\" />",
"<img src=\"data:image/gif;base64,"+
"R0lGODlhEAAQANIAABw8ADxsDGyMALysnP///wAAAAAAAAAAAC"+
"H5BAlkAAQALAAAAAAQABAAAAMrSLrc/pCJ6ESgMlxMrK7CMAik"+
"9klkapqoGgAwsCmrFsPYzcUcgfeznjCSAAA7\" />",
"<img src=\"data:image/gif;base64,"+
"R0lGODlhEAAQANIAABw8ADxsDGyMALysnP///wAAAAAAAAAAAC"+
"H5BAlkAAQALAAAAAAQABAAAAMrSLrc/lCJGeKaoloy6ObehmkW"+
"RTaYCazASQQwzK5PHMxRzG4y8L2un/CRAAA7\" />",

// ТЕХНОЛОГИЯ #7 - рамочки

"<table border=0 cellspacing=0 cellpadding=0><tr>"+
"<td bgcolor=#bcac9c>&nbsp;</td><td bgcolor=#8c7c6c><b>",
"</td><td bgcolor=#5c4c3c>&nbsp;&nbsp;</td></tr><tr>"+
"<td bgcolor=#dcccbc>&nbsp;</td><td bgcolor=#9c8c7c>",
"</td><td bgcolor=#5c4c3c>&nbsp;</td></tr>"+
"<tr bgcolor=#5c4c3c><td bgcolor=#8c7c6c>&nbsp;&nbsp;"+
"</td><td colspan=2>&nbsp;</td></tr></table>"];

// ТЕХНОЛОГИЯ #7 - ф-ии сворачивания/разворачивая списка

function C(P) {
Q = document.getElementById("N"+P);
if(Q.className == "S1") {
Q.className = "S2";
document.getElementById("M"+P).innerHTML = O[2]
} else {
Q.className = "S1";
document.getElementById("M"+P).innerHTML = O[1] }
return false }

// ТЕХНОЛОГИЯ #8 - заполнение табличек

function T2(Z,P,W) {
return "<a onmouseover=\"this.style.cursor='pointer'\" "+
"onclick=\"return "+Z+"("+P+");\"><font color=#dcccbc>"+
"<u>"+W+"</font></u></a>" }

function T1(P) {
W = "";
while (P) {
if (Y[P][2])
W = "\\"+T2("T",P,Y[P][1])+W
else
W = "\\"+Y[P][1]+W
P = Y[P][0] }}

function T(P) {
B = "<h3>"+T2("T",0,(J.length?J[0]:F[1]))+"</h3>"
if (P) {
B += O[3]+"ТЕКУЩИЙ ПУТЬ:"+O[4];
B += O[0]+Y[P][1]+"<br>";
T1(Y[P][0]);
if (W) B+= O[1]+W+"<br>";
B += O[5] + "<br>" + O[3] + "ОСТАЛЬНЫЕ ПУТИ:" + O[4];
for (V in Y[P][2][0]) if (Y[P][2][0][V]!=P) {
T1(Y[P][2][0][V]);
B += O[1]+W+"<br>" }
B += O[5] + "<br>" + O[3] + "БРАТЬЯ:" + O[4];
for (V in Y[Y[P][0]][3]) if (Y[Y[P][0]][3][V]!=P && Y[Y[Y[P][0]][3][V]][2])
B += O[1]+T2("T",Y[Y[P][0]][3][V],V)+"<br>";
B += O[5] + "<br>" + O[3] + "СЫНОВЬЯ:" + O[4];
for (V in Y[P][3]) if (Y[Y[P][3][V]][2])
B += O[1]+T2("T",Y[P][3][V],V)+"<br>";
B += O[5]; }
document.getElementById("I1").innerHTML = B;
B = "";
if (P) {
L = Y[P][2];
for (V = 0; V<L[2].length; V++) B += L[2][V]+"<br>";
B += "<hr>";
for (V = 0; V<L[3].length; V++) B += L[3][V]+"<br>";
B += "<hr>";
for (V in L[4]) B += "["+V+"] "+L[4][V]+"<br>" }
else for (V = 0; V<J.length; V++) B += J[V] ;
document.getElementById("I3").innerHTML = B;
return false }

function H(P, Z) {
var W = [];
B += "<div style=\"margin-left: "+Z+"px\">";
if (Y[P][3]) {
B += T2("C",P,"<span id=M"+P+">"+O[1]+"</span>");
} else B += O[0];
if (Y[P][2]) {
B += T2("T",P,Y[P][1])
} else B += Y[P][1];
B += "</div>";
if (Y[P][3]) {
B += "<div class=S1 id=N"+P+">";
for (var V in Y[P][3]) W.push(V);
W.sort();
for (var V=0; V<W.length; V++) H(Y[P][3][W[V]], Z+20);
B += "</div>" }}

// ТЕХНОЛОГИЯ #1 - пытаемся достучаться до файла

X.open("GET", F[1], true);
X.responseType = "arraybuffer";
X.send(null);

// ТЕХНОЛОГИЯ #9 - расковыривание GIF

function D2 () {
V = 13;
K = D[0].getUint8(10);
if (K&128) V += ((1<<((K&7)+1))*3);
do {
K = D[0].getUint8(V);
if (K==44) {
K = D[0].getUint8(V+9);
V += 11;
if (K&128) V += ((1<<((K&7)+1))*3);
while (K=D[0].getUint8(V)) V += K+1;
V++ }
} while (K!=33);
V += 2 }

// Ф-ия, которая все и делает

function D1 () {
Y = [[0 , "СОДЕРЖАНИЕ", 0, 0]];
J = [];
R=""; G=0;
while (K=D[0].getUint8(V++)) {
D[1]=V+K;
for (; V<D[1]; V++) {
K=D[0].getUint8(V);
if(K==10) { }
else if(K==13) { do {
for (var U=0; U<A[G].length; U++) {
if (!A[G][U][0]||A[G][U][0].exec(R)) {
A[G][U][1]();
if (A[G][U][3]) R = "";
G = A[G][U][2];
break }}} while (R) }

// ТЕХНОЛОГИЯ #6 перекодировщик из Win-1251 в Юникод
// (вот где важна кодировка нашего HTML)

else R += ("*********\t**********************"+
" !\"#$%&'()*+,-./0123456789:;<=>?"+
"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ "+
"****************************************************************"+
"АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя")[K] } } }

// ТЕХНОЛОГИЯ #1 - проверка, готов ли файл.
// Обратите внимание: все считывание и отрисовка происходят внутри этой
// ф-ии, вызываемой асинхронно, по готовности файла.

X.onreadystatechange = function () {
if (X.readyState == 4) {
D = [X.response];

// ТЕХНОЛОГИЯ #2 - получение доступа к готовому файлу

D[0] = new DataView(D[0]);
D2();
D1();
B="";
H(0, 0);
document.getElementById("I2").innerHTML = B;
T(0)}}

</SCRIPT>
</body></html>

Что получилось (для навигации по СОДЕРЖАНИЮ, жмите на стрелочки): Кусок редактируемой БД в сыром виде


Последний раз редактировалось: Gudleifr (Вс Авг 05, 2018 5:09 pm), всего редактировалось 6 раз(а)
avatar
Gudleifr
Admin

Сообщения : 908
Дата регистрации : 2017-03-29

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: 02.01. БЕЗ НАЗВАНИЯ

Сообщение автор Gudleifr в Вс Апр 15, 2018 9:19 am

ПОРА ЗАКАНЧИВАТЬ

К чему все эти попытки найти какие-то общие черты в самых разнообразных текстовых/гипертекстовых описаниях непонятно-чего? Ведь, есть же визуальное программирование! Если у вас установлен какой-нибудь Visual Basic (или его младший брат Delphi, Power C++, Visual C# и т.п.), вы без труда сможете создать по отдельному Windows-окошку для доступа к любой порции данных/текста. Некоторые умельцы умудряются создавать текстовые игры на основе баз данных или электронных таблиц. Чем плохо?

Скажу:
1. Визуальное программирование "на чем-то серьезном", как писал выше, достаточно затратное дело. Откладывать солдатиков и изучать новые технологии?
2. "Рисование окошек" по правилам "современных технологий" относится не к игре, а к программированию игры. Не только в смысле "серьезности дела", но и в смысле невозможности создания/доделывания игры в процессе самой игры.

А я - за неуглубление внутрь машины более необходимого и за возможность играть в создание игры.
***

В чем состоит игра?
Есть некие ФАКТЫ, данные мне в ощущении. И есть мои МЫСЛИ по поводу них. Игра - упорядочение этих МЫСЛЕЙ в какой-то форме. МЫСЛЬ может быть выражена в виде некоторой структуризации ФАКТОВ. Может - в использовании ФАКТОВ в виде констант некоторых программ. Может - в выборе представления ФАКТОВ игроку. В отличие от ФАКТОВ, МЫСЛИ не имеют какой-либо окончательной формы и могут сменять друг друга по мере игры.
В такой трактовке, все что нам надо от программирования, это иметь возможность записи МЫСЛЕЙ. Наших МЫСЛЕЙ, достаточно простых, и, возможно, примитивных. Важна не изощренная способность записи изощренных МЫСЛЕЙ (называемых алгоритмами, парадигмами, технологиями и движками), а простая возможность простой записи. Сел за компьютер, записал/прочел, что надо, и забыл до следующего раза..

Если механизм обмена МЫСЛЯМИ с компьютером будет достаточно прост, чтобы быть работоспособным, и достаточно сложным, чтобы удовлетворить нашу потребность в структуризации данных, то мы получим тот самый баланс ожидаемого и неожиданного, который желателен от машинного интеллекта (см. главу "Про кота").
avatar
Gudleifr
Admin

Сообщения : 908
Дата регистрации : 2017-03-29

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: 02.01. БЕЗ НАЗВАНИЯ

Сообщение автор Gudleifr в Вс Апр 15, 2018 9:23 am

Я все пытаюсь доказать, что на самом убогом компьютере и при любом уровне программирования можно сыграть в игру - построение информационной модели некоего процесса (в т.ч. другой игры). Это называется:

Гете пишет:МОРФОЛОГИЯ еще должна легитимироваться, как особая наука, делая своим главным предметом то, что в других трактуется при случае и мимоходом, собирая то, что там рассеяно, и устанавливая новую точку зрения, позволяющую легко и удобно рассматривать вещи природы. Явления, которыми она занимается, в высшей степени значительны; те умственные операции, при помощи которых она сопоставляет явления, сообразны с человеческой природой и приятны ей, так что даже неудавшийся опыт все-таки соединит в себе пользу и красоту.

Эту цитату я выдрал из книги Проппа Морфология ВОЛШЕБНОЙ СКАЗКИ.
А вот еще пара цитат из этой книги:

Приведенный здесь фрагмент взят из книги: М.Г.Гаазе-Раппопорт, Д.А.Поспелов, "От амебы до робота: модели поведения", М., Наука, 1987.

В конце двадцатых годов XX века советский исследователь В.Пропп пришел к выводу, что все волшебные сказки состоят из одного и того же небольшого набора базовых элементов, а любая сказка - одно из возможных их сочетаний. Более того, Пропп описал все возможные сочетания базовых элементов и построил сюжет универсальной волшебной сказки, который и исчерпывал весь мир сказок. Рассмотрим его подробнее.
***

Персонажи волшебных сказок действуют в особом мире, мало похожем на реальный. В сказочном мире нет привычного для нас времени, нет и того пространства, которые определяют наши перемещения. Сказочные герои перемещаются в своем мире как бы мгновенно. И лишь традиционные формулы типа "Скоро сказка сказывается, да не скоро дело делается" или "Долго ли, коротко ли, но прибыл Иван в Кащеево Царство" очерчивают все эти передвижения в пространстве и бег времени. Для волшебных сказок характерна еще одна особенность. Их персонажи не рассуждают, а действуют, как это предписывается их ролями. Герой всегда преследует врага, борется с ним и побеждает; глупый царь всегда остается в проигрыше, а Баба-Яга всегда оказывается обманутой. В поступках действующих лиц как бы нет той части, которая относится к замыслу, и в повествование включается лишь реализация поступка с априорно предсказуемыми оценками. Далее, каждый персонаж не имеет выбора при необходимости совершить поступок. Ритуальность поведения в волшебной сказке доведена до своего логического завершения. Немыслимо, чтобы герой, проанализировав возможные отрицательные последствия, отказался от битвы со своим противником, и столь же невозможно раскаяние антигероя.

(->)Появление Героя с богатыми подарками и рассказ его о
том, как это получилось
(?)Встреча Ложного Героя с Дарителем
(!)Если Даритель просит что-нибудь сделать, то отказаться
сделать это
(->)Отказ Дарителя от оказания помощи

(Здесь появляются уже какие-то наметки семантики будущего языка - блоки пред- и постусловий, условие и центральная часть.) Поясним эту продукцию. В волшебных сказках действует весьма малый набор персонажей. Он включает в себя Героя, Антигероя, Помощника Героя, Ложного Героя, Помощника Антигероя, Дарителя, Глупца, Невесту и Прорицателя. В сказке часть этих персонажей может присутствовать в виде нескольких конкретных воплощений. У Героя может быть несколько Помощников, может быть не один Даритель и т.д. Единственными бывают только Герой, Антигерой и Невеста, которая играет роль награды, получаемой Героем после успешной победы над Антигероем. Все эти персонажи в сказке как-то конкретизируются. Герой может быть Иванушкой-дурачком, а может быть и царским сыном. Антигероем может быть Кащей Бессмертный, но им может быть и Змей Горыныч. Некоторые персонажи могут в сказке и отсутствовать. Таков например, Прорицатель, заранее предсказывающий некоторые события, которые должны случиться в сказке. Рассмотренная продукция пригодна для любой реальной конкретизации героя. Он на то и Герой, чтобы двигаться в в место расположения Антигероя (локус), биться с ним и победить. Встреча с Дарителем - не обязательный элемент волшебной сказки. Бывают сказки, в которых Герой и без Дарителя приходит к цели, но уж если возникло такое условие, то поведение Героя, определяемое центральной частью продукции, всегда одинаково. Настоящий Герой всегда выполнит просьбу Дарителя. По-другому ведет себя Ложный Герой (вспомните, например, поведение любимой дочки в многочисленных вариантах сказок о падчерице, посылаемой злой мачехой в лес на верную гибель и возвращающейся оттуда на зависть этой дочке и мачехе живой и получившей подарки). Продукция, определяющая поведение Ложного Героя при встрече с Дарителем, имеет следующий вид:

(->)Погоня Помощника Антигероя за Героем
(?)Наличие волшебных даров. Их больше одного
(!)Если Помощник Антигероя догоняет Героя, то использовать очередной волшебный дар
(->)Задержка Помощника Антигероя. Уменьшение числа волшебных даров на единицу

(->)Погоня Помощника Антигероя за Героем
(?)Наличие одного волшебного дара
(!)Если Помощник Антигероя догоняет Героя, то использовать волшебный дар
(->)Гибель Помощника Антигероя или отказ его от погони

(->)Погоня Помощника Антигероя за Ложным Героем
(?)Отсутствие волшебных даров
(!)Если Помощник Антигероя догоняет Ложного Героя, то гибель
(->)Прекращение линии Ложного Героя

И еще - все фунции (31 штука), допустимые в сказках (причем только в приведенной ниже последовательности):

ПОДГОТОВИТЕЛЬНАЯ ЧАСТЬ
1ОтлучкаУезжают родители; царь идет на войну
2Запрет"Не заходи только в десятую комнату"
3НарушениеПобежала Аленушка на улицу, заигралась
4ВыведываниеСтала ведьма вызнавать...
5Выдача"Но царевна все ж милее..."
6ПодвохВолк подражает голосу мамы-козы
7ПособничествоЦаревна ест предложенное старухой яблочко
8Вредительство или недостачаСхватили гуси-лебеди Иванушку,заболел царь тяжелой болезнью
ЗАВЯЗКА
9Посредничество"Иди, Марьюшка, братца искать..."
10Начинающееся противодействие"Позволь мне, царь, попытать счастья..."
11ОтправкаЦаревич отправился в путь
ОСНОВНАЯ ЧАСТЬ
12Первая функция дарителяСтала Баба-Яга вопросы спрашивать
13Реакция героя"Ты б меня сперва накормила..."
14Получение волшебного средства.Дал старичок Ивану коня;"Скажи: по щучьему велению..."
15Перемещение в иное царствоДолго ли шла Марьюшка, коротколи...
16БорьбаСтал Иван биться со Змеем
17КлеймениеРасцарапал ему Змей всю шею
18ПобедаЗавертелся Кощей и сгинул
19Начальная беда или недостача ликвидируетсяВышла к Ивану из подземелья Царь-девица.
20ВозвращениеСели на ковер-самолет, полетели домой
21ПогоняБросились гуси-лебеди вдогонку
22СпасениеБросила она зеркальце, разлилось море.
На этом сказка может кончиться, но часто встречается дополнительный сюжет, в котором действует лжегерой (чаще всего брат или братья главного персонажа). Первая его часть новое вредительство -аналогична функциям 8-15
Лжегерой похищает добычу
10а-11аГерой снова отправляется на поиски
12а-14аГерой снова находит волшебное средство.
Далее при таком развитии появляются новые функции:
23Неузнанное прибытиеПриехал в родной город, но домой непошел, стал учеником портного.
24Необоснованные притязанияГенерал заявляет царю: "Я - змеевпобедитель"
25Трудная задача"Кто поднимет змеиную голову..."
26РешениеПодошел Иван, только тронул...
27УзнаваниеПоказал он заветное колечко
28ОбличениеРассказала все царевна, как было
29ТрансфигурацияИскупался Иван в молоке, вышел лучшепрежнего
30НаказаниеПосадили служанку в бочку...
31Свадьба, воцарениеПолучил Иван царевну и полцарства
avatar
Gudleifr
Admin

Сообщения : 908
Дата регистрации : 2017-03-29

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: 02.01. БЕЗ НАЗВАНИЯ

Сообщение автор Спонсируемый контент


Спонсируемый контент


Вернуться к началу Перейти вниз

Вернуться к началу


 
Права доступа к этому форуму:
Вы не можете отвечать на сообщения