Otptimised checkout behaviours

This commit is contained in:
2023-01-11 15:25:19 +01:00
parent 5becf33df0
commit 3c18e7e360
4 changed files with 72 additions and 62 deletions
+3 -3
View File
@@ -21,13 +21,13 @@ namespace Caisses
Clients = new List<Client>(); Clients = new List<Client>();
Open = false; Open = false;
} }
public void Tick(int averageWaitingTime, int CrossoverTime, int openedCheckoutsCount) public void Tick(GraphicalStore store)
{ {
if (!Open && averageWaitingTime > CrossoverTime || openedCheckoutsCount == 0) if (!Open && store.AverageWaitingTime > GraphicalStore.CROSSOVER_TIME && store.GetEmptyCheckoutCount() == 0 || store.OpenCheckoutCount == 0)
{ {
Open = true; Open = true;
} }
if (Open && averageWaitingTime < 1 && Clients.Count == 0 && openedCheckoutsCount > 1) if (Open && store.AverageWaitingTime < 1 && Clients.Count == 0 && store.OpenCheckoutCount > 0)
{ {
Open = false; Open = false;
} }
+1 -1
View File
@@ -17,7 +17,7 @@ namespace Caisses
{ {
InitializeComponent(); InitializeComponent();
DoubleBuffered = true; DoubleBuffered = true;
store = new GraphicalStore(10,12,pbxRayons.Size,pbxCaisses.Size); store = new GraphicalStore(20,12,pbxRayons.Size,pbxCaisses.Size);
} }
private void btnStartStop_Click(object sender, EventArgs e) private void btnStartStop_Click(object sender, EventArgs e)
+1 -1
View File
@@ -31,7 +31,7 @@ namespace Caisses
//Position = new Point(Random.Next(0, 100), Random.Next(0, 100)); //Position = new Point(Random.Next(0, 100), Random.Next(0, 100));
Speed = new PointF(NextFloat(MIN_CLIENT_SPEED, MAX_CLIENT_SPEED), NextFloat(MIN_CLIENT_SPEED, MAX_CLIENT_SPEED)); Speed = new PointF(NextFloat(MIN_CLIENT_SPEED, MAX_CLIENT_SPEED), NextFloat(MIN_CLIENT_SPEED, MAX_CLIENT_SPEED));
Color = Color.FromArgb(ShoppingTime * 2, 0, 0); Color = Color.FromArgb(ShoppingTime * 2, 0, 0);
int clientWidth = Random.Next(20, 30); int clientWidth = Random.Next(25, 30);
Size = new Size(clientWidth, clientWidth); Size = new Size(clientWidth, clientWidth);
} }
static float NextFloat(float min, float max) static float NextFloat(float min, float max)
+67 -57
View File
@@ -9,6 +9,9 @@ namespace Caisses
{ {
internal class GraphicalStore 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<GraphicalCheckout> _checkouts;
private List<GraphicalClient> _clients; private List<GraphicalClient> _clients;
private int _timeOfTheDayInMinuts; private int _timeOfTheDayInMinuts;
@@ -32,9 +35,6 @@ namespace Caisses
/// Stats /// Stats
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 int TimeOfTheDayInMinuts { get => _timeOfTheDayInMinuts; set => _timeOfTheDayInMinuts = value; }
public List<GraphicalClient> Clients { get => _clients; set => _clients = value; } public List<GraphicalClient> Clients { get => _clients; set => _clients = value; }
internal List<GraphicalCheckout> Checkouts { get => _checkouts; set => _checkouts = value; } internal List<GraphicalCheckout> Checkouts { get => _checkouts; set => _checkouts = value; }
@@ -46,13 +46,13 @@ namespace Caisses
get { return _timeOfTheDayInMinuts / 60; } get { return _timeOfTheDayInMinuts / 60; }
} }
public GraphicalStore(int startingHour,int checkoutNumber, Size shelvesCornerSize,Size checkoutCornerSize) public GraphicalStore(int startingHour, int checkoutNumber, Size shelvesCornerSize, Size checkoutCornerSize)
{ {
TimeOfTheDayInMinuts = startingHour * 60; TimeOfTheDayInMinuts = startingHour * 60;
Clients = new List<GraphicalClient>(); Clients = new List<GraphicalClient>();
Checkouts = new List<GraphicalCheckout>(); Checkouts = new List<GraphicalCheckout>();
CheckoutCorner = new Bitmap(checkoutCornerSize.Width,checkoutCornerSize.Height); CheckoutCorner = new Bitmap(checkoutCornerSize.Width, checkoutCornerSize.Height);
ShelvesCorner = new Bitmap(shelvesCornerSize.Width,shelvesCornerSize.Height); ShelvesCorner = new Bitmap(shelvesCornerSize.Width, shelvesCornerSize.Height);
rnd = new Random(); rnd = new Random();
FillStore(ATTENDANCE[TimeOfTheDayInHours]); FillStore(ATTENDANCE[TimeOfTheDayInHours]);
@@ -81,36 +81,70 @@ namespace Caisses
//Its a new Hour so we can send the new clients //Its a new Hour so we can send the new clients
int amountOfNewCLients = ATTENDANCE[TimeOfTheDayInHours]; int amountOfNewCLients = ATTENDANCE[TimeOfTheDayInHours];
FillStore(amountOfNewCLients); FillStore(amountOfNewCLients);
} }
int cumulatedWaitingTime = 0; int cumulatedWaitingTime = 0;
int waitingClients = 0; int waitingClients = 0;
AverageWaitingTime = 1; AverageWaitingTime = 0;
WaitingClients = new List<GraphicalClient>(); 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) foreach (GraphicalClient client in Clients)
{ {
//Tick //Tick
client.Tick(); client.Tick();
// Calculating average waiting time
if (Clients.Count == 0 || waitingClients == 0)
{
AverageWaitingTime = 0;
}
else
{
AverageWaitingTime = cumulatedWaitingTime / waitingClients;
}
//Waiting time incrementation //Waiting time incrementation
if (Clients.Count != 0 && client.State == Client.ClientState.Waiting) if (Clients.Count != 0 && client.State == Client.ClientState.Waiting)
{ {
cumulatedWaitingTime += client.WaitingTime; cumulatedWaitingTime += client.WaitingTime;
waitingClients += 1; waitingClients += 1;
WaitingClients.Add(client); 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;
}
}
} }
} }
// Calculating average waiting time foreach (GraphicalClient client in clientsToRemove)
if (Clients.Count == 0 || waitingClients == 0)
{ {
AverageWaitingTime = 0; Clients.Remove(client);
}
else
{
AverageWaitingTime = cumulatedWaitingTime / waitingClients;
} }
OpenCheckoutCount = 0; OpenCheckoutCount = 0;
@@ -120,7 +154,7 @@ namespace Caisses
foreach (GraphicalCheckout checkout in Checkouts) foreach (GraphicalCheckout checkout in Checkouts)
{ {
//Tick //Tick
checkout.Tick(AverageWaitingTime,CROSSOVER_TIME,OpenCheckoutCount); checkout.Tick(this);
if (checkout.Open) if (checkout.Open)
{ {
@@ -137,43 +171,6 @@ namespace Caisses
} }
} }
//Processing the checkout mechanism
List<GraphicalClient> clientsToRemove = new List<GraphicalClient>();
foreach (GraphicalClient client in Clients)
{
if (client.State == Client.ClientState.Waiting)
{
if (TotalPlacesLeftCount > 0)
{
if (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, NotFullCheckouts.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);
}
foreach (GraphicalCheckout checkout in Checkouts) foreach (GraphicalCheckout checkout in Checkouts)
{ {
if (checkout.Open && checkout.Clients.Count > 0) if (checkout.Open && checkout.Clients.Count > 0)
@@ -197,8 +194,8 @@ namespace Caisses
} }
public List<Bitmap> Draw() public List<Bitmap> Draw()
{ {
ShelvesCorner = new Bitmap(ShelvesCorner.Width,ShelvesCorner.Height); ShelvesCorner = new Bitmap(ShelvesCorner.Width, ShelvesCorner.Height);
CheckoutCorner = new Bitmap(CheckoutCorner.Width,CheckoutCorner.Height); CheckoutCorner = new Bitmap(CheckoutCorner.Width, CheckoutCorner.Height);
foreach (GraphicalClient client in Clients) foreach (GraphicalClient client in Clients)
{ {
client.Draw(ShelvesCorner); client.Draw(ShelvesCorner);
@@ -219,8 +216,21 @@ namespace Caisses
{ {
for (int i = 0; i < amountOfNewClients; i++) for (int i = 0; i < amountOfNewClients; i++)
{ {
Clients.Add(new GraphicalClient(new Point(0,0),rnd)); 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;
}
} }
} }