Advertisement
Guest User

Examp

a guest
May 21st, 2019
105
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 24.83 KB | None | 0 0
  1. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2. //                                                                                                                  //
  3. //  Project:        Project 4 - Queues                                                                              //
  4. //  File Name:      SimulationForm.cs                                                                               //
  5. //  Description:    Form that handles simulating a given run of supermarket registers in a day.                     //
  6. //  Course:         CSCI 2210-001 - Data Structures                                                                 //
  7. //  Author:         Dillon Buchanan, buchananjd2@etsu.edu, Department of Computing, East Tennessee State University //
  8. //  Created:        Saturday Apr 13 2019                                                                            //
  9. //  Copyright:      Dillon Buchanan 2019                                                                            //
  10. //                                                                                                                  //
  11. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  12.  
  13. using System;
  14. using System.Collections;
  15. using System.Collections.Generic;
  16. using System.ComponentModel;
  17. using System.Data;
  18. using System.Drawing;
  19. using System.Linq;
  20. using System.Text;
  21. using System.Threading;
  22. using System.Threading.Tasks;
  23. using System.Windows.Forms;
  24.  
  25. namespace Project4 {
  26.  
  27.  
  28.     /// <summary>Form that handles simulating a given run of supermarket registers in a day.</summary>
  29.  
  30.     public partial class SimulationForm : Form {
  31.  
  32.         /// <summary>Gets or sets the store.</summary>
  33.         /// <value>The store.</value>
  34.  
  35.         public Supermarket Store {get; set;}
  36.  
  37.         public List<Queue<Customer>> RegisterQueues {get; set;}
  38.  
  39.         /// <summary>Initializes a new instance of the <see cref="SimulationForm"/> class.</summary>
  40.  
  41.         public SimulationForm() {
  42.             InitializeComponent();
  43.         }
  44.  
  45.         #region RegBox placeholder text handling
  46.  
  47.         /// <summary>  Removes default text if the user enters focus on this field.</summary>
  48.         /// <param name="sender">The source of the event.</param>
  49.         /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
  50.  
  51.         private void RegBox_Enter(object sender, EventArgs e) {
  52.  
  53.             if(RegBox.Text == "(Max 15)") { //if default text
  54.                 RegBox.Text = ""; //clear the field
  55.             }
  56.  
  57.         }
  58.  
  59.         /// <summary>  Replaces the default text when the user leaves focus on this field, if the field is left empty or invalid.</summary>
  60.         /// <param name="sender">The source of the event.</param>
  61.         /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
  62.  
  63.         private void RegBox_Leave(object sender, EventArgs e) {
  64.  
  65.             if(RegBox.Text == "" || int.Parse(RegBox.Text) > 15) { //if the field is blank or invalid
  66.                 RegBox.Text = "(Max 15)"; //replace the default text
  67.             }
  68.  
  69.         }
  70.  
  71.  
  72.  
  73.         #endregion
  74.  
  75.         #region CheckBox placeholder text handling
  76.  
  77.         /// <summary>  Removes default text if the user enters focus on this field.</summary>
  78.         /// <param name="sender">The source of the event.</param>
  79.         /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
  80.  
  81.         private void CheckBox_Enter(object sender, EventArgs e) {
  82.  
  83.             if (CheckBox.Text == "(Min 120)") { //if default text
  84.                 CheckBox.Text = ""; //clear the field
  85.             }
  86.  
  87.         }
  88.  
  89.         /// <summary>  Replaces the default text when the user leaves focus on this field, if the field is left empty or invalid.</summary>
  90.         /// <param name="sender">The source of the event.</param>
  91.         /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
  92.        
  93.         private void CheckBox_Leave(object sender, EventArgs e) {
  94.  
  95.             if (CheckBox.Text == "" || int.Parse(CheckBox.Text) < 120) { //if the field is blank or invalid
  96.                 CheckBox.Text = "(Min 120)"; //replace the default text
  97.             }
  98.  
  99.         }
  100.  
  101.         #endregion
  102.  
  103.         #region invalid key press handlers
  104.  
  105.         /// <summary>  Prevents a key press that is not a digit.</summary>
  106.         /// <param name="sender">The source of the event.</param>
  107.         /// <param name="e">The <see cref="KeyPressEventArgs"/> instance containing the event data.</param>
  108.  
  109.         private void CustBox_KeyPress(object sender, KeyPressEventArgs e) {
  110.             string acceptedKeys = "0123456789";
  111.             if (!acceptedKeys.Contains(e.KeyChar) && !char.IsControl(e.KeyChar)) { //if the accepted keys string does not contain the key pressed
  112.                                                                                    //or if the key is a control key (i.e. Backspace)
  113.                 e.Handled = true; //The event is ignored.
  114.             }
  115.         }
  116.  
  117.         /// <summary>  Prevents a key press that is not a digit.</summary>
  118.         /// <param name="sender">The source of the event.</param>
  119.         /// <param name="e">The <see cref="KeyPressEventArgs"/> instance containing the event data.</param>
  120.  
  121.         private void HoursBox_KeyPress(object sender, KeyPressEventArgs e) {
  122.             string acceptedKeys = "0123456789";
  123.             if (!acceptedKeys.Contains(e.KeyChar) && !char.IsControl(e.KeyChar)) { //if the accepted keys string does not contain the key pressed
  124.                                                                                    //or if the key is a control key (i.e. Backspace)
  125.                 e.Handled = true; //The event is ignored.
  126.             }
  127.         }
  128.  
  129.         /// <summary>  Prevents a key press that is not a digit.</summary>
  130.         /// <param name="sender">The source of the event.</param>
  131.         /// <param name="e">The <see cref="KeyPressEventArgs"/> instance containing the event data.</param>
  132.  
  133.         private void RegBox_KeyPress(object sender, KeyPressEventArgs e) {
  134.             string acceptedKeys = "0123456789";
  135.             if (!acceptedKeys.Contains(e.KeyChar) && !char.IsControl(e.KeyChar)) { //if the accepted keys string does not contain the key pressed
  136.                                                                                    //or if the key is a control key (i.e. Backspace)
  137.                 e.Handled = true; //The event is ignored.
  138.             }
  139.         }
  140.  
  141.         /// <summary>  Prevents a key press that is not a digit.</summary>
  142.         /// <param name="sender">The source of the event.</param>
  143.         /// <param name="e">The <see cref="KeyPressEventArgs"/> instance containing the event data.</param>
  144.  
  145.         private void CheckBox_KeyPress(object sender, KeyPressEventArgs e) {
  146.             string acceptedKeys = "0123456789";
  147.             if (!acceptedKeys.Contains(e.KeyChar) && !char.IsControl(e.KeyChar)) { //if the accepted keys string does not contain the key pressed
  148.                                                                                    //or if the key is a control key (i.e. Backspace)
  149.                 e.Handled = true; //The event is ignored.
  150.             }
  151.         }
  152.  
  153.         #endregion
  154.  
  155.         #region Run Button -> simulation handling
  156.  
  157.         /// <summary>  Starts the simulation.</summary>
  158.         /// <param name="sender">The source of the event.</param>
  159.         /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
  160.  
  161.         private async void RunBtn_Click(object sender, EventArgs e) {
  162.  
  163.             //bad input handling
  164.             if(CustBox.Text == "" || HoursBox.Text == "") {
  165.                 MessageBox.Show("Error: Empty field.", "Empty Field Error");
  166.                 return;
  167.             }
  168.             else if (RegBox.Text == "(Max 15)") {
  169.                 MessageBox.Show("Error: Too Many Registers.", "Argument Exception Error");
  170.                 return;
  171.             }
  172.             else if (CheckBox.Text == "(Min 120)") {
  173.                 MessageBox.Show("Error: Average Checkout Time too short.", "Argument Exception Error");
  174.                 return;
  175.             }
  176.             else if(int.Parse(CustBox.Text) < 0 || int.Parse(HoursBox.Text) < 0 || int.Parse(RegBox.Text) < 0) {
  177.                 MessageBox.Show("Error: Negative Value entered.", "Negative Value Error");
  178.                 return;
  179.             }
  180.  
  181.             //disable all registers and clear them (in case this is not the first run)
  182.             Register1.Visible = false;
  183.             Register2.Visible = false;
  184.             Register3.Visible = false;
  185.             Register4.Visible = false;
  186.             Register5.Visible = false;
  187.             Register6.Visible = false;
  188.             Register7.Visible = false;
  189.             Register8.Visible = false;
  190.             Register9.Visible = false;
  191.             Register10.Visible = false;
  192.             Register11.Visible = false;
  193.             Register12.Visible = false;
  194.             Register13.Visible = false;
  195.             Register14.Visible = false;
  196.             Register15.Visible = false;
  197.  
  198.             Register1.Items.Clear();
  199.             Register2.Items.Clear();
  200.             Register3.Items.Clear();
  201.             Register4.Items.Clear();
  202.             Register5.Items.Clear();
  203.             Register6.Items.Clear();
  204.             Register7.Items.Clear();
  205.             Register8.Items.Clear();
  206.             Register9.Items.Clear();
  207.             Register10.Items.Clear();
  208.             Register11.Items.Clear();
  209.             Register12.Items.Clear();
  210.             Register13.Items.Clear();
  211.             Register14.Items.Clear();
  212.             Register15.Items.Clear();
  213.  
  214.             Store = new Supermarket(int.Parse(CustBox.Text), int.Parse(HoursBox.Text), int.Parse(RegBox.Text), int.Parse(CheckBox.Text));
  215.  
  216.             //enable registers
  217.             switch (Store.Registers) {
  218.                 case 15:
  219.                     Register15.Visible = true;
  220.                     goto case 14;
  221.                 case 14:
  222.                     Register14.Visible = true;
  223.                     goto case 13;
  224.                 case 13:
  225.                     Register13.Visible = true;
  226.                     goto case 12;
  227.                 case 12:
  228.                     Register12.Visible = true;
  229.                     goto case 11;
  230.                 case 11:
  231.                     Register11.Visible = true;
  232.                     goto case 10;
  233.                 case 10:
  234.                     Register10.Visible = true;
  235.                     goto case 9;
  236.                 case 9:
  237.                     Register9.Visible = true;
  238.                     goto case 8;
  239.                 case 8:
  240.                     Register8.Visible = true;
  241.                     goto case 7;
  242.                 case 7:
  243.                     Register7.Visible = true;
  244.                     goto case 6;
  245.                 case 6:
  246.                     Register6.Visible = true;
  247.                     goto case 5;
  248.                 case 5:
  249.                     Register5.Visible = true;
  250.                     goto case 4;
  251.                 case 4:
  252.                     Register4.Visible = true;
  253.                     goto case 3;
  254.                 case 3:
  255.                     Register3.Visible = true;
  256.                     goto case 2;
  257.                 case 2:
  258.                     Register2.Visible = true;
  259.                     goto case 1;
  260.                 case 1:
  261.                     Register1.Visible = true;
  262.                     break;
  263.             }
  264.  
  265.             //add Queues to the list of registers for each register enabled.
  266.             RegisterQueues = new List<Queue<Customer>>();
  267.             for(int i = 0; i < Store.Registers; i++) {
  268.                 RegisterQueues.Add(new Queue<Customer>());
  269.             }
  270.  
  271.             //dequeue the events one by one and display them to the GUI while keeping track of important values
  272.  
  273.             int Longest = 0;
  274.             int Arrived = 0;
  275.             int Departed = 0;
  276.             List<int> serveTimes = new List<int>();
  277.             int Average = 0;
  278.             int Minimum = 0;
  279.             int Maximum = 0;
  280.            
  281.  
  282.             for(int i = Store.Events.Count; i > 0; i--) {
  283.                 Customer temp = Store.Customers[Store.Events.Peek().ID - 1]; //gets the customer related to the event from the List
  284.                 if (!Store.Events.Peek().Leave) { //if this is an enter event
  285.                     //we need to find the smallest line.
  286.                     List<int> regSizes = new List<int>();
  287.                     switch (Store.Registers) {
  288.                         case 15:
  289.                             regSizes.Insert(0, Register15.Items.Count);
  290.                             goto case 14;
  291.                         case 14:
  292.                             regSizes.Insert(0, Register14.Items.Count);
  293.                             goto case 13;
  294.                         case 13:
  295.                             regSizes.Insert(0, Register13.Items.Count);
  296.                             goto case 12;
  297.                         case 12:
  298.                             regSizes.Insert(0, Register12.Items.Count);
  299.                             goto case 11;
  300.                         case 11:
  301.                             regSizes.Insert(0, Register11.Items.Count);
  302.                             goto case 10;
  303.                         case 10:
  304.                             regSizes.Insert(0, Register10.Items.Count);
  305.                             goto case 9;
  306.                         case 9:
  307.                             regSizes.Insert(0, Register9.Items.Count);
  308.                             goto case 8;
  309.                         case 8:
  310.                             regSizes.Insert(0, Register8.Items.Count);
  311.                             goto case 7;
  312.                         case 7:
  313.                             regSizes.Insert(0, Register7.Items.Count);
  314.                             goto case 6;
  315.                         case 6:
  316.                             regSizes.Insert(0, Register6.Items.Count);
  317.                             goto case 5;
  318.                         case 5:
  319.                             regSizes.Insert(0, Register5.Items.Count);
  320.                             goto case 4;
  321.                         case 4:
  322.                             regSizes.Insert(0, Register4.Items.Count);
  323.                             goto case 3;
  324.                         case 3:
  325.                             regSizes.Insert(0, Register3.Items.Count);
  326.                             goto case 2;
  327.                         case 2:
  328.                             regSizes.Insert(0, Register2.Items.Count);
  329.                             goto case 1;
  330.                         case 1:
  331.                             regSizes.Insert(0, Register1.Items.Count);
  332.                             break;
  333.                     }
  334.                     int smallestLine = Min(regSizes, regSizes.Count); //the Register Index with the smallest line
  335.  
  336.                     //now we need to enter the customer into the smallest line
  337.                     RegisterQueues[smallestLine].Enqueue(temp);
  338.                     regSizes[smallestLine]++; //increment the size of the line we just added to
  339.  
  340.                     //find the longest line at the moment (this is one of the data points we are tracking
  341.                     int currentLQueue = regSizes[Max(regSizes, regSizes.Count)];
  342.                     if(currentLQueue > Longest) { //only change the tracked data point if a longer queue than already tracked is found
  343.                         Longest = currentLQueue;
  344.                         LQueue.Text = Longest.ToString();
  345.                     }
  346.  
  347.                     //and now we need to add the customer to the GUI element representing this
  348.                     switch (smallestLine + 1) {
  349.                         case 15:
  350.                             Register15.Items.Add(temp.ID);
  351.                             break;
  352.                         case 14:
  353.                             Register14.Items.Add(temp.ID);
  354.                             break;
  355.                         case 13:
  356.                             Register13.Items.Add(temp.ID);
  357.                             break;
  358.                         case 12:
  359.                             Register12.Items.Add(temp.ID);
  360.                             break;
  361.                         case 11:
  362.                             Register11.Items.Add(temp.ID);
  363.                             break;
  364.                         case 10:
  365.                             Register10.Items.Add(temp.ID);
  366.                             break;
  367.                         case 9:
  368.                             Register9.Items.Add(temp.ID);
  369.                             break;
  370.                         case 8:
  371.                             Register8.Items.Add(temp.ID);
  372.                             break;
  373.                         case 7:
  374.                             Register7.Items.Add(temp.ID);
  375.                             break;
  376.                         case 6:
  377.                             Register6.Items.Add(temp.ID);
  378.                             break;
  379.                         case 5:
  380.                             Register5.Items.Add(temp.ID);
  381.                             break;
  382.                         case 4:
  383.                             Register4.Items.Add(temp.ID);
  384.                             break;
  385.                         case 3:
  386.                             Register3.Items.Add(temp.ID);
  387.                             break;
  388.                         case 2:
  389.                             Register2.Items.Add(temp.ID);
  390.                             break;
  391.                         case 1:
  392.                             Register1.Items.Add(temp.ID);
  393.                             break;
  394.                     }
  395.  
  396.                     //now, enqueue a leave event for the customer.
  397.                     //their service time does not start until the customer in front of them leaves.
  398.                     //so, we can only enter a leave event now in this part of the logic if the customer just entered an empty queue
  399.                     //if we don't do it here, we will do it after the customer in front of this one's leave event
  400.  
  401.                     if(RegisterQueues[smallestLine].Count == 1) { //if the register queue only contains this customer
  402.                         Event Leave = new Event(temp.ID, true, temp.RegArrival + temp.RegDuration);
  403.                         Store.Events.Enqueue(Leave);
  404.                         i++; //if we add an event we need to increment i so that the loop continues
  405.                     }
  406.  
  407.                     //finally, increment CArrived and dequeue the event
  408.                     Store.Events.Dequeue();
  409.                     Arrived++;
  410.                     CArrived.Text = Arrived.ToString();
  411.                 }
  412.                 else { //if this is a leave event
  413.                     //first, we need to find out which line the customer is in.
  414.                     bool found = false;
  415.                     int count = 0;
  416.                     int queueIndex = -1;
  417.                     while(!found) {
  418.                         if(RegisterQueues[count].Count == 0) {
  419.                             found = false;
  420.                         }
  421.                         else if(RegisterQueues[count].Peek().ID == temp.ID) {
  422.                             queueIndex = count;
  423.                             found = true;
  424.                         }
  425.                         count++;
  426.                     }
  427.  
  428.                     //second, we need to add the Service Time of this customer to serveTimes
  429.                     serveTimes.Add(temp.RegDuration);
  430.  
  431.                     //third, we need to remove this customer from RegisterQueues
  432.                     RegisterQueues[queueIndex].Dequeue();
  433.  
  434.                     //next, we need to add the leave event for the next customer in line, if there is one.
  435.                     if (RegisterQueues[queueIndex].Count != 0) {
  436.                         Customer next = RegisterQueues[queueIndex].Peek();
  437.                         //OccurTime calculated by taking the time of this leave event and adding the next customer's RegDuration to it.
  438.                         Event Leave = new Event(next.ID, true, Store.Events.Peek().OccurTime + next.RegDuration);
  439.                         Store.Events.Enqueue(Leave);
  440.                         i++; //if we add an event we need to increment i so that the loop continues
  441.                     }
  442.  
  443.                     //now we need to update the UI to reflect these changes
  444.                     switch (queueIndex + 1) {
  445.                         case 15:
  446.                             Register15.Items.RemoveAt(0);
  447.                             break;
  448.                         case 14:
  449.                             Register14.Items.RemoveAt(0);
  450.                             break;
  451.                         case 13:
  452.                             Register13.Items.RemoveAt(0);
  453.                             break;
  454.                         case 12:
  455.                             Register12.Items.RemoveAt(0);
  456.                             break;
  457.                         case 11:
  458.                             Register11.Items.RemoveAt(0);
  459.                             break;
  460.                         case 10:
  461.                             Register10.Items.RemoveAt(0);
  462.                             break;
  463.                         case 9:
  464.                             Register9.Items.RemoveAt(0);
  465.                             break;
  466.                         case 8:
  467.                             Register8.Items.RemoveAt(0);
  468.                             break;
  469.                         case 7:
  470.                             Register7.Items.RemoveAt(0);
  471.                             break;
  472.                         case 6:
  473.                             Register6.Items.RemoveAt(0);
  474.                             break;
  475.                         case 5:
  476.                             Register5.Items.RemoveAt(0);
  477.                             break;
  478.                         case 4:
  479.                             Register4.Items.RemoveAt(0);
  480.                             break;
  481.                         case 3:
  482.                             Register3.Items.RemoveAt(0);
  483.                             break;
  484.                         case 2:
  485.                             Register2.Items.RemoveAt(0);
  486.                             break;
  487.                         case 1:
  488.                             Register1.Items.RemoveAt(0);
  489.                             break;
  490.                     }
  491.  
  492.                     //update the average/min/max service time values
  493.                     int sum = 0;
  494.                     foreach (int time in serveTimes) {
  495.                         sum += time;
  496.                     }
  497.                     Average = sum / serveTimes.Count;
  498.                     AvgTime.Text = Average.ToString();
  499.                     AvgTime.Text += " Seconds";
  500.  
  501.                     Minimum = serveTimes[Min(serveTimes, serveTimes.Count)];
  502.                     Maximum = serveTimes[Max(serveTimes, serveTimes.Count)];
  503.  
  504.                     MinTime.Text = Minimum.ToString();
  505.                     MinTime.Text += " Seconds";
  506.                     MaxTime.Text = Maximum.ToString();
  507.                     MaxTime.Text += " Seconds";
  508.  
  509.                     //finally, increment CDeparted and dequeue the event
  510.                     Store.Events.Dequeue();
  511.                     Departed++;
  512.                     CDeparted.Text = Departed.ToString();
  513.                 }
  514.  
  515.                 //add a small delay so that the simulation can be seen
  516.                 await Task.Delay(25);
  517.             }
  518.  
  519.         }
  520.  
  521.         #endregion
  522.  
  523.         #region simulation handling helper methods
  524.  
  525.         /// <summary>Determines the minimum of the parameters.</summary>
  526.         /// <param name="list">The list.</param>
  527.         /// <param name="n">The size of the list.</param>
  528.         /// <returns>the index of the minimum in the list.</returns>
  529.  
  530.         private static int Min(List<int> list, int n) {
  531.             int min = 0;
  532.  
  533.             for (int i = 0; i < n; i++) {
  534.                 if (list[min] > list[i]) {
  535.                     min = i;
  536.                 }
  537.             }
  538.             return min;
  539.         }
  540.  
  541.         /// <summary>Determines the maximum of the parameters.</summary>
  542.         /// <param name="list">The list.</param>
  543.         /// <param name="n">The size of the list.</param>
  544.         /// <returns>the index of the maximum in the list.</returns>
  545.  
  546.         private static int Max(List<int> list, int n) {
  547.             int max = 0;
  548.  
  549.             for (int i = 0; i < n; i++) {
  550.                 if (list[max] < list[i]) {
  551.                     max = i;
  552.                 }
  553.             }
  554.             return max;
  555.         }
  556.  
  557.         #endregion
  558.  
  559.         /// <summary>  Exits the Application</summary>
  560.         /// <param name="sender">The source of the event.</param>
  561.         /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
  562.  
  563.         private void ExitBtn_Click(object sender, EventArgs e) {
  564.             Application.Exit();
  565.         }
  566.     }
  567.  
  568. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement