239 lines
9.0 KiB
C#
239 lines
9.0 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Drawing;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace Caisses
|
|
{
|
|
internal class GraphicalStore
|
|
{
|
|
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 };
|
|
public const int CROSSOVER_TIME = 10;
|
|
|
|
private List<GraphicalCheckout> _checkouts;
|
|
private List<GraphicalClient> _clients;
|
|
private int _timeOfTheDayInMinuts;
|
|
private Random rnd;
|
|
|
|
/// Stats
|
|
|
|
private int _AverageWaitingTime;
|
|
private int _OpenCheckoutCount;
|
|
private int _PlacesLeftCount;
|
|
private List<GraphicalCheckout> _NotFullCheckouts;
|
|
private List<GraphicalClient> _WaitingClients;
|
|
|
|
public int AverageWaitingTime { get => _AverageWaitingTime; set => _AverageWaitingTime = value; }
|
|
public int OpenCheckoutCount { get => _OpenCheckoutCount; set => _OpenCheckoutCount = value; }
|
|
public int TotalPlacesLeftCount { get => _PlacesLeftCount; set => _PlacesLeftCount = value; }
|
|
internal List<GraphicalCheckout> NotFullCheckouts { get => _NotFullCheckouts; set => _NotFullCheckouts = value; }
|
|
public List<GraphicalClient> WaitingClients { get => _WaitingClients; set => _WaitingClients = value; }
|
|
|
|
/// Stats
|
|
|
|
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 int TimeOfTheDayInHours
|
|
{
|
|
get { return _timeOfTheDayInMinuts / 60; }
|
|
}
|
|
|
|
public GraphicalStore(int startingHour, int checkoutNumber, Size checkoutsRoom)
|
|
{
|
|
TimeOfTheDayInMinuts = startingHour * 60;
|
|
Clients = new List<GraphicalClient>();
|
|
Checkouts = new List<GraphicalCheckout>();
|
|
rnd = new Random();
|
|
|
|
FillStore(ATTENDANCE[TimeOfTheDayInHours]);
|
|
populateCheckouts(checkoutsRoom,checkoutNumber);
|
|
Tick();
|
|
}
|
|
public void populateCheckouts(Size checkoutRoom,int checkoutNumber)
|
|
{
|
|
int checkoutWidth = checkoutRoom.Width / checkoutNumber + 1;
|
|
for (int i = 0; i < checkoutNumber; i++)
|
|
{
|
|
Point position = new Point(i * checkoutWidth + checkoutWidth / checkoutNumber, 0);
|
|
Checkouts.Add(new GraphicalCheckout());
|
|
}
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
int cumulatedWaitingTime = 0;
|
|
int waitingClients = 0;
|
|
AverageWaitingTime = 0;
|
|
WaitingClients = new List<GraphicalClient>();
|
|
|
|
if (NotFullCheckouts == null)
|
|
NotFullCheckouts = new List<GraphicalCheckout>();
|
|
|
|
//Clients that will leave the store
|
|
List<GraphicalClient> clientsToRemove = new List<GraphicalClient>();
|
|
|
|
foreach (GraphicalClient client in Clients)
|
|
{
|
|
//Tick
|
|
client.Tick();
|
|
|
|
// Calculating average waiting time
|
|
if (Clients.Count == 0 || waitingClients == 0)
|
|
{
|
|
AverageWaitingTime = 0;
|
|
}
|
|
else
|
|
{
|
|
AverageWaitingTime = cumulatedWaitingTime / waitingClients;
|
|
}
|
|
|
|
//Waiting time incrementation
|
|
if (Clients.Count != 0 && client.State == Client.ClientState.Waiting)
|
|
{
|
|
cumulatedWaitingTime += client.WaitingTime;
|
|
waitingClients += 1;
|
|
WaitingClients.Add(client);
|
|
|
|
//Checkout process
|
|
if (TotalPlacesLeftCount > 0 && NotFullCheckouts.Count > 0)
|
|
{
|
|
//Now we select a random one to put our waiting client
|
|
int index = 0;
|
|
int count = NotFullCheckouts.Count;
|
|
if (count > 0)
|
|
{
|
|
index = rnd.Next(0, count - 1);
|
|
}
|
|
else
|
|
{
|
|
index = 0;
|
|
}
|
|
if (NotFullCheckouts[index].Clients.Count < Checkout.MAX_CAPACITY)
|
|
{
|
|
//We need to check that because a client could have been already added and so the checkout could not have any places left even tho she is listed as not full
|
|
NotFullCheckouts[index].Clients.Add(client);
|
|
//Clients.Remove(client);
|
|
clientsToRemove.Add(client);
|
|
client.State = Client.ClientState.Inline;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
foreach (GraphicalClient client in clientsToRemove)
|
|
{
|
|
Clients.Remove(client);
|
|
}
|
|
|
|
OpenCheckoutCount = 0;
|
|
TotalPlacesLeftCount = 0;
|
|
NotFullCheckouts = new List<GraphicalCheckout>();
|
|
|
|
foreach (GraphicalCheckout checkout in Checkouts)
|
|
{
|
|
//Tick
|
|
checkout.Tick(this);
|
|
|
|
if (checkout.Open)
|
|
{
|
|
//Calculate amount of open Checkouts
|
|
OpenCheckoutCount++;
|
|
//Calculate amount of places left
|
|
int CheckoutPlacesLeft = Checkout.MAX_CAPACITY - checkout.Clients.Count();
|
|
TotalPlacesLeftCount += CheckoutPlacesLeft;
|
|
//Collecting every non full checkout
|
|
if (CheckoutPlacesLeft > 0)
|
|
{
|
|
NotFullCheckouts.Add(checkout);
|
|
}
|
|
|
|
//Checkout behaviour
|
|
if (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(Size shelvesRoom,Size waitRoom,Size checkoutsRoom)
|
|
{
|
|
Bitmap shelvesImage = new Bitmap(shelvesRoom.Width,shelvesRoom.Height);
|
|
Bitmap waitingRoomImage = new Bitmap(waitRoom.Width, waitRoom.Height);
|
|
Bitmap checkoutsImage= new Bitmap(checkoutsRoom.Width,checkoutsRoom.Height);
|
|
foreach (GraphicalClient client in Clients)
|
|
{
|
|
client.Draw(shelvesImage, waitingRoomImage);
|
|
}
|
|
|
|
for (int i = 0; i < Checkouts.Count; i++)
|
|
{
|
|
Checkouts[i].Draw(checkoutsImage, Checkouts.Count,i);
|
|
foreach (GraphicalClient client in Checkouts[i].Clients)
|
|
{
|
|
client.Draw(shelvesImage, waitingRoomImage);
|
|
}
|
|
}
|
|
/*
|
|
foreach (GraphicalCheckout checkout in Checkouts)
|
|
{
|
|
checkout.Draw(checkoutsImage,Checkouts.Count, );
|
|
foreach (GraphicalClient client in checkout.Clients)
|
|
{
|
|
client.Draw(shelvesImage,waitingRoomImage);
|
|
}
|
|
}
|
|
*/
|
|
return new List<Bitmap> { shelvesImage, waitingRoomImage, checkoutsImage};
|
|
}
|
|
public virtual void FillStore(int amountOfNewClients)
|
|
{
|
|
for (int i = 0; i < amountOfNewClients; i++)
|
|
{
|
|
Clients.Add(new GraphicalClient(new Point(0, 0), rnd));
|
|
}
|
|
}
|
|
public int GetEmptyCheckoutCount()
|
|
{
|
|
int result = 0;
|
|
foreach (GraphicalCheckout checkout in Checkouts)
|
|
{
|
|
if (checkout.Open && checkout.Clients.Count == 0)
|
|
{
|
|
result += 1;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
}
|
|
|
|
}
|