Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

AgAgent.cs 6.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. using System;
  2. using System.Linq;
  3. using System.Threading;
  4. using Microsoft.Extensions.DependencyInjection;
  5. using Microsoft.Extensions.Options;
  6. using uqac_ia_aspirobot.Agent.FakeEnv;
  7. using uqac_ia_aspirobot.Agent.FakeEnv.Effectors;
  8. using uqac_ia_aspirobot.Agent.FakeEnv.Sensors;
  9. using uqac_ia_aspirobot.Agent.Interfaces.Effectors;
  10. using uqac_ia_aspirobot.Agent.Interfaces.Sensors;
  11. using uqac_ia_aspirobot.Common;
  12. using uqac_ia_aspirobot.Extensions;
  13. using uqac_ia_aspirobot.Interfaces;
  14. using uqac_ia_aspirobot.UI;
  15. namespace uqac_ia_aspirobot.Agent
  16. {
  17. public class AgAgent
  18. {
  19. private readonly IAgDustSensor _agDustSensor;
  20. private readonly IAgBatterySensor _agBatterySensor;
  21. private readonly IAgPickedSensor _agPickedSensor;
  22. private readonly IAgVaccumSensor _agVaccumSensor;
  23. private readonly IAgEngineEffector _engineEffector;
  24. private readonly IAgVaccumEffector _vaccumEffector;
  25. private readonly IEnvironment _environment;
  26. private readonly AgConfig _options;
  27. private readonly AgState _state;
  28. private readonly IUi _ui;
  29. private static Thread _thread;
  30. public static void Start(AgConfig agConfig, ArConfig arConfig)
  31. {
  32. var agServices = new ServiceCollection();
  33. agServices.AddOptions();
  34. agServices.AddSingleton<AgState>();
  35. agServices.AddSingleton<AgAgent>();
  36. agServices.AddSingleton<ArClient>();
  37. agServices.AddSingleton<IAgDustSensor, AgDustSensor>();
  38. agServices.AddSingleton<IAgBatterySensor, AgBatterySensor>();
  39. agServices.AddSingleton<IAgVaccumSensor, AgVaccumSensor>();
  40. agServices.AddSingleton<IAgPickedSensor, AgPickedSensor>();
  41. agServices.AddSingleton<IAgVaccumEffector, AgVaccumEffector>();
  42. agServices.AddSingleton<IAgEngineEffector, AgEngineEffector>();
  43. agServices.AddSingleton<IUi, UiConsole>();
  44. agServices.AddSingleton<IEnvironment, AgEnvironment>();
  45. agServices.AddTransient<IRoom, AgRoom>();
  46. agServices.Configure<AgConfig>(agConfig.CopyTo);
  47. agServices.Configure<ArConfig>(arConfig.CopyTo);
  48. var agProvider = agServices.BuildServiceProvider();
  49. var agThread = agProvider.GetService<AgAgent>();
  50. _thread = new Thread(agThread.Run)
  51. {
  52. Name = nameof(AgAgent)
  53. };
  54. _thread.Start();
  55. }
  56. public static void Join()
  57. {
  58. _thread.Join();
  59. }
  60. public AgAgent(IOptions<AgConfig> options,
  61. IEnvironment environment, AgState state, IUi ui,
  62. IAgDustSensor agDustSensor, IAgBatterySensor agBatterySensor, IAgPickedSensor agPickedSensor, IAgVaccumSensor agVaccumSensor,
  63. IAgEngineEffector engineEffector, IAgVaccumEffector vaccumEffector)
  64. {
  65. _agDustSensor = agDustSensor;
  66. _agBatterySensor = agBatterySensor;
  67. _agPickedSensor = agPickedSensor;
  68. _agVaccumSensor = agVaccumSensor;
  69. _engineEffector = engineEffector;
  70. _vaccumEffector = vaccumEffector;
  71. _environment = environment;
  72. _state = state;
  73. _ui = ui;
  74. _options = options.Value;
  75. _state.LastThinkTime = DateTime.MinValue;
  76. _state.ThinkTimeInterval = _options.ThinkTimeInterval;
  77. }
  78. private void Run()
  79. {
  80. var running = true;
  81. _environment.Setup();
  82. _state.DustyRooms = _environment.FindDustyRoomsWithoutJewel();
  83. while (running)
  84. {
  85. if (_options.SleepTime > 0)
  86. {
  87. Thread.Sleep(_options.SleepTime);
  88. }
  89. UpdateSensors();
  90. _ui.Update();
  91. UpdateState();
  92. Think();
  93. Work();
  94. }
  95. }
  96. public void UpdateSensors()
  97. {
  98. _agDustSensor.Update();
  99. _agBatterySensor.Update();
  100. _agPickedSensor.Update();
  101. _agVaccumSensor.Update();
  102. }
  103. public void UpdateState()
  104. {
  105. if (_options.AutoAdjustThinkTimeInterval)
  106. {
  107. var dustyRooms = _environment.FindDustyRooms();
  108. if ((dustyRooms.Count < _state.DustyRooms.Count || !dustyRooms.Any()) && _state.ThinkTimeInterval < 7500)
  109. {
  110. _state.ThinkTimeInterval += _state.ThinkTimeInterval / 2;
  111. }
  112. else if (dustyRooms.Count > _state.DustyRooms.Count && _state.ThinkTimeInterval > 100)
  113. {
  114. _state.ThinkTimeInterval -= _state.ThinkTimeInterval / 2;
  115. }
  116. _state.DustyRooms = dustyRooms;
  117. }
  118. else
  119. {
  120. _state.DustyRooms = _environment.FindDustyRooms();
  121. }
  122. }
  123. public void Think()
  124. {
  125. if (_state.LastThinkTime.AddMilliseconds(_state.ThinkTimeInterval) <= DateTime.Now)
  126. {
  127. if (_state.Destination == null && _state.DustyRooms.Any())
  128. {
  129. _state.Destination = _state.DustyRooms.OrderBy(room => room.Distance(_engineEffector)).First();
  130. }
  131. _state.LastThinkTime = DateTime.Now;
  132. }
  133. }
  134. public void Work()
  135. {
  136. if (_environment.GetRoomState(_engineEffector.X, _engineEffector.Y).HasFlag(RoomState.Jewel))
  137. {
  138. _vaccumEffector.Pick();
  139. }
  140. if (_environment.GetRoomState(_engineEffector.X, _engineEffector.Y).HasFlag(RoomState.Dust))
  141. {
  142. _vaccumEffector.Vaccum();
  143. }
  144. if (_state.Destination != null && _engineEffector.IsInRoom(_state.Destination))
  145. {
  146. _state.Destination = null;
  147. }
  148. if (_state.Destination != null)
  149. {
  150. if (_state.Destination.X < _engineEffector.X)
  151. {
  152. _engineEffector.Move(-1, 0);
  153. }
  154. else if (_state.Destination.X > _engineEffector.X)
  155. {
  156. _engineEffector.Move(1, 0);
  157. }
  158. else if (_state.Destination.Y < _engineEffector.Y)
  159. {
  160. _engineEffector.Move(0, -1);
  161. }
  162. else if (_state.Destination.Y > _engineEffector.Y)
  163. {
  164. _engineEffector.Move(0, 1);
  165. }
  166. }
  167. }
  168. }
  169. }