// elev.cpp // содержит определения данных и методов класса #include "elev.h" //включить объявление класса /////////////////////////////////////////////////////////// // определения функций для класса building /////////////////////////////////////////////////////////// building::building() //конструктор { char ustring[BUF_LENGTH]; //строка для номеров этажей init_graphics(); //инициализация графики clear_screen(); //очистка экрана num_cars = 0; for(int k=0; kcar_tick1(); //послать временную метку 1 for(j=0; jcar_tick2(); //послать временную метку 2 } //конец master_tick() //--------------------------------------------------------- void building::show_floor_reqs() const //вывод запросов { for(int j=0; jget_floor(); } //--------------------------------------------------------- //get_cars_dir() – определение направления direction building::get_cars_dir(const int carNo) const { return car_list[carNo]->get_direction(); } //--------------------------------------------------------- /////////////////////////////////////////////////////////// // определения функций класса elevator /////////////////////////////////////////////////////////// //конструктор elevator::elevator(building* ptrB, int nc) : ptrBuilding(ptrB), car_number(nc) { current_floor = 0; //начать с 0 (для пользователя - 1) old_floor = 0; //запомнить предыдущий этаж current_dir = STOP; //вначале стоит на месте for(int j=0; jget_floor_req(UP, current_floor) && current_dir != DN) ) { current_dir = UP; //(если была остановка) //удалить ЗЭ в данном направлении движения ptrBuilding->set_floor_req(current_dir, current_floor, false); if( !loading_timer) //посадка loading_timer = LOAD_TIME; return; } //Если запрос «вниз» с этого этажа и если мы едем вниз или //стоим, посадить пассажиров if( (ptrBuilding->get_floor_req(DN, current_floor) && current_dir != UP) ) { current_dir = DN; //(если была остановка) //удалить ЗЭ данного направления ptrBuilding->set_floor_req(current_dir, current_floor, false); if( !loading_timer) //посадка loading_timer = LOAD_TIME; return; } //проверка других назначений или ЗЭ //расстояние считать до ближайшего запроса destins_above = destins_below = false; requests_above = requests_below = false; for(j=current_floor+1; jget_floor_req(UP, j) || ptrBuilding->get_floor_req(DN, j) ) { //если ЗЭ requests_above = true; //установить флаг if( !nearest_higher_req ) //если еще не установлен nearest_higher_req = j; //установить ближайший ЗЭ } } for(j=current_floor-1; j>=0; j--) //проверка нижних этажей { if(destination[j] ) //если назначения destins_below = true; //установить флаг if( ptrBuilding->get_floor_req(UP, j) || ptrBuilding->get_floor_req(DN, j) ) { //если запросы requests_below = true; //установить флаг if( !nearest_lower_req ) //если еще не установлен nearest_lower_req = j; //установить ближайший ЗЭ } } //если нет запросов сверху/снизу, остановиться if( !destins_above && !requests_above && !destins_below && !requests_below) { current_dir = STOP; return; } //если есть назначение, а мы стоим или движемся к нему, //начать/продолжать движение if( destins_above && (current_dir==STOP || current_dir==UP) ) { current_dir = UP; return; } if( destins_below && (current_dir==STOP || current_dir==DN) ) { current_dir = DN; return; } //проверка, есть ли другие лифты, (a) того же направления //между нами и ближайшим ЗЭ, или //(b) встречного направления с другой стороны ЗЭ car_between_up = car_between_dn = false; car_opposite_up = car_opposite_dn = false; for(j=0; jget_cars_floor(j); //и odir = ptrBuilding->get_cars_dir(j); //направление //если едет вверх, и ЗЭ вверху if( (odir==UP || odir==STOP) && requests_above ) //если он при этом между нами и ЗЭ if( (ofloor > current_floor && ofloor <= nearest_higher_req) //или там же, но его номер ниже || (ofloor==current_floor && j < car_number) ) car_between_up = true; //если он едет вниз, и ЗЭ внизу if( (odir==DN || odir==STOP) && requests_below ) //если он снизу, но над ближайшим ЗЭ if( (ofloor < current_floor && ofloor >= nearest_lower_req) //или на том же этаже, но с меньшим номером || (ofloor==current_floor && j < car_number)) car_between_dn = true; //если идет вверх, а ЗЭ снизу if( (odir==UP || odir==STOP) && requests_below ) //и он ниже ЗЭ и ближе к нему, чем мы if(nearest_lower_req >= ofloor && nearest_lower_req - ofloor < current_floor - nearest_lower_req) car_opposite_up = true; //если идет вниз, а ЗЭ сверху if( (odir==DN || odir==STOP) && requests_above ) //и он над ЗЭ и ближе к нему, чем мы if(ofloor >= nearest_higher_req && ofloor - nearest_higher_req < nearest_higher_req - current_floor) car_opposite_dn = true; } //конец if(не для нашего лифта) } //конец for(для каждого лифта) //если идем вверх или остановились, а ЗЭ над нами //и между нами и ЗЭ нет идущих вверх лифтов //или идущих вниз над ЗЭ и ближе к нему, чем мы, тогда //ехать вверх if( (current_dir==UP || current_dir==STOP) && requests_above && !car_between_up && !car_opposite_dn ) { current_dir = UP; return; } //если идем вниз или остановились, и снизу есть ЗЭ, //и нет лифтов, идущих вниз, между нами и ЗЭ //или под ЗЭ, идущих вверх и ближе нас к ЗЭ if( (current_dir==DN || current_dir==STOP) && requests_below && !car_between_dn && !car_opposite_up ) { current_dir = DN; return; } //если больше ничего не происходит, остановиться current_dir = STOP; } //end decide(), finally //--------------------------------------------------------- void elevator::move() { //если посадка или высадка, if(loading_timer || unloading_timer) //не двигаться return; if(current_dir==UP) //если идем вверх, идти вверх current_floor++; else if(current_dir==DN) //если идем вниз, идти вниз current_floor--; } //end move() //--------------------------------------------------------- void elevator::get_destinations() //остановка, получение //пунктов назначения { char ustring[BUF_LENGTH]; //входной рабочий буфер int dest_floor; //этаж назначения set_cursor_pos(1,22);clear_line();//удалить верхнюю строку set_cursor_pos(1, 22); cout << "Лифт " << (car_number+1) << " остановился на этаже " << (current_floor+1) << "\nЭтаж назначения (0 для окончания ввода)"; for(int j=1; j