KRIEGSSPIELE!

GUDLEIFR СОЛДАТИКИ FORTH gudleifr.h1.ru
 
ФорумФорум  КалендарьКалендарь  ЧаВоЧаВо  ПоискПоиск  ПользователиПользователи  ГруппыГруппы  РегистрацияРегистрация  ВходВход  

Поделиться | 
 

 01.07. ЧЕМОДАН ЭЛЕКТРОННЫХ СОЛДАТИКОВ

Перейти вниз 
АвторСообщение
Gudleifr
Admin
avatar

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

СообщениеТема: 01.07. ЧЕМОДАН ЭЛЕКТРОННЫХ СОЛДАТИКОВ   Ср Дек 06, 2017 3:06 pm

ГЛАВА СЕДЬМАЯ. ЧЕМОДАН ЭЛЕКТРОННЫХ СОЛДАТИКОВ

Собрав такую коллекцию отдельных миниигр, можно поставить, наконец, вопрос о "скелете" игры. Конечно, сейчас каноническим является игровой мир в виде совокупности большого количества простых элементов, но раньше все было не так. От концепции "компьютерного противника" в виде некого "сверхобъекта" отказаться было трудно. Ведь должна же компьютерная игра быть компьютерной, а не просто переносом на экран обычного гексово-жетонного объекта.
Т.е. берем HAMMURABI и учим его командовать армией...


Последний раз редактировалось: Gudleifr (Чт Дек 07, 2017 10:19 am), всего редактировалось 1 раз(а)
Вернуться к началу Перейти вниз
Посмотреть профиль
Gudleifr
Admin
avatar

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

СообщениеТема: Re: 01.07. ЧЕМОДАН ЭЛЕКТРОННЫХ СОЛДАТИКОВ   Ср Дек 06, 2017 3:19 pm

STAR TREK

Листинг - JPG/RAR, 1.58Мб.

Как и положено родоначальнику, игра очень проста. И очень похожа на "B-1 NUCLEAR BOMBER".
Тот же цикл вокруг ВЫБОРА команд, тот же тригонометрический калькулятор, тот же разруливающий финальный блок.
Главное отличие - предельно формализованная вселенная, позволяющая любые расширения (ТЕМА #28, АБЗАЦ #167). Это сделало STAR TREK тем же, чем TALISMAN является для игр настольных - универсальной базой игр-конструкторов.

10 КОММЕНТАРИИ
220 ЗАГОЛОВОК
260 МАССИВЫ ДАННЫХ И ПАРА ФУНКЦИЙ
1230 ПРИГЛАШЕНИЕ
1320 ВХОД В НОВЫЙ КВАДРАНТ
1980 ^^6420
1990 ЭНЕРГИИ ДОСТАТОЧНО^2060
2020 "НЕХВАТКА ЭНЕРГИИ", ^6220
2060 ВЫБОР КОМАНДЫ: 2290,1980,3990,4250,4690,5520,5680,7290,6270
ВСЕ ИСКЛЮЧЕНИЯ ИЗ КОМАНД - ^1990
2290 ПЕРЕМЕЩЕНИЕ КОРАБЛЯ, ТЕЧЕНИЕ ВРЕМЕНИ, РЕМОНТ, ^1980
В Т.Ч. ВЫХОД В СЛЕДУЮЩИЙ КВАДРАНТ, ^1320
2590 ПЕРЕМЕЩЕНИЕ КЛИНГОНОВ
2700 ^^5990
3900 ПОДПРОГРАММА ИЗМЕНЕНИЯ E И S^
3990 ДАЛЬНИЙ РАДАР, ^1990
4250 ФАЗЕР, ПО ВСЕМ КЛИНГОНАМ РАЗОМ, ^1990
4650 КЛИНГОНЫ КОНЧИЛИСЬ^6370
4670 ^^5990
4690 ТОРПЕДЫ, НАДО УКАЗЫВАТЬ КУРС, ^1990
5110 КЛИНГОНЫ КОНЧИЛИСЬ^6370
5210 ПОПАДАНИЕ В ЗВЕЗДУ
5280 ПОПАДАНИЕ В БАЗУ (ВОЗМОЖЕН ПРОИГРЫШ - ^6270)
5490 ^^5990
5520 УСТАНОВКА МОЩНОСТИ ЩИТОВ, ^1990
5680 РЕМОНТ, ТЕЧЕНИЕ ВРЕМЕНИ, ОТЧЕТ, ^1990
5990 ПОДПРОГРАММА СТРЕЛЬБЫ КЛИНГОНОВ^
6090 ЩИТЫ ПРОБИТЫ^6240
6140 ПОВРЕЖДЕНИЯ ОТСЕКОВ
6210-6370 КОНЕЦ ИГРЫ
6330 НОВАЯ ИГРА^10
6240 БЛИЖНИЙ РАДАР (ОДИН КВАДРАНТ), СТАТУС^
6490 ПРОВЕРКА СТЫКОВКИ С БАЗОЙ
7280 ВЫБОР КОМАНДЫ КОМПЬЮТЕРА: 7530,7890,8060,8500,8150,7390
7390 КАРТА ГАЛАКТИКИ (СТАТИСТИКА), ^1990
7530 ДОП.ВХОД ДЛЯ ИМЕН
7630 ВЫВОД СТАТИСТИКИ
7740 ВЫВОД ИМЕН
7890 "ХОД КАМПАНИИ", ^5690
8010 "ВСЕ БАЗЫ ПОТЕРЯНЫ!", ^5690
8060 РАССЧИТАТЬ КУРС НА ВСЕХ КЛИНГОНОВ, ^1990
8150 ДОП.ВХОД ДЛЯ ЛЮБЫХ 2-Х ТОЧЕК
8500 ДОП.ВХОД ДЛЯ КУРСА НА БАЗУ
8580 ПОИСК ПУСТОГО МЕСТА НА КАРТЕ КВАДРАНТА^
8670 ЗАПИСЬ НА КАРТУ КВАДРАНТА^
8780 ИМЯ ОТСЕКА^
8820 СВЕРКА С КАРТОЙ^
9010 ИМЯ КВАДРАНТА^

Все, в общем-то, очевидно. Особенно, то, что BASIC провоцирует программиста писать код как попало. Почему один код выделен в подпрограмму, другой продублирован, а третий доступен путем переходов с "указанием обратного адреса"? Вплоть до установки флага "невхода в цикл", перехода внутрь цикла и выпрыга из него по флагу, не доходя до NEXT (см. 8150).
***

Можно также заметить, что калькулятор вытащен из программы наружу и игроку позволено кое-что считать самому.
***

Самое же необычное для нас, что на экран выводится только то, что мы попросили. Никаких постоянно висящих на экране декораций. Игра т.о. больше напоминает программирование, чем "руление кораблем".
Однако, такой подход нам дает целых два забавных способа расширения игры. Об этом - позже.
Вернуться к началу Перейти вниз
Посмотреть профиль
Gudleifr
Admin
avatar

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

СообщениеТема: Re: 01.07. ЧЕМОДАН ЭЛЕКТРОННЫХ СОЛДАТИКОВ   Ср Дек 06, 2017 3:30 pm

АТАВИЗМЫ ПРОГРАММИРОВАНИЯ

Забавно наблюдать, как одни и те же решения все возвращаются и возвращаются на каждом витке развития программирования. Диалектика или инерция мышления?
***

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

5920 ... PRINT ... INT(D(R1)*100)*.01

т.е. округление числа используется для нормализации его вывода - две цифры после запятой.

Еще один трюк:

7700 PRINTRIGHT$(STR$<Z(I,J)+1000),3);

Печать числа с ведущими нулями.

Встречаются и сложные предосторожности "на всякий случай":

475 DEF FNR(R)=INT(RND(R)*7.98+1.01)

Чего они тут боятся? Что INT(RND(R)*8 )+1 даст 9?
***

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

3110 X1=C(C1,1)+(C(C1+1,1)-C(C1,1))*(C1-INT(C1)): ...
3140 X2=C(C1,2)+(C(C1+1,2)-C(C1,2))*(C1-INT(C1)): ...

Здесь массив C() содержит единичные вектора, соответствующие "розе ветров", причем, с обычной для квадратных сеток проблемой ускоренного движения по диагоналям, т.к. длина вектора (1,1) больше длины вектора (1,0).
Расчет курса (обратная процедура) сделан так же, да еще с кучей проверок, какая компонента вектора длиннее и в какую примерно сторону вектор указывает (см. 8060).
***

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

9010 REM QUADRANT NAME IN G2$ FROM Z4,Z5 (=Q1,Q2)
9020 REM CALL WITH G5=1 TO GET REGION NAME ONLY
9030 IF Z5<=4 THEN ON Z4 GOTO 9040,9050,9060,9070,9080,9090,9100,9110
9035 GOTO 9120
9040 G2$="ANTARES":GOTO 9210
9050 G2$="RIGEL":GOTO 9210
...
9110 G2$="POLLUX":GOTO 9210
9120 ON Z4 GOTO 9130,9140,9150,9160,9170,9180,9190,9200
9130 G2$="SIRIUS":GOTO9210
9140 G2$="DENEB":GOTO9210
...
9200 G2$="SPICA"
9210 IF G5<>1 THEN ON Z5 GOTO9230,9240,9250,9260,9230,9240,9250,9260
9220 RETURN
9230 G2$=G2$+" I":RETURN
9240 G2$=G2$+" II":RETURN
9250 G2$=G2$+" III":RETURN
9260 G2$-G25+" IV":RETURN

"Структурный" программист наверняка бы засунул эти строки в списки (мол, возьми строку #18 и добавь суффикс #24). Конечно, если мы берем имена "из функции", а не "из массива", географию можно было бы сделать и посложнее, менее регулярной, подобно "ОРЕГОНСКОЙ ТРОПЕ".
Атмосфера игры поддерживается строками-репликами персонажей одноименного сериала, в основном, комментирующими промахи командира.

Впрочем, и BASIC-программисту никто не запрещает использовать массивы строк. И, даже, использовать байтовые массивы. Например, в ВЫБОРЕ комманд:

710 A1$="NAVSRSLRSPHATORSHEDAMCOMXXX"
...
2060 INPUT"COMMAND";A$
2080 FOR I=1 TO 9:IF LEFT$(A$,3)<>MID$(A1$,3*I-2,3)THEN2160
2140 ON I GOTO2300,1980,4000,4260,4700,5530,5690,7290,6270

Присутствует и "строковая арифметика:

440 ... X$="":X0$=" IS "
...
1200 ... IF B9<>1 THEN X$="S":X0$=" ARE "
...
1260 PRINT"   ON STARDATE";T0+T9;"  THIS GIVES YOU";T9;"DAYS.  THERE";X0$
1270 PRINT"  ";B9;"STARBASE";X$;" IN THE GALAXY FOR RESUPPLYING YOUE SHIP"

***

Подобно "плиточным платформерам" здесь тоже попытались использовать одни и те же массивы и для рисования, и для расчетов взаимодействия нарисованных объектов.
Так, есть "карта квадранта" - строка Q$ по три символа на позицию (выводимая на "экран радара") и совершенно жуткий строковый калькулятор для нее: подпрограмма СВЕРКА С КАРТОЙ (8820) - проверяет стоят ли в данной позиции именно эти три символа, ЗАПИСЬ НА КАРТУ КВАДРАНТА (8670) записывает в позицию новую тройку, а ПОИСК ПУСТОГО МЕСТА НА КАРТЕ КВАДРАНТА (8580) методом тыка ищет позицию, в которой стоят пробелы. Через эти три операции выражаются операции перемещения объектов (корабля, звезд, базы, клингонов) и проверяются контакты. Например, перемещение клингона описывается как вызов 8670 для затирания текущей позиции, затем - 8580 для поиска нового места, и снова 8670 для рисования в новом месте.
К сожалению, этих трех операций не всегда достаточно и работают они с жуткой избыточностью. Вместо простой проверки, что здесь стоит, нужно вызвать 8820 со всеми возможными тройками символов... местоположение клингонов приходится дублировать в другом массиве и т.д.
***

Но, в общем, BASIC работает с строками гораздо естественнее, чем с обычными арифметическими массивами, обозначающим координаты объектов. Все эти проверки на пересечение границ квадрантов и попадание в звезду запутают кого угодно.
Да и хранение карты галактики (массивы G$() и Z$(), второй - для исследованного пространства) в виде набора трехзначных чисел (первая цифра - клингоны, вторая - базы, третья - звезды) вызывает жуткие проблемы преобразования туда-обратно. Хранить в символьном виде было бы проще.
***

Конечно, в "платформерах" и "симуляторах" мы уже встречались с необходимостью заполнять большие массивы данных до начала игры, но здесь и без всякой графики приходится генерировать достаточно сложный мир игры, причем, в отличие от AKALABETH подразумевается, что наличествует некий баланс исходных чисел, делающий игру интересной.
Другой, связанный с массивами данных, прием состоит в том, что карты квадрантов не сохраняются при уходе из них, а при повторном заходе генерируются заново. Сохраняются только общие статистические данные - число клингонов, баз, звезд.
Вернуться к началу Перейти вниз
Посмотреть профиль
Gudleifr
Admin
avatar

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

СообщениеТема: Re: 01.07. ЧЕМОДАН ЭЛЕКТРОННЫХ СОЛДАТИКОВ   Ср Дек 06, 2017 3:34 pm

ПОДРОБНОСТИ АЛГОРИТМА

ВСЕЛЕННАЯ: 8*8 квадрантов, каждый разбит еще на 8*8 позиций - секторов. В среднем: клингонов в 2% квадрантов - 3, в 3% - 2, в 15% - 1; базы в 4% квадрантов (не меньше 1). Звезд - 1-8 на квадрант. Времени (дней) дается на игру не меньше числа клингонов.
КЛИНГОН. Сила - 101-200.
КОРАБЛЬ. Начальная энергия - 3000. Запас торпед - 10. Пополняются на базах (достаточно стоять рядом). Отсеки соответствуют командам, их повреждение ограничивает команды.
КОМАНДЫ: КУРС, БЛИЖНИЙ РАДАР, ДАЛЬНИЙ РАДАР, ФАЗЕР, ТОРПЕДЫ, ЩИТЫ, РЕМОНТ, КОМПЬЮТЕР. В угловых скобках - вызванные нашими командами ответные или фоновые действия.

- КУРС. Ввод направления - 1.-9. (по розе ветров: 1.0 - Восток, 2.0 - Северо-Восток, 3.0 - Север, ... 8.0 - Юго-Восток, 9.0 - опять Восток). Скорость - 0-8 (при повреждении двигателя - 0-0.2). Энергозатраты = [скорость*8]+10 (недостаток может быть покрыт за счет исправных щитов, но не более 10). Попытка сдвинуться на число квадратов, равное скорости. Могут помешать звезды и границы вселенной, начало нового квадранта. Продолжительность = min(1, скорость), при попытке пересечь границу квадранта - 1. <Движение клингонов> <Регенерация>
- Б.РАДАР. Выдача карты квадрата и состояния. Проверка стыковки с базой.
- Д.РАДАР. Выдача статистик по соседним квадрантам.
- ФАЗЕР. Мощность = затраты энергии (при повреждении компьютера умножить на 0-1). Для каждого клингона в квадранте: удар = мощность / число клингонов / расстояние * 2-3. Если удар <= сила клингона * .15 - ничего. Иначе - уменьшить силу клингона на удар, при занулении - уничтожить. <Стрельба клингонов>
- ТОРПЕДЫ. Направление - 0-9. Затраты энергии - 2. Торпеду останавливает звезда или граница квадранта - без последствий, клингон или база - уничтожаются. <Стрельба клингонов>
- РЕМОНТ. Если работоспособно, то ничего (см. регенерацию), только статистика. Иначе - полный ремонт на базе, на которую уйдет времени: число ремонтируемых отсеков * 0.1 + 0.1, но не более 1.
- ЩИТЫ. Увеличивает величину защиты и на величину затраченной энергии в день. (Щиты менее 200 считаются опасно слабыми).
- КОМПЬЮТЕР. Одна из команд: КАРТА, СТАТИСТИКА, ПРИЦЕЛ, НАВИГАЦИЯ, ВОЗВРАТ, РЕГИОНЫ.
- - КАРТА. Вывод статистики обследованных квадрантов.
- - СТАТИСТИКА. Сколько осталось дней и клингонов.
- - ПРИЦЕЛ. Расчет торпедной стрельбы.
- - ВОЗВРАТ. Курс на базу в квадрате.
- - ДИСТАНЦИЯ. Расчет перелета из точки в точку.
- - РЕГИОНЫ. Показывает имена квадрантов.

ДВИЖЕНИЕ КЛИНГОНОВ. Случайное маневрирование в квадрате. <Стрельба клингонов>
СТРЕЛЬБА КЛИНГОНОВ. База защищает от огня. Удар по щитам с силой клингона / дистанция * 2-3. Сила клингона уменьшается в 3-4 раза. (Какое-то непонятное самоистощение.) Если щиты пробиты - корабль уничтожен. Если удар >= 20 и удар / щиты > 0.2 в 60% случаев повреждается один из отеков на удар / щиты + 0-0.5.
РЕГЕНЕРАЦИЯ. Все отсеки чинятся пропорционально времени (коэффициент 1). В 3% одно из устройств повреждается на 1-1.5, в 2% - чинится на 1-4.
***

Кажется, что все очень просто - и команды, и отсеки, и способы их работы до предела структурированны, но программа столь запутана, что никакой возможности "прицепить еще пару отсеков, не поломав корабля", не просматривается.
Да и работает-то программа только в силу своей простоты.
Вернуться к началу Перейти вниз
Посмотреть профиль
Gudleifr
Admin
avatar

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

СообщениеТема: Re: 01.07. ЧЕМОДАН ЭЛЕКТРОННЫХ СОЛДАТИКОВ   Ср Дек 06, 2017 4:37 pm

УСЛОЖНИТЕЛИ

Итак, основная часть жуткого листинга на Python (TXT, 0.2Мб). 6 с лишним тысяч строк. По словам автора, автоматически сгенерирована из C-программы (доведена вручную) и имеет штук 20 дополнительных возможностей, которые можно включить/выключить установкой специальных флагов-опций.
Смотрим:

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

8780 REM PRINTS DEVICE NAME
8790 ON R1 GOTO 8792,8794,8796,8798,8800,8802,8804,8806
8792 G2$="WARP ENGINES":RETURN
8794 G2$="SH0RT RANGE SENSORS":RETURN
...
8806 G2$="LIBRARY-COMPUTER":RETURN

И пишет:

# Define devices
DSRSENS = 0
DLRSENS = 1
...
DDSP = 15
NDEVICES = 16 # Number of devices

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

"Choose a device to damage, at random."
weights = (
105, # DSRSENS: short range scanners 10.5%
105, # DLRSENS: long range scanners 10.5%
...
30, # DDSP: deep-space probes 3.0%
)

Оказывается есть и отдельный массив имен устройств, но его связь с константами уже совершенно неочевидна:

device = (
_("S. R. Sensors"), \
_("L. R. Sensors"), \
...
_("D. S. Probe"), \
)

Первая же попытка проследить хотя бы некоторые из этих констант проливает свет на причины ужасающего размера кода: Python-текст произведен из запутанного BASIC-кода путем его старательного "раскатывания в блин". Если, в "МАРИО" мы видели "матрешку" циклов, то здесь мы видим "елочку", имеющую по отдельной веточке для каждого мыслимого случая, причем никаких действий на пути от "ствола", практически, не предпринимается - только проверки условий.
Конечно, "елочка" не уменьшает числа ошибок (наоборот, увеличивает, т.к. все комбинации предусмотреть невозможно), но помогает программисту уменьшить их влияние на работу программы путем дополнительных проверок на опасных ветвях.
Как следствие, почти каждая из подпрограмм, посвященных какому-либо действию, по размеру равна всей BASIC-программе.

- А как же модульность/структурированность? Программное отображение структур отсеков, команд... Никак. Вот классы, с которыми мы имеем дело (за исключением чисто "внутрипрограммных"): coord (пара чисел), planet, quadrant, page (три числа - характеристика квадранта), snapshot (состояние игры), event (событие), enemy, gamestate (полное состояние игры), course, sstscanner - т.е. исключительно собранные в одно место наборы переменных для выполнения отдельных действий. А "игровые объекты" (за исключением врагов - enemy - и событий - event) размазаны по всему коду, как выше - отсеки. То, что мы называли "ООП - чтоб как у людей".

- Рассмотрим класс-объект enemy:

class enemy:
- def __init__(self, type=None, loc=None, power=None):
- - self.type = type
- - self.location = coord()
- - if loc:
- - - self.move(loc)
- - self.power = power
- - game.enemies.append(self)
- def move(self, loc):
- - motion = (loc != self.location)
- - if self.location.i is not None and self.location.j is not None:
- - - if motion:
- - - - if self.type == 'T':
- - - - - game.quad[self.location.i][self.location.j] = '#'
- - - - else:
- - - - - game.quad[self.location.i][self.location.j] = '.'
- - if loc:
- - - self.location = copy.copy(loc)
- - - game.quad[self.location.i][self.location.j] = self.type
- - - self.kdist = self.kavgd = (game.sector - loc).distance()
- - else:
- - - self.location = coord()
- - - self.kdist = self.kavgd = None
- - - game.enemies.remove(self)
- - return motion
- def __repr__(self):
- - return "<%s,%s.%f>" % (self.type, self.location, self.power)

Что мы видим?
Собственно, к классу относятся всего три операции: создания врага (сила, место, тип), перемещение в новое место, отладочная выдача. "Елочка" налицо: "перемещение" вызывается аж в трех случаях - первое выставление на игровое поле, собственно перемещение и убирание с поля. Какой "случай" имеется в виду, операция определяется аж тремя проверками. Причем, даже в таком огрызке уже есть дублирование проверок: __init__ проверяет loc и вызывает move, который опять проверяет loc. А, собственно, кода, который что-то делает - тут "кот наплакал". Нет даже намека на то как и куда происходит перемещение объектов.
С четвертой проверкой все еще хуже: если тип "T" - толианин - то он вместо себя оставляет не пустое место, а "космическую паутину". Вот она гадость - проверка в неожиданном месте - попробуйте найти все, что умеет толианин, и вам придется перелопатить всю программу (а это уже не сотни, а тысячи строк!).
Список типов врагов (и прочих космических тел) мы найдем только в самом конце кода:

def cramen(type):
"Emit the name of an enemy or feature."
if type == 'R': s = _("Romulan")
elif type == 'K': s = _("Klingon")
elif type == 'C': s = _("Commander")
elif type == 'S': s = _("Super-commander")
elif type == '*': s = _("Star")
elif type == 'P': s = _("Planet")
elif type == 'B': s = _("Starbase")
elif type == ' ': s = _("Black hole")
elif type == 'T': s = _("Tholian")
elif type == '#': s = _("Tholian web")
elif type == '?': s = _("Stranger")
elif type == '@': s = _("Inhabited World")
else: s = "Unknown??"
return s

Да-да, невзирая на все структурности, тип объекта обозначается той самой буквой, которая рисуется для него на экране, а совсем не указателем на "структуру его свойств".
Т.е. вывод очевиден, никого проку от структуризации программы мы не видим. Нам, по крайней мере, она не поможет. То, что добавлено в игру по сравнению с первоначальной версией, будем искать методом тыка.
Найдя следующий кусок о врагах, мы видим, например, 50 строк, потраченных на выяснение может ли враг покинуть квадрант (tryexit). Проверяется 12 условий (одно в цикле), и есть, по крайней мере, одна ошибка.
Такое усложнение вызвано желанием иметь много интересных разновидностей врагов. Враги отличаются не только силой, но и своим поведением, поэтому в любой процедуре "имеющей с ними дело" большая часть проверок посвящена выяснению, с каким врагом мы имеем дело и может/будет ли он использовать в данный момент свои специальные способности.
Следов какого-либо "искусственного интеллекта" я не заметил, только правдоподобно выглядящие "если ..., то ... с вероятностью ...". Нечто подобное нам предлагали запрограммировать в "ВОРОТИЛАХ".

- Конечно, больше всего нас должны заинтересовать события - event:

# Define future events
FSPY = 0 # Spy event happens always (no future[] entry)
# can cause SC to tractor beam Enterprise
FSNOVA = 1 # Supernova
FTBEAM = 2 # Commander tractor beams Enterprise
FSNAP = 3 # Snapshot for time warp
FBATTAK = 4 # Commander attacks base
FCDBAS = 5 # Commander destroys base
FSCMOVE = 6 # Supercommander moves (might attack base)
FSCDBAS = 7 # Supercommander destroys base
FDSPROB = 8 # Move deep space probe
FDISTR = 9 # Emit distress call from an inhabited world
FENSLV = 10 # Inhabited word is enslaved
FREPRO = 11 # Klingons build a ship in an enslaved system
NEVENTS = 12

Как они работают? Точно так же, как в "ЗВЕЗДНЫХ ТОРГОВЦАХ". "Жетоны" событий помещаются на "табло ходов"! Только два отличия: хоть время события назначается достаточно произвольно, его тип и место назначаются в результате действия противников и других космических объектов. Второе отличие - т.к. это игра не компьютерная, а не настольная игра, проверка того, что событие случилось, производится в момент обсчета "длительных" команд. Как в "БОМБЕРЕ".

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

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

Еще пример скелета игры, на этот раз, выдранного из игры ELITE (там на нем базировался трехмерый "симулятор космического полета") - TXT, 0.02Мб. Программа - модель очередного многопланетного рынка. Не будем еще раз вникать в механику ценообразования, хватит этой фигни. Посмотрим на скелетообразующую механику. Конечно, здесь опять видим избыточную структуризацию (программа-то - на языке C), с лишними пересылками данных.
Скелет строится, практически, как в STAR TREK - сначала buildgalaxy для, кто бы мог подумать, построения вселенной, затем - циклический повтор ввода-исполнения комманд (parser). Более того, хотя "машина вселенной" очень напоминает "ЗВЕЗДНЫХ ТОРГОВЦЕВ", ее состояние генерируется случайным образом "по ходу дела", на основании свойств товаров и свойств рынков (genmarket).
Из других интересностей - еще один вариант простого генератора чисел (myrand) и развитой калькулятор текстовых сообщений с использованием макрогенерации (goat_soup).
***

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



Вылитый "Сапер", только не "целочисленный". Числа означают потенциальную опасность самих клеток, а не их соседей. Но, ведь, мы можем комбинировать и изобретать свои правила...

В этом и плюс "скелета" - он не мешает экспериментировать. Хотим проверить, вполне ли соответствует алгоритм "Сапера" разумному выбору пути - пожалуйста!
***



Вот еще один космический бой - SPACE ACE 21 (TXT, 0.02Мб). Странные строки 71-82 - в кодировке компьютера TRS-80 гораздо симпатичнее (это отсеки кораблей):



Первое, что бросается в глаза - неожиданное использование псевдографики для рисования. И, если это можно так назвать, "заставка на движке игры" - строится и взлетает демонстрационный корабль.
Корабль может иметь до 21 (7 "этажей" по 3 отсека) отсека 12 типов: Armor, Bridge, Cargo, Disruptor, Engine, Fuel, Generator, Life Support, Missiles, Phaser, Sensor, Torpedo. 5 обязательных (Bridge, Engine, Fuel, Generator, Life Support) нужно иметь не менее, чем по одной штуке. Непосредственно за Engine обязательно должно располагаться пустое место (поэтому естественно поставить их на нижнем "этаже"). А Bridge естественно смотрится на верхнем этаже.

Для рисования трехмерного космоса на экране используется две проекции, а курс как и прежде вводится заданием углов (в объеме их нужно два - азимут и возвышение).
К счастью, и курс и скорость можно задавать не только в цифрах, но и в человеческих терминах: курс может быть проложен на вражеский корабль, на его базу, на свою базу, оставлен прежним; скорость можно задать максимальной/минимальной или прежней. Но считать, все равно, придется много: сложные взаимозависимости отсеков, ТТХ оружия...
По идее, это тот же HIGN HOON, только более сложный - "улица" получила новые измерения, поведение противников усложнилось, кроме двух кораблей-дуэлянтов в бою участвуют их базы. Атавизмом осталось введение команд по требованию программы, обязательно в порядке: отчет, направление, скорость, стрельба. И отсчет времени равными отрезками (а не от события к событию).

Программа написана в манере, которую достаточно сложно считать исконно бейсиковой. Сплошь подпрограммы по одной строчке (и, как же без них, есть в кодах процессора). По идее, это означает, что нормальный BASIC авторов игры не устраивает и они на нем написали свой язык программирования BASIC', к сожалению, слишком трудночитаемый. Язык BASIC' базируется на наборе переменных (а на чем же еще?): в O1, O2, O3 передаются параметры пищания, слово для впечатывания в строку - W и т.п. Впрочем, этот язык здесь не столь уж необходим, скорее, это такой выпендрежный стиль автора. Хотя, обращения к массивам им удалось инкапсулировать очень хорошо, нет как в STAR TREK этих жутких выражений с индексами по всей программе.
Программа работает в два прогона: при первом RUN загружаются кодовые процедуры и удаляются строки DATA, их содержащие (проверка номера прогона в начале строки 90).
Затем (после перезапуска) - заставка - строки 0, 90, 95. Да, да, всего три строки, зато, с кучей процедур (а, по сути - операторов нашего нового языка). Причем, активно используется способ сращивания хвостов - вызовов процедуры по GOTO вместо GOSUB, чтобы она по RETURN завершила, заодно, и того, кто ее вызвал. Из интересных операторов: 40 - строительство и выдача одного из 10 кораблей, 20 - постройка и выдача корабля по его "чертежу", 26 - выдача одного отсека. Остальные - разного рода пищалки и позиционирования, потом добавится еще мелочь для ввода/вывода.
После заставки следует блок ввода параметров (со строки 120) - ввод числа и имен игроков, выбор корабля для компьютера, выбор сценария (их целых три - предполагающих разную роль баз), решение играть в двух или трех измерениях. Создаются корабли игроков (проверяется правильно ли это сделано). Плотность использования подпрограмм в этом блоке уже поменьше.
Сам цикл игры начинается со строки 300. Сначала - ввод команд: 305 - отчет, 310 - направление, 330 - скорость, 340 - оружие. После (400) - их исполнение. К "операторам" ввода/вывода добавляются тригонометрические и прочих вычислений.
Со строки 500 - "искусственный интеллект".
Вернуться к началу Перейти вниз
Посмотреть профиль
Gudleifr
Admin
avatar

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

СообщениеТема: Re: 01.07. ЧЕМОДАН ЭЛЕКТРОННЫХ СОЛДАТИКОВ   Ср Дек 06, 2017 5:18 pm

УПРОЩАТЕЛИ


Очередной STAR TREK. Немножко другая вселенная, чуть-чуть другие команды.

Почему я отношу эту и последующие игры к упрощениям? По очень простой причине: взяв за основу известную программистскую игру, авторы ее слегка причесали/обрезали и выдают за окончательный продукт. А как раз отсутствие "окончательности" тут интереснее всего.
***


Например, в советском клоне "Звездный патруль" добавили реальное время. Для этого пришлось объединить все экраны в один (их некогда переключать) и упростить геометрию (убрать калькулятор). Правда, я так и не понял, играет здесь таймер роль напоминалки о бренности бытия или заставляет рулить быстрее.
***

Немного покопавшись в истории игры STAR TREK, обнаружил целое семейство "продолжений":


STAR FLEET - тоже самое, но в обобщенной вселенной "наши против зеленых";


STAR FLEET II - игра "за зеленых", добавлено немного графики и возможность высаживать десанты на планеты;


STAR LEGIONS - опять "за зеленых", практически одни наземные операции (зато - графика по поводу и без);


EMPIRE - совсем простая вселенная "наши против ненаших", только наземные операции, но очень похоже на STAR FLEET II.

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

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

СообщениеТема: Re: 01.07. ЧЕМОДАН ЭЛЕКТРОННЫХ СОЛДАТИКОВ   Ср Дек 06, 2017 5:35 pm

ОПЫТ "ЛУНОЛЕТА"

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

В рассматриваемых здесь играх интересна прежде всего разнородность объектов управления. Позже, осталось только два интерфейса (и соответственно типа объектов): "общий", реализуемый меню главного окна (СТРАТЕГИЧЕСКАЯ КАРТА, т.к. здесь я опять возвращаюсь к комнатной модели) и "частный", реализуемый контекстным меню отдельного "танка" (ПУЛЬТ). В те же далекие времена даже у стратегий наблюдался разнобой в сложности объектов.
Сразу бросается в глаза, что "общий" интерфейс во всех играх серии (кроме EMPIRE) привязан к некоторому сверхобъекту - космическому кораблю. Интерфейс сложный, состоящий из ПУЛЬТОВ, СТРАТЕГИЧЕСКОЙ И ТАКТИЧЕСКОЙ КАРТ. Однако, обычное для нас управление (тыкнуть мышкой в нужный орган) в ранних играх отсутствует. Для ввода команд используется текстовый набор.
Неоднородны и "частные" объекты - здесь, "танки", участвующие в наземных операциях. По сравнению с "CIVILIZATION", где подразделения сведены в более-менее строгую систему (не говоря уже о конструкторе подразделений в EMPIRE II), в EMPIRE - форменный винегрет. Можно условно разделить тамошние "танки" на совсем простые (армии и авиакрылья) и посложнее (города и корабли). Да-да, разнобой в подразделениях такой, что города не являются чем-то особенно выдающимся (ср. CIVILIZATION).
Армии тупые до безобразия - тупо ползают по карте с единичной скоростью и захватывают города (уничтожают армии врага) с вероятностью 50%. Управление авиакрыльями посложнее. И скорость у них побольше (4-5 единиц) и запас топлива ограничен (разбиваются не успев вернуться в города).
Корабли (не говоря уже о городах) обладают кучей самых разных особенностей - вместимостью, живучестью, скоростью, ударной мощью. По сути, вся стратегия игры сводится к строительству сбалансированного флота.
Итак, имеем сверхобъекты (один сложнее и красивее другого) и малые объекты (забавные своей разнородностью). Пытаться свести все к общему знаменателю, как в современных играх? Или, найти каждому свою КОМНАТУ? Если заводить речь о реализме модели, то безусловно, второе. Иначе придется строить полноценный симулятор жизни. Частные же модели вполне могут быть честными.
Не могу не упомянуть и еще об одном минусе "стандартизации", проявившемся уже в EMPIRE. Недоработанность СТРАТЕГИЧЕСКОЙ КАРТЫ привела к наличию кучи команд, отдаваемых как меню, так и кликами мышкой, цель которых - избежать выхода простых объектов из-под контроля: засыпания, потери фокуса, пропуска акции... Забавно, но, по мере развития жанра, число таких предохранителей все увеличивалось. В современных стратегиях можно практически "тыкать" куда попало, не опасаясь роковых последствий. Этакий Windows-стандарт: лишний клик дела не испортит. Вот и тыкаешь, как дурак, пока не сработает.

Еще одним явно проявившимся в серии отличием сверхобъектов (далее буду называть их сложными) от простых является разный подход к их "автоматизации". Если для простых объектов автоматизация сводится к простенькому программированию (приказам передислоцироваться, патрулировать, эскортировать...), то для сложных - сверхобъект дополняется управленческим "компьютером" для облегчения расчета сложных команд (например, торпедной стрельбы или прокладки курса).
Разделение объектов на простые и сложные также служит мне оправданием в деле размежевания ТАКТИЧЕСКОЙ И СТРАТЕГИЧЕСКОЙ КАРТ. Очевидно, что "при прочих равных", бой сложного объекта естественнее смотрится на ТАКТИЧЕСКОЙ, а кучи простых - на СТРАТЕГИЧЕСКОЙ КАРТЕ.
Посмотрим теперь на устройство наших объектов. Комнатная модель, вроде бы, позволяет все разложить по полочкам в компьютерной реализации, но как быть в настольной игре или книге-игре?
В настольных играх с простыми объектами проблем нет - фишки, как фишки. Все их особенные свойства без труда описываются правилами. Однако, со сложными объектами возникает проблема. Использование сложных органайзеров вполне допустимо, пока сложные объекты ассоциируются с игроком (см. "TALISMAN"), но требует введения игрока-банкира, при описании в виде сложного объекта "общеигровой обстановки" (см. "MONOPOLY"), или, даже, введения гейм-мастера.
Имеет ли это смысл? Может, сложные объекты допустимы только в играх на одного игрока? Т.е. мир, в котором "живет" игрок имеет смысл усложнять введением подобных монстров только тогда, когда мы хотим сделать сложность противником игрока. Зачем, например, банк в "MONOPOLY"? По моему мнению, он нужен только постольку, поскольку игра заведомо случайная и игрок не может полностью управлять своими объектами. Если игра полностью зависит от взаимодействия стратегий игроков, то вполне достаточно фиксации игровой ситуации изменениями позиции на игровом поле и изменениями настроения игроков.
Соображение здесь такое. Игроки, начинающие партию в случайную игру, каждый раз предвкушают, что в этот раз случайные числа сложатся в такую комбинацию, которая породит нечто очень интересное и незабываемое (при минимальном участии игроков), породит некую "новую сущность". А для этого необходимо как можно полнее учесть все случившиеся события в разнообразных накопителях и органайзерах. Впрочем, это только моя гипотеза.
Гораздо большее влияние на современные игры оказывает появление "промежуточных" объектов. Сложных, но присутствующих в большом количестве. Например, города в стратегических играх, начиная с "CIVILIZATION". В настольных играх ярким примером служат т.н. wargames. Каждая группа фишек-солдат на столе снабжается листочком подробного учета состояния подразделения, в который аккуратно заносятся все потери, траты боезапаса и изменения "морали". Причем, игры, в которых подобное отражается одним-двумя жетонами-маркерами ("ASL" или "DIRTSIDE II") клеймятся как "нереалистичные". Кроме того, что использование подобной механики не имеет никакого отношения к реализму, ничего сказать не могу.
Книги-игры, это игры для одного игрока (а нередко и того меньше - только для автора). Значит сложный объект, описывающий состояние вселенной и состояние игрока, здесь вроде бы уместен, как нигде. Простые объекты здесь обычно выступают двумя способами - как объекты, вступающие во взаимодействие со сложным объектом игрока (как Клингоны, атакующие Энтерпрайз в STAR TREK), и как трофеи-награды, которые копятся игроком (друзья и предметы в TALISMAN).
***

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

Начиная работу над "Лунолетом" (ТЕМА #43, АБЗАЦ #431), хотел сделать корабль как можно более модульным. Что-то вроде:


Смотреть надо не на планеты, хотя, я всегда хотел снабдить "Лунолет" иллюминатором, а на разные наборы кнопок на пультах.

Чтобы можно было постепенно добавлять к "Лунолету" модули - "Изменение гравитации", "Центробежные силы", "Сопротивление атмосферы"...
Пока речь шла о параметрах вселенной и вводе/выводе все было просто, однако, нарисовать чертеж корабля никак не получалось. Потом я понял, что это не требуется - проще представить корабль в виде функции, а его части в виде макросов.
Вернуться к началу Перейти вниз
Посмотреть профиль
Gudleifr
Admin
avatar

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

СообщениеТема: Re: 01.07. ЧЕМОДАН ЭЛЕКТРОННЫХ СОЛДАТИКОВ   Ср Дек 06, 2017 5:37 pm

БЕЗ ДИНАМИКИ ПРОЩЕ И СКУЧНЕЕ

А если, все-таки, строить "корабль" в данных?
Можно.
Помните, мы формулировали четыре игровых действия?

1. Изучение правил.
2. Изучение игрового мира.
3. Изменение игрового мира.
4. Изменение персонажа.

Мы просто описываем в виде структур данных те отсеки "корабля", при помощи которых выполняем эти действия.
И получаем...
... так называемые 4-Х игры: eXploration (исследование миров), eXploitation (освоение миров), eXpansion (развитие) и eXtermination (уничтожение конкурентов). По сути, с некоторой потерей "ортогональности осей" (для играбельности) это те же пп.1-4.

Конечно, XXXX-играм свойственны:
1. Рутина. Один из "X" обычно превращается в сложный ритуал, автоматическое повторение которого отнимает до 90% игрового времени. Например, строительство баз в "Deuteros".
2. Рудименты. Другой из "X" обычно остается бедным родственником, оставленным непонятно зачем в ущербном состоянии. Например, производство в "X-Com".
3. Эклектика. Совмещение разных "X" в одном флаконе приводит обычно к появлению жутких мутантов. Например, графика в "Reunion".
4. Несуразности. Для притирки "X" друг к другу обычно приходится идти на жуткие натяжки в правилах. Например, скорость размножения людей в "Millennium".

И это, наверное, не такие уж и недостатки, пока речь идет об игре-конструкторе, в которую играет программист, но начинает сильно раздражать, когда обрезав от игры все, что не заработало, это вываливают, как "полноценную реал-таймовую стратегию".
Вернуться к началу Перейти вниз
Посмотреть профиль
Gudleifr
Admin
avatar

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

СообщениеТема: Re: 01.07. ЧЕМОДАН ЭЛЕКТРОННЫХ СОЛДАТИКОВ   Ср Дек 06, 2017 5:43 pm

КСТАТИ, А КАК БЫТЬ СО СЛОЖНЫМИ ИГРАМИ?

По материалам моего участия в форумах:

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

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

Чуть выше мы вспомнили второй набор "кубиков":
1. изучение правил;
2. изучение игрового мира;
3. изменение игрового мира;
4. изменение персонажа.
***

Третий набор "кубиков" (являющийся классическим - по Бруксу):
1. программа;
2. программный продукт;
3. программный комплекс;
4. системный программный продукт;
***

Ах, да, из последнего закрытого модераторами: с точки зрения игры, как игры, можно выделить:
1. создание привлекательного мира для завлечения игрока (не имеющего отношения к игре)
2. собственно игру - обмен некими сигналами-ходами с игроком (позднее я придумал термин - "машина игры")
3. игру автора (управление игроком, совершенствование игры...)
***

В разговоре о возможности группировки игр по типам всплыла ссылка на статью "Смысл игровых жанров" - http://www.lki.ru/text.php?id=37, где игры делились на
1. Игры движения. В этих играх ключевой фактор - движение, скорость, точность. Мозги тоже нужны (иногда), но без отличных навыков управления делать тут просто нечего.
2. Игры планирования. Здесь основное - это планирование событий и борьба за получение преимущества в дальнейшем.
3. Игры сюжета. В этой группе может быть важна и динамика, и план, но на деле и то и другое - лишь средства, а не цель. Цель же - продвижение по сюжетной линии.

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

Если вспомнить, что игры приходится программировать...

Работа программиста состоит обычно из двух частей: 10-20% времени - получив задачу, программист применяет свой опыт и эрудицию, чтобы быстренько ее решить; 80-90% - на то, чтобы заставить это решение работать. И те редкие счастливые моменты, когда до второй стадии не доходит (или, хотя бы, удается значительно ее сократить), наполняют программиста гордостью и верой в свое призвание.
***

Для того, чтобы "что-то закодировать", программист должен знать три вещи:
1. как решить задачу (математика);
2. как запрограммировать решение (язык программирования);
3. как написать/запустить программу (операционная система).
Считать, что эти вещи "взаимопроникающие" и/или "взаимозаменяющие", может, разве что, "быдлокодер". Только он может думать, что библиотеки - часть языка, а не ОС, или, что решить задачу можно "сразу начав писать программу".
***

К сожалению, это работает только для простых задач. А сложные? Для них работает метод FORTH: Имеем A (язык машины), пишем на нем на коленке за неделю язык F (Forth), затем на нем - P (проблемно-ориентированный язык), отдаем последний пользователю для решения своих задач.

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

1. "Плюем и копипастим". Очевидно, что чем "последовательнее" куски кода, тем длиннее они могут быть. Но где найти столь выразительный язык, чтобы на нем можно было бы писать без "петель"? На помощь приходят Операционные Системы. Они разрешают пользователю писать только отдельные главы "Что произойдет, когда пользователь нажмет на кнопку?", "Что надо не забыть при размещении окна на экране?",.. А связь между главами берут полностью на себя. В такой умной среде даже достаточно сложно привязанную к сюжету "главу" можно просто приписать в конец программы. Минус подхода, разумеется, в том, что здесь не писатель управляет сюжетом, а сюжет - писателем. Мы постоянно видим вокруг программы, напрягающими пользователя заполнением ненужных ему форм, требуя от него ненужных подтверждений очевидного, навязывая ненужные ритуалы.

2. "Структурное программирование". В своей книге "Дисциплина программирования" Дейкстра ввел аксиоматику соединения программных глав в единое произведение. Два важнейших способа - операторы выбора и цикла. Со временем аксиоматика забылась и программисты уверовали, что цикл может гарантировать им чуть ли не кибернетическую ультраустойчивость, а выбор обеспечит возможность учесть "все". Эти два оператора ответственны за увеличение мусора в программах на один, а то и два, порядка. Чтобы это оценить нужно вспомнить аксиоматику. Она проста (если не вникать в математику): основное качество цикла не способность вовремя остановиться, а способность сохранять т.н. "инвариант цикла", что позволяет ему не пойти вразнос; с выбором все очевиднее - этот оператор должен учитывать все варианты не в смысле "все что придет в голову", а в смысле "честной мат.логики" - всех возможных наборов значений переменных, входящих в условие выбора. Как это работает?
Обычная ошибка применения циклов, как мы видели ранее - "матрешка". Циклы вкладываются один в другой не "по логике", а "по сюжету". Кроме потерь на лишние переборы, порожденные изменением одной-двух переменных состояния, приходится слишком долго проверять, не был ли поврежден "инвариант". А, если программист сам плохо понимает, какой инвариант к какому циклу относится, число проверок/восстановлений растет в геометрической прогрессии.
Аналогичной ошибкой при использовании оператора выбора является упомянутая выше "елочка". Вместо последовательной обработки отдельных переменных состояния, при неудачном распределении последних, получается громоздкое дерево. Для всех вариантов значения первой переменной, проверяются все значения второй, для каждого значения второй - все значения третьей... В сложных елочках часто происходит более одной проверки одного условия, т.к. понять была ли ранее сделана та или другая проверка достаточно сложно, особенно после внесения пары-другой исправлений.
Как избежать матрешки и елочки? Нужно стараться отделить логику управления от других вычислений программы. А затем - попытаться ее упростить по правилам обычной математики.
Несмотря на трудность правильного применения структурного программирования, оно позволяет писать очень красивые (и доказуемо правильные) программы.

3. "Масштабирование". С ростом популярности языка C термин "структурное программирование" стал использоваться в другом значении - как программирование путем бесконечной группировки структур (кода и данных) в более крупные структуры. Появилось (такое же дурное) понимание понятия "объектно-ориентированного программирования" - как создания неких универсальных структур (объединяющих - "инкапсулирующих" - в себе и код, и данные вместе).
Для увеличения сложности таким путем, очевидно, характерен "синдром чайника" - когда "вылить уже налитую воду" проще, чем переписать процедуру "кипячения".
Другой источник мусора при таком подходе - избыточность предохранительных процедур, которые "для универсальности и безопасности" вставляют во все процедуры, где неправильные данные могут вызвать ошибки. Такой подход не только приводит к жуткой избыточности ненужных проверок, но и служит источником ошибок - необнаружению критических сбоев.

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




СообщениеТема: Re: 01.07. ЧЕМОДАН ЭЛЕКТРОННЫХ СОЛДАТИКОВ   

Вернуться к началу Перейти вниз
 
01.07. ЧЕМОДАН ЭЛЕКТРОННЫХ СОЛДАТИКОВ
Вернуться к началу 
Страница 1 из 1
 Похожие темы
-
» Где купить чемодан?
» Наборы солдатиков
» Собираем чемодан на отдых!
» Серии солдатиков
» Шкафчик для солдатиков из фоторамки 50х60см.

Права доступа к этому форуму:Вы не можете отвечать на сообщения
KRIEGSSPIELE! :: Заметки о простых играх-
Перейти: