Danny Watson
Danny Watson

Reputation: 165

Forever lost in if, while and foreach statement - cannot get the appropriate condition to run

I have spent a fair few hours on this problem, it's quite basic but has gotten out of hand quickly.

Because it is rather confusing I'll post what I want it to do and what it actually does

Goal

If a supervisor is busy, it will move onto the next one, if they are all busy it will display a message "Sorry all supervisors are busy". Likewise with all employees.

Method

I want the method to read all the supervisors, if one is not busy it continues down, then I want it to read all of the employees, if one is not busy it continues down.

Then it reads if the employee has the appropriate skill and if the success has already been met, to avoid the same person being assigned the same job.

if this is all good so far, it checks if the supervisor is occupied, if it is, it reverts back and changes supervisor.

It then assigns the employee with the information, also assigning the supervisor with some and checking the 'success' condition.

From here it starts to get a bit sloppy, as you can see, I have put numerous boolean statements to simply get the program out of the loops and exit it.

After all of this, the program assigns the work, so far, it works to a reasonable degree, but I want there to be a message that states that if all of the supervisors are busy that no more work can be allocated.

I have in the past, used MessageBox.Show after foreach statements but if one supervisor is busy it will display the message which is not what I want.

Code

Method to distribute a job

bool finishLast = false;
bool successFirst = false;
while (successFirst != true)
{
    foreach (Supervisor sup in supervisors)
    {
        bool failure = false;
        while (failure != true)
        {
            foreach (Employee emp in employees)
            {
                if (emp.Busy == false && emp.Skills.HasFlag(_skillRequired) && successFirst == false)
                {
                    if (sup.SupervisorOccupied == false)
                    {
                        successFirst = true;
                        emp.EmployeeWorkload = _jobName;
                        emp.ShiftsLeft = _shiftsLeft;
                        emp.Busy = true;
                        sup.EmployeeWorkload = "Supervising Employee: " + emp.EmployeeName + " to finish task: " + emp.EmployeeWorkload;
                        sup.ShiftsLeft = _shiftsLeft;
                        sup.SupervisorOccupied = true;
                    }
                }
                else if (emp.Busy == true)
                {
                    failure = true;
                }
            }
        }
        if (failure == true)
        {
            finishLast = true;
        }
    }
    if (finishLast == true)
    {
        successFirst = true;
    }
}

Of course if anyone can think of a simpler way of having this I will be open to ideas.

EDIT 1

This is not a multi-threaded system, yes emp.Busy and sup.SupervisorOccupied are technically the same thing, they are both in the same class so yes sup could inherit emp.Busy.

Upvotes: 3

Views: 132

Answers (2)

Lasse V. Karlsen
Lasse V. Karlsen

Reputation: 391396

Here's how you should write that code:

var availableSupervisor = supervisors
    .FirstOrDefault(supervisor => !supervisor.SupervisorOccupied);
if (availableSupervisor == null)
    return;

var availableEmployee = employees
    .FirstOrDefault(employee => !employee.Busy && employee.Skills.HasFlag(_skillRequired));
if (availableEmployee == null)
    return;

availableEmployee.EmployeeWorkload = _jobName;
availableEmployee.ShiftsLeft = _shiftsLeft;
availableEmployee.Busy = true;
availableSupervisor.EmployeeWorkload = "Supervising Employee: " + emp.EmployeeName + " to finish task: " + emp.EmployeeWorkload;
availableSupervisor.ShiftsLeft = _shiftsLeft;
availableSupervisor.SupervisorOccupied = true;

Upvotes: 3

Leonardo Spina
Leonardo Spina

Reputation: 680

I think something like this should work:

        bool assigned = false;
        foreach (Supervisor sup in supervisors)
        {
            if (!sup.SupervisorOccupied)
            {
                foreach (Employee emp in employees)
                {
                    if (!emp.Busy && emp.Skills.HasFlag(_skillRequired))
                    {
                        assigned = true;
                        emp.EmployeeWorkload = _jobName;
                        emp.ShiftsLeft = _shiftsLeft;
                        emp.Busy = true;
                        sup.EmployeeWorkload = "Supervising Employee: " + emp.EmployeeName + " to finish task: " + emp.EmployeeWorkload;
                        sup.ShiftsLeft = _shiftsLeft;
                        sup.SupervisorOccupied = true;
                        break;
                    }
                }
            }
            if (assigned)
                break;
        }

if at the end "assigned == false", no employee is available (actually there's some code missing so it can't run, but theoretically it should do what you want!).

Upvotes: 5

Related Questions