ZX-Ревю 1991 №11-12 1990 г.

Adventure project - Окончание. Взаимодействие между играющим и программой.


Темы статьи: Интервью  

ADVENTURE PROJECT

Окончание.

Начало см. на стр. 122, 193.

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

Большинство адвентюрных программ используют технологию интерпретаторов для выяснения того, какую же команду хотел дать пользователь. В минимальной виде он включает конструкции типа Глагол + Существительное. В этом случае глагол выполняет функции команды, а существительное указывает на объект, к которому эта команда относится и, тем самым, служит как бы параметром при команде. Например программа поймет команду GO NORTH (Идти на север), но вполне может не понять команду PLEASE GO NORTH (Пожалуйста иди на север) или, еще того хуже, GO DOWN THE ROAD TO THE NORTH (Идти по дороге на север).

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

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

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

Под охраной подземных жителей их провели в столицу страны и теперь они ждут допроса у короля.

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

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

Когда в конце 60-х на гигантских вычислительных машинах, имевших огромные размеры памяти, но совершенно негибкие и неэффективные операционные системы, появились первые текстовые игры, они были по сегодняшним меркам невероятно примитивными и имели словарь порядка 100 слов. Как же они работали?

Приняв команду, например GO NORTH, они делили ее на две части и в каждой оставляли только два первых символа, отрезая остальные. Так что у Вас оставалось GO NO, после чего начиналась трансляция.

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

Второй способ хоть и требует большего расхода памяти, имеет предпочтение в большем просторе алгоритмизации и кодирования, особенно на БЕЙСИКе и ограничения, накладываемые на программу здесь не столь жестки.

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

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

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

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

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

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

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

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

Система ввода через меню или ключевые слова может быть использована в простейшей подпрограмме ввода и будет работать таким образом, чтобы введенные слова одинаково интерпретировались во всех сценах Вашей игры. Пример для ключевых слов GO ("G") и TAKE ("T") приведен на листинге 1.

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

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

Строка 10 принимает от пользователя команду в виде одного символа и помещает его в переменную a$. Строки 20 и 30 проверяют что это за команда - GO или TAKE. Если принятый символ не является ни "g" ни "t", тогда компьютер печатает в нижней части экрана "Не понимаю!" и ждет другой команды.

Если была нажата клавиша "g", то это команда GO и выполняется переход на строку 60 для анализа этой команды.

Строка 60 - начало блока управления сценой. Переменные n,s,e,w,u,d - соответствуют тем шести направлениям, в которые может захотеть переместиться играющий. Содержатся же в этих переменных номера строк, к которым следует перейти, чтобы отработать поданную пользователем команду. Ноль указывает на то, что в данном направлении перемещение невозможно.

Строка 70 вызывает подпрограмму, выполняющую ввод направления перемещения от пользователя и проверку на допустимость этого направления. Если оно недопустимо, в соответствующую переменную вводится ноль.

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

Если же все прошло нормально, Вы переходите к следующей сцене по номеру строки, содержавшемуся в B.

Подпрограмма, занимающаяся командой TAKE расположена начиная со строки 100. Играющего спрашивают о том, какой предмет он хочет взять и вводят его в a$.

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

Если a$ не совпадает с o$, пользователя предупреждают о том, что данный предмет взять нельзя, он не здесь. Если же взять предмет удалось, вам об этом сообщают и данный предмет заносится в Ваш инвентарный список (переменная i$, которая отслеживает пополнение Вашей коллекции). Символ "*" служит для отделения объектов друг от друга и список может быть просмотрен, например с помощью программы, о которой мы уже говорили (см. стр. 194).

Листинг 1.

5 LET o$="SWORD":LET i$=""

10 PAUSE 0: LET a$=INKEY$: IF a$="" THEN GO TO 10 20 IF a$="g" THEN GO TO 60 30 IF a$="t" THEN GO TO 100 40 PRINT #0;"Я Вас не понимаю" 50 GO TO 10

55 REM Начало процедуры перемещения.

60 LET n=0: LET d=0: LET s=4000: LET w=5000: LET e=5050: LET u=4050 70 GO SUB 1000

80 IF B=0 THEN FRINT "Вы не можете идти в этом направлении": GO TO 10 90 GO TO B

100 INPUT "Что взять?"; а$

110 IF a$="" THEN FRINT "Здесь нет предметов, которые можно было бы взять.": GO TO 10

115 IF a$<>o$ THEN PRINT "Этот предмет находится не здесь.": GO TO 10

120 PRINT "вы берете ";o$

130 LET i$=i$+"*"+о$

140 GO TO 10

1000

INPUT

Куда идти? "

;b

$

LET b$

1010

IF b$=

n"

THEN

LET

b=

n

RETURN

1020

IF b$=

s"

THEN

LET

b=

s

RETURN

1030

IF b$=

e"

THEN

LET

b=

e

RETURN

1040

IF b$=

w"

THEN

LET

b=

w

RETURN

1050

IF b$=

u"

THEN

LET

b=

u

RETURN

1060

IF b$=

d"

THEN

LET

b=

d

RETURN

1080

RETURN

4000 CLS: PRINT "Вы находитесь в тронном зале короля Кельроса. Сверкающий трон поражает своим великолепием. Во взгляде властелина читается жестокая решимость. "

4010 GO TO 10

4050 CLS: PRINT "Оттолкнув стражу, Вы бросаетесь вверх по лестнице и, преодолев ее,

попадаете в пустой коридор. Все боковые двери закрыты. Дальше дороги нет. Погоня настигает, сопротивляться бесполезно. "

4060 GO TO 10

5000 CLS: PRINT "Воспользовавшись секундным замешательством стражи с криком 'Бежим!' Вы хватаете Ору за руку и бросаетесь к выходу. "

5010 GO TO 10

5050 CLS: PRINT "Собрав все силы, Вы вырываетесь из рук стражи и бежите к ближайшей двери, но она сказывается закрытой. Погоня настигает Вас, под тяжелыми ударами Вы падаете и теряете сознание."

5060 GO TO 10

Это то, что касается первой технологии коммуникации.

Теперь рассмотрим второй прием, позволяющий вводить длинные предложения.

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

Фактически перед ними три пути. Либо попытаться убежать, либо схватить часы и попытаться убежать, либо попробовать договориться мирным путем.

Переведя все это на язык компьютера, мы получаем: GO (идти) или TAKE AND GO (взять и идти), или SAY TO (сказать).

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

В нашем примере мы рассмотрим именно эти три функции GO, TAKE и SAY TO. Давайте сразу отметим, что в любом языке одно и то же действие можно выразить по-разному, но тем не менее возможный набор синонимов все-таки ограничен. Так, например вместо "взять", можно употребить "схватить", "украсть", "похитить" и даже что-либо типа "умыкнуть", но надо все-таки признаться, что последнее очень маловероятно. Скорее всего пользователь будет применять TAKE или GET и их и надо искать в его команде. Если же программа пишется на русском языке, то имеет смысл настраивать ее на "взять" и на "хват" (от слов схватить, захватить). Если же он употребит иные слова, то ему можно сообщить, что мысль его в общем-то понятна, но не мог ли бы он попробовать ее выразить другими словами. Итак, мы остановимся на TAKE и GET. Точно также и с перемещением GO. Способов перемещения не так много - GO, RUN, MOVE (идти, бежать, передвигаться) и пожалуй из общеупотребимых это все. Направления же возможного движения вообще известны однозначно: СЕВЕР, ЗАПАД, ЮГ, ВОСТОК, ВВЕРХ, ВНИЗ (NORTH, SOUTH, WEST, EAST, UP, DOWN). Только уж если Вы захотите создать шедевр искусственного интеллекта, Вы сделаете так, что программа будет понимать вперед и назад (FORWARD, BACK).

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

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

Если выделить в такой команде ключевые слова, то она будет выглядеть так:

(...ИДТИ) (...СЕВЕР...) (...И...) (...ЗАПАД...). GO...NORTH...AND...WEST

GO - основной носитель команды в этой фразе и искать этот глагол надо в первую очередь. Если он не найден, то значит надо проверить прочие глаголы-команды, которыми может воспользоваться играющий.

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

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

Если она находит GO, то выполнит переход в подпрограмму, которая занимается вопросами перемещения и проанализирует остальную часть фразы.

Аналогично может строиться и строка команды TAKE (GET).

Например:

GET...CLOCK...AND...TORCH...

ВЗЯТЬ...ЧАСЫ...И...ФАКЕЛ...

Теперь рассмотрим команду SAY TO (сказать). На первый взгляд она может представлять проблему. Нет, особых проблем нет, решается все той же техникой, хотя немного посложнее. Именно ее-то мы и рассмотрим в конкретном примере (Листинг 2), не отвлекаясь на TAKE, GO и т.п.

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

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

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

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

Конструкция получается типа:

СКАЗАТЬ КОРОЛЮ "...ДАТЬ...ЧАСЫ..

" SAY TO KING "...GIVE....CLOCK..."

Возможно, конечно, что Вы захотите дать пользователю возможность строить очень головоломные конструкции типа: "Идти на север и потом повернуть на восток. Взять веревку и ведро и спросить у старика с палкой: "Где колодец?"."

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

Тогда Ваша длинная последовательность упростится до:

ИДТИ...СЕВЕР...И...ВОСТОК...

ВЗЯТЬ...ВЕРЕВКА...И...ВЕДРО...

СПРОСИТЬ СТАРИКА...

...КОЛОДЕЦ ?

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

ИДТИ...СЕВЕ...И...ВОСТ...

ВЗЯТ...ВЕРЕ...И...ВЕДР...

СПРО...СТАР...

...КОЛО?

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

В нижеприведенном образце программы рассмотрен вариант обработки SAY TO. Программа ждет, что Вы обратитесь к королю. Он правда не очень разговорчив и подарив ему свой меч SAY TO KING 'TAKE MY SWORD', Вы уловите момент, когда он отвлечется рассматриванием подарка, схватите часы и броситесь бежать. А уж как вам удастся вывести героев на поверхность - это дело Ваше. Листинг 2 5 DIM m(10):DIM с$(10,32)

10 CLS

11 REM Ввод команды играющего.

20 INPUT a$

21 REM Первый этап анализа команды.

30 LET nend=2

31 LET c$(1)="G"

32 LET c$(2)="S"

33 LET m(1)=100

34 LET m(2)=200

35 LET e=20

36 REM Правильнее конечно было бы вводить эти данные через READ/DATA, но так для примера

нагляднее.

37 GO SUB 1000

38 GO TO gt 100 LET nend=1

110 LET c$(1)="GO" 120 LET m(1)=300 130 LET e=200 140 GO SUB 1000 150 GO TO gt 200 LET nend=1 210 LET c$(1)="SAY TO" 220 LET m(1)=400 230 LET е=20 240 GO SUB 1000 250 GO TO gt

30O REM Здесь расположен блок анализа перемещения. Мы не будем его рассматривать в данном примере.

310 REM ......................

398 REM ......................

399 STOP

400 REM Второй этап анализа команды SAY TO. 410 LET nend=1

420 LET c$(1) = "TO KING" 430 LET m(1)=500 440 LET e = 900 450 GO SUB 1000 460 GO TO gt

500 REM Поиск прямой речи. Предположим, что она должна быть ограничена слева и справа не

кавычками, а апострофами. 510 LET nend=1

520 LET c$(1)=.....

530 LET m(1)=600 540 LET e = 910 550 GO SUB 1000 560 GO TO gt

600 REM Найден первый апостроф! Теперь можно найти и второй. 605 LET a$=a$(k+1 TO) 610 LET nend=1

620 LET c$(1)=.....

630 LET a(1)=700 640 LET e=920 650 GO SUB 1000

660 GO TO gt

700 REM Высказывание определено и теперь можно его анализировать.

705 LET a$=a$( TO K)

710 LET nend=1

720 LET c$(1)="TAKE"

730 LET m(1)=800

740 LET e=930

750 GO SUB 1000

760 GO TO gt

800 REM Король понял, что он может принять от Вас что-то в подарок, осталось только понять

что именно. 805 LET a$=a$( TO K) 810 LET nend=2 820 LET c$(1)="SWORD" 830 LET m(1)=890 840 LET e=940 850 GO SUB 1000 860 GO TO gt

890 PRINT "король благожелательно улыбнулся, беря Ваш меч в свои руки и внимательно

рассматривая его. Внимание охраны несколько рассеялось, все внимательно смотрят на короля."

899 STOP: REM Наступает момент, когда Вы можете схватить часы и попытаться убежать.

900 PRINT "Попробуйте обратиться к другому персонажу" 905 GO TO 30

910 PRINT "Ваше обращение к персонажу - это прямая речь и ее надо ограничить апострофами

слева и справа." 915 GO TO 20

920 PRINT "Вы забыли закрыть прямую речь справа." 925 GO TO 20.

930 PRINT "король грозно смотрит на Вас и о чем-то шепчется со своими воинами. Пока Вы не

нашли нужных слов для спасения собственной жизни. "' 935 GO TO 20.

940 PRINT "'Я не понимаю, что можешь предложить мне ты, несчастный чужестранец?'- грозно

спрашивает король. Стража напряглась, в зале воцарило напряженное ожидание. " 945 GO то 20

1000 REM Анализатор подстроки в строке.

1005 LET kend=LEN (a$)

1006 LET ktest=LEN(c$) 1010 FOR k=1 TO kend 1020 FOR n=1 TO nend

1030 IF a$(k TO k+ktest-1)=c$(n) THEN LET gt=m(n):GO TO 1070

1040 LET gt=e

1050 NEXT n

1060 NEXT k

1070 RETURN

Еще раз обращаем Ваше внимание на то, что приведенный пример лишен элегантности именно потому, что это учебный пример. В Вашей реальной программе Вы конечно же должны использовать тот факт, что строки 100....200....300... и т.д. имеют одинаковую структуру. Введя подпрограмму, которая будет универсальной для всех этих блоков и вводя данные не через LET, а через READ-DATA, Вы во много раз сократите объем Вашей программы.

Заканчивая этот материал, мы еще раз хотим вам напомнить, что мы не ставили целью научить Вас составлять игровые программы. Это дело очень и очень сложное, к которому надо идти кропотливым трудом не один год. Мы только напомним, что основное направление деятельности "ИНФОРКОМа" - обучающие программы, а хорошая обучающая программа строится по тем же самым принципам, что и игровая.

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

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

Обучающие программы

Очень и очень многие пишут о том, как нужны им обучающие программы. Сегодня для них радостное сообщение пришло из Бухары. Наш читатель Подкорытов Л.К. выполнил русификацию пакета TUTOR. Для тех, кто не знает, сообщаем - это 40 уроков АССЕМБЛЕРа и этот пакет был бы замечательным дополнением к нашему трехтомнику по программированию в машинных кодах. Мы, к сожалению, перегружены сейчас собственными проектами и не сможем принять маркетинг этого пакета на себя, но полагаем, что те, кому он нужен, смогут обратиться к т. Подкорытову напрямую по адресу:

705022, г. Бухара-22, ул. Ульянова, д.82. кв.115.

Для тех, кто тоже работает в этом направлении мы всегда дадим "Зеленую улицу". И вот Вам адреса для потенциального партнерства:

ИЩЕМ ОБУЧАЮЩЕ ПРОГРАММЫ ДЛЯ ПК "SPECTRUM" ПО СПЕЦИАЛЬНОСТЯМ:

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

Нужны программы по "Правилам дорожного движения".

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

Обработаем поступающую информацию и вышлем всем желающим.

Наш адрес: 659700, г. Горно-Алтайск, ул. Маресьева 11/1. Межшкольный учебно-производственный комбинат. Сарычевой Т.А.

ДЛЯ ЭКСПЛУАТАЦИИ В ВУЗЕ требуются обучающие программы для ПК "Спектрум".

453135, Стерлитамак-25, а/я 75 Веревкину Игорю Дмитриевичу.

И еще одна нужная вам информация:

Малое предприятие "РИТМ" просит отозваться всех программистов, пишущих игровые программы для "Спектрума".

Контактный адрес: 400009, Волгоград, пр. Ленина, д.129,кв.45. Харионовскому А.В.




СОДЕРЖАНИЕ:


  Оставте Ваш отзыв:

  НИК/ИМЯ
  ПОЧТА (шифруется)
  КОД



Темы: Игры, Программное обеспечение, Пресса, Аппаратное обеспечение, Сеть, Демосцена, Люди, Программирование

Похожие статьи:
Анонс
Подписка - Подписка на газету Оптрон для пользователей сети Internet и Fido.
PartyZone - Chaos Constructions'o1 ZX results.
Смак - бутерброды.
Разберемся - Подробный отчет о прохождении игры ЗВЕЗДНОЕ НАСЛЕДИЕ - 1.

В этот день...   25 апреля