Fixed the waiting time calculation and added graphical representation on the checkouts fill
This commit is contained in:
@@ -0,0 +1,237 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Caisses
|
||||
{
|
||||
internal class GraphicalStore
|
||||
{
|
||||
private List<GraphicalCheckout> _checkouts;
|
||||
private List<GraphicalClient> _clients;
|
||||
private int _timeOfTheDayInMinuts;
|
||||
private Bitmap _shelvesCorner;
|
||||
private Bitmap _checkoutCorner;
|
||||
private Random rnd;
|
||||
|
||||
public static readonly int[] ATTENDANCE = { 0, 0, 0, 0, 0, 0, 0, 30, 30, 40, 50, 60, 100, 80, 50, 30, 80, 100, 50, 50, 80, 0, 0, 0 };
|
||||
const int CROSSOVER_TIME = 10;
|
||||
|
||||
public int TimeOfTheDayInMinuts { get => _timeOfTheDayInMinuts; set => _timeOfTheDayInMinuts = value; }
|
||||
public List<GraphicalClient> Clients { get => _clients; set => _clients = value; }
|
||||
internal List<GraphicalCheckout> Checkouts { get => _checkouts; set => _checkouts = value; }
|
||||
public Bitmap ShelvesCorner { get => _shelvesCorner; set => _shelvesCorner = value; }
|
||||
public Bitmap CheckoutCorner { get => _checkoutCorner; set => _checkoutCorner = value; }
|
||||
|
||||
public int TimeOfTheDayInHours
|
||||
{
|
||||
get { return _timeOfTheDayInMinuts / 60; }
|
||||
}
|
||||
|
||||
public GraphicalStore(int startingHour,int checkoutNumber, Size shelvesCornerSize,Size checkoutCornerSize)
|
||||
{
|
||||
TimeOfTheDayInMinuts = startingHour * 60;
|
||||
Clients = new List<GraphicalClient>();
|
||||
Checkouts = new List<GraphicalCheckout>();
|
||||
CheckoutCorner = new Bitmap(checkoutCornerSize.Width,checkoutCornerSize.Height);
|
||||
ShelvesCorner = new Bitmap(shelvesCornerSize.Width,shelvesCornerSize.Height);
|
||||
rnd = new Random();
|
||||
|
||||
FillStore(ATTENDANCE[TimeOfTheDayInHours]);
|
||||
populateCheckouts(checkoutNumber);
|
||||
Tick();
|
||||
}
|
||||
public void populateCheckouts(int numberOfCheckouts)
|
||||
{
|
||||
int checkoutWidth = CheckoutCorner.Width / numberOfCheckouts + 1;
|
||||
for (int i = 0; i < numberOfCheckouts; i++)
|
||||
{
|
||||
Point position = new Point(i * checkoutWidth + checkoutWidth / numberOfCheckouts, 0);
|
||||
Checkouts.Add(new GraphicalCheckout(position, new Rectangle(new Point(0, 0), new Size(CheckoutCorner.Width, CheckoutCorner.Height)), numberOfCheckouts));
|
||||
}
|
||||
}
|
||||
|
||||
public void Tick()
|
||||
{
|
||||
TimeOfTheDayInMinuts++;
|
||||
if (TimeOfTheDayInMinuts % 60 == 0)
|
||||
{
|
||||
if (TimeOfTheDayInMinuts >= 24 * 60)
|
||||
{
|
||||
TimeOfTheDayInMinuts = 0;
|
||||
}
|
||||
//Its a new Hour so we can send the new clients
|
||||
int amountOfNewCLients = ATTENDANCE[TimeOfTheDayInHours];
|
||||
FillStore(amountOfNewCLients);
|
||||
}
|
||||
|
||||
foreach (GraphicalClient client in Clients)
|
||||
{
|
||||
client.Tick();
|
||||
}
|
||||
foreach (GraphicalCheckout checkout in Checkouts)
|
||||
{
|
||||
checkout.Tick(GetAverageWaitingTime(),CROSSOVER_TIME,GetAmountOfOpenCheckouts());
|
||||
}
|
||||
|
||||
//Processing the checkout mechanism
|
||||
int openPlacesAmount = GetAmountOfPlacesLeft();
|
||||
|
||||
List<GraphicalClient> clientsToRemove = new List<GraphicalClient>();
|
||||
foreach (GraphicalClient client in Clients)
|
||||
{
|
||||
if (client.State == Client.ClientState.Waiting)
|
||||
{
|
||||
if (openPlacesAmount > 0)
|
||||
{
|
||||
List<GraphicalCheckout> checkoutsWithFreeSpace = GetNotFullCheckouts();
|
||||
if (checkoutsWithFreeSpace.Count > 0)
|
||||
{
|
||||
//Now we select a random one to put our waiting client
|
||||
int index = 0;
|
||||
int count = checkoutsWithFreeSpace.Count - 1;
|
||||
if (count > 0)
|
||||
{
|
||||
index = rnd.Next(0, checkoutsWithFreeSpace.Count - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
index = 0;
|
||||
}
|
||||
checkoutsWithFreeSpace[index].Clients.Add(client);
|
||||
//Clients.Remove(client);
|
||||
clientsToRemove.Add(client);
|
||||
client.State = Client.ClientState.Inline;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach (GraphicalClient client in clientsToRemove)
|
||||
{
|
||||
Clients.Remove(client);
|
||||
}
|
||||
|
||||
foreach (GraphicalCheckout checkout in Checkouts)
|
||||
{
|
||||
if (checkout.Open && checkout.Clients.Count > 0)
|
||||
{
|
||||
Client cClient = checkout.Clients[0];
|
||||
if (cClient.State != Client.ClientState.Checkout)
|
||||
cClient.State = Client.ClientState.Checkout;
|
||||
|
||||
if (cClient.CheckoutTime <= 0)
|
||||
{
|
||||
checkout.Clients.Remove(cClient);
|
||||
//We dont load the next because he should be loaded the next time this function is loaded
|
||||
}
|
||||
|
||||
foreach (GraphicalClient ccClient in checkout.Clients)
|
||||
{
|
||||
ccClient.Tick();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public List<Bitmap> Draw()
|
||||
{
|
||||
ShelvesCorner = new Bitmap(ShelvesCorner.Width,ShelvesCorner.Height);
|
||||
CheckoutCorner = new Bitmap(CheckoutCorner.Width,CheckoutCorner.Height);
|
||||
foreach (GraphicalClient client in Clients)
|
||||
{
|
||||
client.Draw(ShelvesCorner);
|
||||
}
|
||||
|
||||
foreach (GraphicalCheckout checkout in Checkouts)
|
||||
{
|
||||
checkout.Draw(CheckoutCorner);
|
||||
foreach (GraphicalClient client in checkout.Clients)
|
||||
{
|
||||
client.Draw(ShelvesCorner);
|
||||
}
|
||||
}
|
||||
|
||||
return new List<Bitmap> { ShelvesCorner, CheckoutCorner };
|
||||
}
|
||||
public virtual void FillStore(int amountOfNewClients)
|
||||
{
|
||||
for (int i = 0; i < amountOfNewClients; i++)
|
||||
{
|
||||
Clients.Add(new GraphicalClient(new Point(0,0),rnd));
|
||||
}
|
||||
}
|
||||
public List<GraphicalClient> GetClientsWithoutCheckout()
|
||||
{
|
||||
List<GraphicalClient> result = new List<GraphicalClient>();
|
||||
foreach (GraphicalClient client in Clients)
|
||||
{
|
||||
if (client.State == Client.ClientState.Waiting)
|
||||
result.Add(client);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
public List<GraphicalCheckout> GetNotFullCheckouts()
|
||||
{
|
||||
List<GraphicalCheckout> result = new List<GraphicalCheckout>();
|
||||
foreach (GraphicalCheckout checkout in Checkouts)
|
||||
{
|
||||
if (checkout.Clients.Count < Checkout.MAX_CAPACITY && checkout.Open)
|
||||
{
|
||||
result.Add(checkout);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
public int GetAmountOfPlacesLeft()
|
||||
{
|
||||
int result = 0;
|
||||
foreach(GraphicalCheckout checkout in Checkouts)
|
||||
{
|
||||
if (checkout.Open)
|
||||
{
|
||||
result += Checkout.MAX_CAPACITY - checkout.Clients.Count();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
public int GetAmountOfOpenCheckouts()
|
||||
{
|
||||
int result = 0;
|
||||
foreach (GraphicalCheckout checkout in Checkouts)
|
||||
{
|
||||
if (checkout.Open)
|
||||
{
|
||||
result++;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
public int GetAverageWaitingTime()
|
||||
{
|
||||
int cumulatedWaitingTime = 0;
|
||||
int averageWaitingTime = 0;
|
||||
|
||||
int waitingClients = 0;
|
||||
|
||||
foreach (GraphicalClient client in Clients)
|
||||
{
|
||||
if (client.State == Client.ClientState.Waiting)
|
||||
{
|
||||
cumulatedWaitingTime += client.WaitingTime;
|
||||
waitingClients += 1;
|
||||
}
|
||||
}
|
||||
if (Clients.Count == 0 || waitingClients == 0)
|
||||
{
|
||||
averageWaitingTime = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
averageWaitingTime = cumulatedWaitingTime / waitingClients;
|
||||
}
|
||||
|
||||
return averageWaitingTime;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user