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.

AgAgent.cs 6.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Threading;
  5. using Microsoft.Extensions.DependencyInjection;
  6. using Microsoft.Extensions.Options;
  7. using uqac_ia_aspirobot.Agent.FakeEnv;
  8. using uqac_ia_aspirobot.Agent.FakeEnv.Effectors;
  9. using uqac_ia_aspirobot.Agent.FakeEnv.Sensors;
  10. using uqac_ia_aspirobot.Agent.Interfaces.Effectors;
  11. using uqac_ia_aspirobot.Agent.Interfaces.Sensors;
  12. using uqac_ia_aspirobot.Agent.Sensors;
  13. using uqac_ia_aspirobot.Common;
  14. using uqac_ia_aspirobot.Extensions;
  15. using uqac_ia_aspirobot.Interfaces;
  16. using uqac_ia_aspirobot.UI;
  17. namespace uqac_ia_aspirobot.Agent
  18. {
  19. public class AgAgent
  20. {
  21. private readonly IAgEngineEffector _engineEffector;
  22. private readonly IAgVaccumEffector _vaccumEffector;
  23. private readonly IEnvironment _environment;
  24. private readonly AgConfig _options;
  25. private readonly AgState _state;
  26. private readonly IUi _ui;
  27. private readonly IAgPerformanceSensor _agPerformanceSensor;
  28. private static Thread _thread;
  29. public static void Start(AgConfig agConfig, ArConfig arConfig)
  30. {
  31. var agServices = new ServiceCollection();
  32. agServices.AddOptions();
  33. agServices.AddSingleton<AgState>();
  34. agServices.AddSingleton<AgAgent>();
  35. agServices.AddSingleton<ArClient>();
  36. agServices.AddSingleton<IAgDustSensor, AgDustSensor>();
  37. agServices.AddSingleton<IAgBatterySensor, AgBatterySensor>();
  38. agServices.AddSingleton<IAgVaccumSensor, AgVaccumSensor>();
  39. agServices.AddSingleton<IAgPickedSensor, AgPickedSensor>();
  40. agServices.AddSingleton<IAgPerformanceSensor, AgPerformanceSensor>();
  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, IAgPerformanceSensor agPerformanceSensor,
  62. IAgEngineEffector engineEffector, IAgVaccumEffector vaccumEffector)
  63. {
  64. _engineEffector = engineEffector;
  65. _vaccumEffector = vaccumEffector;
  66. _environment = environment;
  67. _state = state;
  68. _ui = ui;
  69. _agPerformanceSensor = agPerformanceSensor;
  70. _options = options.Value;
  71. _state.LastThinkTime = DateTime.MinValue;
  72. _state.ThinkTimeInterval = _options.ThinkTimeInterval;
  73. }
  74. private void Run()
  75. {
  76. var running = true;
  77. _environment.Setup();
  78. _state.DustyRooms = new List<IRoom>();
  79. while (running)
  80. {
  81. _environment.Update();
  82. _ui.Update();
  83. UpdateState();
  84. Think();
  85. Work();
  86. if (_options.SleepTime > 0)
  87. {
  88. Thread.Sleep(_options.SleepTime);
  89. }
  90. }
  91. }
  92. public void UpdateState()
  93. {
  94. if (_options.AutoAdjustThinkTimeInterval)
  95. {
  96. var dustyRooms = _environment.FindDustyRooms();
  97. if ((dustyRooms.Count < _state.DustyRooms.Count || !dustyRooms.Any()) && _state.ThinkTimeInterval < 7500)
  98. {
  99. _state.ThinkTimeInterval += _state.ThinkTimeInterval / 2;
  100. }
  101. else if (dustyRooms.Count > _state.DustyRooms.Count && _state.ThinkTimeInterval > 100)
  102. {
  103. _state.ThinkTimeInterval -= _state.ThinkTimeInterval / 2;
  104. }
  105. _state.DustyRooms = dustyRooms;
  106. }
  107. else
  108. {
  109. _state.DustyRooms = _environment.FindDustyRooms();
  110. }
  111. }
  112. public void Think()
  113. {
  114. var now = DateTime.Now;
  115. if (_state.LastThinkTime.AddMilliseconds(_state.ThinkTimeInterval) <= now || _agPerformanceSensor.Performance <= _options.LowPerformance)
  116. {
  117. if (_state.Destination == null && _state.DustyRooms.Any())
  118. {
  119. _state.Destination = _state.DustyRooms.OrderBy(room => room.Distance(_engineEffector)).First();
  120. }
  121. _state.LastThinkTime = now;
  122. }
  123. }
  124. public void Work()
  125. {
  126. if (_environment.GetRoomState(_engineEffector.X, _engineEffector.Y).HasFlag(RoomState.Jewel))
  127. {
  128. _vaccumEffector.Pick();
  129. }
  130. if (_environment.GetRoomState(_engineEffector.X, _engineEffector.Y).HasFlag(RoomState.Dust))
  131. {
  132. _vaccumEffector.Vaccum();
  133. }
  134. if (_state.Destination != null && _engineEffector.IsInRoom(_state.Destination))
  135. {
  136. _state.Destination = null;
  137. }
  138. if (_state.Destination != null)
  139. {
  140. if (_state.Destination.X < _engineEffector.X)
  141. {
  142. _engineEffector.Move(-1, 0);
  143. }
  144. else if (_state.Destination.X > _engineEffector.X)
  145. {
  146. _engineEffector.Move(1, 0);
  147. }
  148. else if (_state.Destination.Y < _engineEffector.Y)
  149. {
  150. _engineEffector.Move(0, -1);
  151. }
  152. else if (_state.Destination.Y > _engineEffector.Y)
  153. {
  154. _engineEffector.Move(0, 1);
  155. }
  156. }
  157. }
  158. }
  159. }