A simple demonstration of OOP styles.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ParkingLot.cs 7.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Runtime.Remoting.Channels;
  5. using System.Timers;
  6. using ParkingLot.Vehicles;
  7. namespace ParkingLot
  8. {
  9. public class ParkingLot
  10. {
  11. private const double _BaseRate = 1.0; // The rate per RateTime
  12. private const double _FlatRate = 40.0; // The flat rate applied for times over MaxTime
  13. private const int _RateTime = 15; // The time in minutes for the base rate
  14. private const int _MinTime = 60; // The minimum time for being charged
  15. private const int _MaxTime = 480; // The maximum time for the rate to be applied
  16. public event Action<double> VehicleLeftEvent;
  17. private List<Level> levels;
  18. public List<Level> Levels
  19. {
  20. get { return levels; }
  21. set { levels = value; }
  22. }
  23. public ParkingLot()
  24. {
  25. SetDefaults();
  26. }
  27. public void SetDefaults()
  28. {
  29. Levels = new List<Level>();
  30. }
  31. public static ParkingLot CreateParkingLot(int levels, int maxRows, int maxSpaces)
  32. {
  33. ParkingLot newParkingLot = new ParkingLot();
  34. List<Level> newLevels = new List<Level>();
  35. Random rand = new Random();
  36. for (int l = 0; l < levels; l++)
  37. {
  38. Level newLevel = new Level();
  39. int randRows = rand.Next(1, maxRows);
  40. List<Row> newRows = new List<Row>();
  41. for (int r = 0; r < randRows; r++)
  42. {
  43. Row newRow = new Row();
  44. int randSpaces = rand.Next(1, maxSpaces);
  45. List<Space> newSpaces = new List<Space>();
  46. for (int s = 0; s < randSpaces; s++)
  47. {
  48. Space newSpace = new Space();
  49. int randType = rand.Next(0, 10);
  50. if (randType < 3)
  51. {
  52. newSpace.SpaceType = SpaceType.Motorcycle;
  53. }
  54. else if (randType >= 3 && randType < 6)
  55. {
  56. newSpace.SpaceType = SpaceType.Compact;
  57. }
  58. else if (randType >= 6)
  59. {
  60. newSpace.SpaceType = SpaceType.Large;
  61. }
  62. newSpaces.Add(newSpace);
  63. }
  64. newRow.Spaces = newSpaces;
  65. newRows.Add(newRow);
  66. }
  67. newLevel.Rows = newRows;
  68. newLevels.Add(newLevel);
  69. }
  70. newParkingLot.Levels = newLevels;
  71. return newParkingLot;
  72. }
  73. public bool AddVehicle(Vehicle vehicle)
  74. {
  75. bool vehicleAdded = false;
  76. int levelID = 0;
  77. foreach (Level level in Levels)
  78. {
  79. int rowID = 0;
  80. foreach (Row row in level.Rows)
  81. {
  82. int numOpen = 0;
  83. for (int i = 0; i < row.Spaces.Count; i++)
  84. {
  85. Space space = row.Spaces[i];
  86. if (space.CurrentVehicle == null &&
  87. ((vehicle.VehicleType == VehicleType.Motorcycle && (space.SpaceType == SpaceType.Motorcycle || space.SpaceType == SpaceType.Compact))
  88. || (vehicle.VehicleType == VehicleType.Car && (space.SpaceType == SpaceType.Compact || space.SpaceType == SpaceType.Large))
  89. || (vehicle.VehicleType == VehicleType.Bus && space.SpaceType == SpaceType.Large)))
  90. {
  91. numOpen++;
  92. if (numOpen == vehicle.NumSpaces)
  93. {
  94. vehicle.TimeArrived = DateTime.Now;
  95. vehicle.LeaveTimer.Enabled = true;
  96. for (int x = 0; x < vehicle.NumSpaces; x++)
  97. {
  98. vehicle.Level = levelID;
  99. vehicle.Row = rowID;
  100. vehicle.Spaces.Add(i - x);
  101. row.Spaces[i - x].CurrentVehicle = vehicle;
  102. }
  103. vehicle.LeaveTimer.Elapsed += (sender, e) => VehicleLeaveHandler(sender, e, vehicle.Level, vehicle.Row, vehicle.Spaces);
  104. vehicleAdded = true;
  105. break;
  106. }
  107. }
  108. else
  109. {
  110. numOpen = 0;
  111. }
  112. }
  113. rowID++;
  114. if (vehicleAdded)
  115. break;
  116. }
  117. levelID++;
  118. if (vehicleAdded)
  119. break;
  120. }
  121. return vehicleAdded;
  122. }
  123. private void VehicleLeaveHandler(object sender, EventArgs e, int level, int row, List<int> spaces)
  124. {
  125. double price = RemoveVehicle(level, row, spaces);
  126. var vehicleLeft = VehicleLeftEvent;
  127. if (vehicleLeft != null)
  128. {
  129. vehicleLeft(price);
  130. }
  131. }
  132. public double RemoveVehicle(int level, int row, List<int> spaces)
  133. {
  134. double price = 0;
  135. if (Levels.Count > level)
  136. {
  137. Level foundLevel = Levels[level];
  138. if (foundLevel.Rows.Count > row)
  139. {
  140. Row foundRow = foundLevel.Rows[row];
  141. if (foundRow.Spaces.Count > spaces.Max())
  142. {
  143. bool vehicleFound = false;
  144. DateTime foundTime = DateTime.Now;
  145. foreach (int space in spaces)
  146. {
  147. Space foundSpace = foundRow.Spaces[space];
  148. if (foundSpace.CurrentVehicle != null)
  149. {
  150. vehicleFound = true;
  151. foundTime = foundSpace.CurrentVehicle.TimeArrived;
  152. foundSpace.CurrentVehicle.LeaveTimer.Enabled = false;
  153. foundSpace.CurrentVehicle = null;
  154. }
  155. }
  156. if (vehicleFound)
  157. {
  158. TimeSpan timeSpan = DateTime.Now.Subtract(foundTime);
  159. double numMinutes = timeSpan.TotalSeconds; // For testing purposes, use seconds as our 'minutes'
  160. if (numMinutes <= _MinTime)
  161. {
  162. price = _BaseRate*(_MinTime/_RateTime);
  163. }
  164. else if (numMinutes > _MaxTime)
  165. {
  166. price = _FlatRate;
  167. }
  168. else
  169. {
  170. price = _BaseRate*(numMinutes/_RateTime);
  171. }
  172. }
  173. }
  174. }
  175. }
  176. return price;
  177. }
  178. }
  179. }