public final boolean isValidMove (final char action) {
        final char direct = getDirectByAction(action);
        if (direct == '\0') {
            // It's a invalid action.
            return false;
        }

        final Point newPos = new Point(minerPos);
        movePos(newPos, direct);
        if (!isInBound(newPos)) {
            // This move is out of bound of map.
            return false;
        }

        final char spot = map[newPos.x][newPos.y];
        if (spot == WALL || spot == LIFT) {
            // Can not go through the wall nor the closed lift.
            return false;
        }

        if (spot == ROCK && (direct == DIRECT_RIGHT || direct == DIRECT_LEFT)) {
            final Point posBehindRock = new Point(newPos);
            movePos(posBehindRock, direct);
            if (!isInBound(newPos)) {
                /* Rock is at the bound of map, so rock cannot be pushed, so
                 * this move is invalid. */
                return false;
            } else {
                final char spotBehindRock =
                        map[posBehindRock.x][posBehindRock.y];
                /* The spot behind rock is empty, so rock can be pushed, so
                 * this move is valid. Otherwise it's invalid. */
                return (spotBehindRock == EMPTY);
            }
        } // if (spot == ROCK && (direct == DIRECT_RIGHT ||

        // Other situations is valid.
        return true;
    }