Р. ЛАФОРЕ ОБЪЕКТНО-ОРИЕНТИРОВАННОЕ ПРОГРАММИРОВАНИЕ В 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 (см. приложение Д «Упрощенный вариант консольной графики»).
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
