Subversion Repositories programming

Rev

Rev 334 | Rev 336 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
321 ira 1
 
2
#include "controller.h"
3
 
4
Controller::Controller (int num_floors, int num_elevators) : num_floors (num_floors), num_elevators (num_elevators)
5
{
6
    assert (num_floors > 2);
7
    assert (num_elevators > 0);
8
 
334 ira 9
    elevator.reserve (num_elevators);
331 ira 10
 
11
    for (int i=0; i<num_elevators; i++)
332 ira 12
    {
334 ira 13
        elevator.push_back (new Elevator (num_floors));
14
        elevator.at(i) -> set_controller (this);
332 ira 15
    }
335 ira 16
 
17
    // Seed the RNG
18
    srandom (time(NULL));
321 ira 19
}
20
 
21
Controller::~Controller ()
22
{
23
}
24
 
329 ira 25
void Controller::request_elevator (int on_floor, int direction)
321 ira 26
{
334 ira 27
    assert (on_floor < num_floors);
28
    assert (on_floor >= 0);
331 ira 29
    assert (direction == MOVE_UP || direction == MOVE_DOWN);
328 ira 30
 
31
    float distance = INT_MAX;
32
    int elevator_number;
33
 
34
    // check that there is not already an elevator requested
35
    // to this floor. If there is already one, ignore this
36
    // request.
37
    if (floor_already_requested (on_floor))
38
        return;
39
 
335 ira 40
    //puts("2");
334 ira 41
 
328 ira 42
    // find elevator that is closest, AND NOT moving away
43
    // "push" it's button
332 ira 44
    elevator_number = find_closest_elevator (on_floor, direction);
334 ira 45
    elevator.at(elevator_number) -> push_button (on_floor);
332 ira 46
 
47
    printf ("elevator[%d] gets queued for floor: %d\n", elevator_number, on_floor);
321 ira 48
}
49
 
328 ira 50
/**
51
 * Check if there is an elevator already in the queue to stop
52
 * at the floor given as a parameter.
53
 */
54
bool Controller::floor_already_requested (int on_floor)
55
{
56
    int i;
57
 
58
    for (i=0; i<num_elevators; i++)
334 ira 59
        if (elevator.at(i) -> button_is_pushed (on_floor))
328 ira 60
            return true;
61
 
62
    return false;
63
}
64
 
65
/**
66
 * Return the number of the closest elevator to the
67
 * floor given as a parameter.
68
 *
69
 * We only want to choose elevators that are close and
70
 * heading in the right direction, or the closest elevator
71
 * if it is sitting idle.
72
 */
332 ira 73
int Controller::find_closest_elevator (int to_floor, int in_direction)
328 ira 74
{
75
    int i;
76
    float distance = INT_MAX;
77
    float temp_distance;
335 ira 78
    int answer = -1;
328 ira 79
 
80
    float cur_floor;
335 ira 81
    int   cur_direction;
328 ira 82
 
335 ira 83
    printf ("finding closest elevator: to_floor=%d -- in_direction=%d\n", to_floor, in_direction);
84
 
328 ira 85
    for (i=0; i<num_elevators; i++)
86
    {
334 ira 87
        cur_floor = elevator.at(i) -> get_current_floor ();
335 ira 88
        cur_direction = elevator.at(i) -> get_direction ();
328 ira 89
        temp_distance = fabsf (cur_floor - to_floor);
90
 
335 ira 91
        printf ("cur_floor=%e -- direc=%d -- t_dist=%e\n", cur_floor, cur_direction, temp_distance);
334 ira 92
 
332 ira 93
        // Automatically discard elevators that are moving in the wrong
94
        // direction, but DO consider ones that are idle.
335 ira 95
        if (cur_direction == MOVE_DOWN && in_direction == MOVE_UP)
96
        {
97
            printf ("type 1: skipped elevator[%d]\n", i);
332 ira 98
            continue;
335 ira 99
        }
332 ira 100
 
335 ira 101
        if (cur_direction == MOVE_UP && in_direction == MOVE_DOWN)
102
        {
103
            printf ("type 2: skipped elevator[%d]\n", i);
334 ira 104
            continue;
335 ira 105
        }
334 ira 106
 
335 ira 107
        if (cur_floor < to_floor && cur_direction == MOVE_UP)
328 ira 108
        {
335 ira 109
            printf ("good cantidate type 1\n");
110
            // GOOD CANTIDATE
111
            if (temp_distance < distance)
328 ira 112
            {
113
                answer = i;
114
                distance = temp_distance;
115
            }
335 ira 116
        }
117
 
118
        if (cur_floor > to_floor && cur_direction == MOVE_DOWN)
119
        {
120
            printf ("good cantidate type 2\n");
121
            // GOOD CANTIDATE
122
            if (temp_distance < distance)
328 ira 123
            {
124
                answer = i;
125
                distance = temp_distance;
126
            }
127
        }
335 ira 128
 
129
        if (cur_direction == IDLE && temp_distance < distance)
130
        {
131
            printf ("idle cantidate\n");
132
            answer = i;
133
            distance = temp_distance;
134
        }
328 ira 135
    }
136
 
335 ira 137
    // If we failed to find an elevator, then we need to
138
    // pick at random.
139
    if (answer == -1)
140
    {
141
        // Pick a random number in the range [0,num_elevators-1]
142
        answer = (int) (0.0 + ((num_elevators - 1.0) * (random() / (RAND_MAX + 1.0))));
143
 
144
        printf ("picked at random: %d\n", answer);
145
 
146
        assert (answer >= 0);
147
        assert (answer < num_elevators);
148
    }
149
 
328 ira 150
    return answer;
151
}
152
 
329 ira 153
void Controller::disable_elevator (int elevator_number)
154
{
155
}
156
 
157
void Controller::enable_elevator (int elevator_number)
158
{
159
    // make sure elevator is enabled first
160
}
161
 
331 ira 162
void Controller::start_all_elevators ()
163
{
164
    int i;
165
 
166
    for (i=0; i<num_elevators; i++)
334 ira 167
        elevator.at(i) -> thread_start ();
331 ira 168
}
169
 
170
void Controller::stop_all_elevators ()
171
{
172
    int i;
173
 
174
    for (i=0; i<num_elevators; i++)
334 ira 175
        elevator.at(i) -> thread_stop ();
331 ira 176
}
177
 
178
void Controller::pause_all_elevators ()
179
{
180
    int i;
181
 
182
    for (i=0; i<num_elevators; i++)
334 ira 183
        elevator.at(i) -> thread_pause ();
331 ira 184
}
185
 
186
void Controller::unpause_all_elevators ()
187
{
188
    int i;
189
 
190
    for (i=0; i<num_elevators; i++)
334 ira 191
        elevator.at(i) -> thread_unpause ();
331 ira 192
}
193
 
334 ira 194