Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

AgAgent.cs 5.7KB

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