Р. ЛАФОРЕ ОБЪЕКТНО-ОРИЕНТИРОВАННОЕ ПРОГРАММИРОВАНИЕ В C++ (4-Е ИЗДАНИЕ) (часть13) онлайн

Проектирование системы

Лифты могут быть приблизительно одинаковыми, поэтому есть смысл сделать

их объектами одного класса под названием elevator. В этом классе содержатся

данные, характерные для каждого отдельно взятого лифта: текущее местополо-

жение, направление движения, номера этажей назначения и т. д.

Тем не менее есть данные обо всем здании в целом. Эти данные будут частью

класса building. Во-первых, есть массив запросов с этажей. Это список этажей,

где люди, ждущие лифта, нажали кнопку «вверх» или «вниз» и тем самым попро-

сили лифт подъехать к ним. Любой из лифтов может отвечать на эти запросы,

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

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

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

Третий элемент данных в этом классе — это число уже созданных лифтов. Это позволяет лифтам иметь свой уникальный идентификатор.

Управление временем

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

После этого каждый лифт должен быть сдвинут на свою новую позицию. Так. Что-то в этом месте все усложняется. Поскольку каждый лифт должен знать, где находятся остальные, прежде чем принять решение, все лифты долж- ны пройти через процесс принятия решения, прежде чем кто-либо из них сдви- нется с места. Чтобы удостовериться в том, что это действительно имеет место, мы запускаем tick'и дважды для каждой кабинки. Таким образом, car_tickl() вызывается для принятия решения о том, куда каждый лифт поедет, а другая функция — car_tick2() — для реального запуска лифтов. Изменяется значение переменной current_floor — кабинки начинают двигаться.

Процесс посадки пассажиров включает в себя последовательность опреде- ленных шагов, которые на экране отображаются так:

кабинка с закрытыми дверями, счастливое лицо отсутствует;

кабинка с открытыми дверями, счастливое лицо слева;

кабинка со счастливым лицом в открытых дверях, узнать от пассажира конечный этаж;

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

При высадке пассажира применяется обратный порядок. Эти последова- тельности действий осуществляются с помощью таймера (целочисленной пе- ременной), который уменьшается с каждой временной отметкой (tick) от 3 до 0. С помощью case в функции car_display() выбирается и рисуется на экране соот- ветствующая версия изображения лифта.

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

ров Microsoft или BORLACON.H для компиляторов Borland (см. приложение Д «Упрощенный вариант консольной графики»).

 

21