2 buttons pressed at the same time elevator logic
if we are in level 1, both the levels 2 and 3 are pressed it should go
  to level 2 even if level 3 was pressed first.


For this to work, the program should remember which buttons (mind the
plural!) have been pressed. Thus, instead of remembering only one
request, as in

int required_level =-1;


it should have a boolean variable for each of the possible levels,
telling us whether a stop was requested for that level.

For convenience, I would number the levels from zero, and hold these
variables in an array:

const int LEVEL_COUNT = 3;
bool requested_stop[LEVEL_COUNT];



  if we are in level 2 and both level 1 and 3 are pressed, it should go
  to the one that is pressed first as both levels are the same distance
  from level 2.


The part I emphasized doesn't make sense to me. The elevator should go
to the one that was pressed first, irrespective of the distances.
Imagine you are in an elevator at level 5, and press the button for
level 2. As the elevator just starts moving down, another rider presses
the button for level 6. Should the elevator immediately revert to going
up in order to reach level 6, which is closer? Of course not. If it is
going down, it should continue in that direction. Now, if the other
rider presses 3, it should stop by level 3 on its way down, even though
you pressed 2 first.

As stated by chrisl in a comment, a finite state machine is
definitely the solution for this kind of problems. I propose a state
machine with three states, STOPPED, GOING_UP, and GOING_DOWN:


when STOPPED, it should change to GOING_UP or GOING_DOWN as soon
as a button for another level is pressed
when GOING_UP, as soon as it reaches a level that has been
requested, it should change to STOPPED
same thing when GOING_DOWN.


And here is my proposed implementation:

void loop() {
    // Check the buttons.
    for (int i = 0; i &lt; LEVEL_COUNT; i++)
        if (digitalRead(button[i]) == HIGH)
            requested_stop[i] = true;

    // Finite state machine.
    static enum { STOPPED, GOING_UP, GOING_DOWN } state = STOPPED;
    switch (state) {
    case STOPPED:
        requested_stop[current_level] = false;
        for (int i = 0; i &lt; LEVEL_COUNT; i++) {
            if (requested_stop[i]) {
                if (i &lt; current_level) {
                    analogWrite(pwmMot, PWM_DOWN);
                    state = GOING_DOWN;
                    break;
                } else if (i &gt; current_level) {
                    analogWrite(pwmMot, PWM_UP);
                    state = GOING_UP;
                    break;
                }
            }
        }
        break;
    case GOING_UP:
        if (elevator_height() &gt;= LEVEL_HEIGHT[current_level + 1]) {
            current_level++;
            if (requested_stop[current_level]) {
                analogWrite(pwmMot, PWM_STOP);
                state = STOPPED;
            }
        }
        break;
    case GOING_DOWN:
        if (elevator_height() &lt;= LEVEL_HEIGHT[current_level - 1]) {
            current_level--;
            if (requested_stop[current_level]) {
                analogWrite(pwmMot, PWM_STOP);
                state = STOPPED;
            }
        }
        break;
    }
}


This code assumes you have written the function elevator_height() that
measures the height of the elevator, and have defined an array of
constants LEVEL_HEIGHT[].

Notice that this is still far from perfect. You should probably ensure
that each stop lasts at least some minimum duration. Otherwise, if the
elevator stops at level 1 while level 0 has also been requested, the
stop will only last an instant. This can be achieved by splitting the
STOPPED state in two distinct states, and switching from “waiting for
the riders to go in/out” to “waiting for a button to be pressed” on a
timeout. You may also want to ensure that, after a stop, the elevator
continues in the same direction if possible. Otherwise it will never
reach level 2 if some joker is repeatedly pressing 0 and 1.