[Из песочницы] Если бы CRT модуль Паскаля был в JavaScript

Попытка реализовать известный модуль CRT, используемый в Pascal, в JavaScript. Что из этого получилось, а что нет, расскажу.

Вступление


Мое знакомство с программированием началось еще в 8 классе, когда я впервые узнал на уроке информатики, что такое Pascal и какие он дает возможности. Тогда на школьных компьютерах был установлен Turbo Pascal, хотя учитель информатики давно хотел поставить туда PascalABC.NET. Безусловно, начиналось все с банальных выводов строки в консоли, моя деятельность в основном была направлена на отличную подготовку к ОГЭ. Никаких модулей не изучалось, ибо на экзамене этого никто и не требовал.

Но даже тогда, когда я мог себе «подчинить» консольное окно, выводить все, что туда захочется, производить вычисления, принимать ввод от пользователя, я был удивлен, насколько это круто!

Но время идет, жизнь меняется: ОГЭ сдано, ЕГЭ пройдено, успешное поступление в ВУЗ. Всё это время я с огромным интересом изучал новые языки, в результате чего уже могу спокойно писать сайты, будь это front или back. Почему-то веб-программирование меня больше всего интересует.

Как дошло дело до CRT


Еще в школьные годы я изучил один из интересных модулей Pascal под названием CRT. На самом деле в нем нет ничего сложного, набор команд, по сути, маленький, но они позволяли в консольном окне творить новые вещи: перемещать курсор по экрану размером 80×25 (размер экрана DOS), менять цвет фона и текста, воспроизводить звук определенной частоты и продолжительности. На нем можно было создавать полноценные ASCII игры, которые практически не занимали место на жестком диске в силу их маленького размера.

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

Сама идея


Проект имеет очень простую структуру из трех файлов:

  • crt.js — файл с функциями, который нужно подключить к html файлу
  • index.html — файл — основа, который следует открыть в браузере
  • user.js — пустой файл, в котором программист должен писать свой код


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

Реализованные команды:

  • gotoxy (x, y) — перемещение курсора в координаты
  • write (str) — вывод строки на экран
  • clrscr () — очистка экрана выбранным заранее фоном и перемещение курсора в координаты 1,1
  • textcolor (int) — смена цвета текста
  • textbackground (int) — смена цвета фона
  • sound (fr,1000) — воспроизвести звук частотой fr и продолжительностью 1 секунда


Давайте покажу пример работы «модуля»:

Код:

image

Результат:

image

Вам может показаться, что буквы стоят отдельно друг от друга. Да, так и есть. Дело в том, что здесь содержимое страницы поделено на части div’ами. Давайте вспомним размер окна DOS (80×25). Значит, сколько здесь div’ов? Правильно, 2000. Каждый из них имеет равный размер. Вообще, при запуске страницы автоматически выполняется следующая функция:

image

Я специально повесил эту работу на JS. Я хотел, чтобы в html файле было чисто и понятно.

image

Да, из-за такой схемы есть эффект, при запуске страницы на слабеньком ПК, думаю, секунд 4–5 будет происходить только загрузка, ибо цикл довольно сложный. Комментировать каждую строку не вижу смысла, на фото основные действия объяснены. Каждый раз генерируем div с определенными id и параметрами и добавляем его в body. Каждый div содержит только один символ, как это было по аналогии в DOS (одна ячейка — один символ).

Работа с координатами и цветами основана на этих переменных:

image

Команды gotoxy (x, y), textcolor (int), textbackground (int) просто меняют содержимое переменных xnow, ynow, color, bgcolor.

С цветами есть интересные моменты. В DOS, как мы знаем, можно было выбирать цвет из набора, в котором было всего 16 цветов. В Pascal можно обращаться к цвету с помощью номера (0–15). Причем в DOS’е фон избирался только из первых восьми цветов, а текст из всех 16. Тогда как уже в Windows в PascalABC.NET при подключении модуля фон можно менять из всех 16 цветов. Возможно не все поняли, что я хотел сейчас донести, но давайте поясню на примере:

image

Здесь перечислены все цвета, которые используются в консоли. Если мы попробуем поменять фон в DOS’е на светло-зеленый (10), то background станет зеленым (2), тогда как шрифт станет того цвета, которого мы требовали. Почему-то возможности изменения фона в DOS’е (Free Pascal) ограничены восемью цветами.

А теперь о команде clrscr, которая очищала экран определенным цветом. В JS я её реализовал так:

image

Здесь нет ничего сложного. Мы циклом проходим все div’ы, где в каждом содержимое делаем пустым (так как в DOS символы стираются) и меняем фон на цвет, выбранный заранее командой textbackground. И, конечно, не забываем вернуть курсор в положение 1,1 (левый верхний угол окна).

Самое интересное — это вывод строки командой write. Да, я помню, что есть еще writeln, но посчитал, что будет достаточно и одной команды, так как в данной ситуации перевод курсора на новую строку нас не интересует.

Реализация:

image

Здесь нужно было уберечь браузер от ошибки, в случае, если пользовательская строка собиралась выйти за границы окна (а там div’ов нет!). Поэтому было решено сделать цикл с защитой break.

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

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

Мы помним, что для вывода, например, звука частотой 200 Гц и продолжительностью 1 секунда нужно написать код:

sound(200);
delay(1000);
nosound;


В JS пришлось сделать так:

image

Но зато это работает! Реализация:

image

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

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

image

Я попытался решить проблему с помощью setTimeout, однако это не всегда работает.

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

Заключение


Даже после активного верстания сайтов хочется попробовать написать что-то необычное, даже если это не имеет практической пользы. Pascal с его модулем CRT действительно в свое время оказал на меня эффект, который сподвиг меня на дальнейшее изучение языков программирования. А может, стоит написать что-нибудь в стиле ASCII?

На всякий случай выложил это на GitHub

© Habrahabr.ru