Reputation: 165
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
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
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