123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165 |
- using System.Linq;
- using System.Threading;
- using Microsoft.Extensions.DependencyInjection;
- using Microsoft.Extensions.Options;
- using uqac_ia_aspirobot.Agent.Effectors;
- using uqac_ia_aspirobot.Common;
- using uqac_ia_aspirobot.Extensions;
- using uqac_ia_aspirobot.Interfaces;
- using uqac_ia_aspirobot.UI;
-
- namespace uqac_ia_aspirobot.Agent
- {
- public class AgAgent
- {
- private readonly AgDustSensor _agDustSensor;
-
- private readonly AgEngineEffector _engineEffector;
-
- private readonly AgVaccumEffector _vaccumEffector;
-
- private readonly IEnvironment _environment;
-
- private readonly AgConfig _options;
-
- private readonly AgState _state;
- private readonly IUi _ui;
-
- private static Thread _thread;
-
- public static void Start(AgConfig agConfig, ArConfig arConfig)
- {
- var agServices = new ServiceCollection();
- agServices.AddOptions();
- agServices.AddSingleton<AgState>();
- agServices.AddSingleton<AgAgent>();
- agServices.AddSingleton<ArClient>();
-
- agServices.AddSingleton<AgDustSensor>();
- agServices.AddSingleton<AgBatterySensor>();
- agServices.AddSingleton<AgVaccumSensor>();
- agServices.AddSingleton<AgPickedSensor>();
-
- agServices.AddSingleton<AgVaccumEffector>();
- agServices.AddSingleton<AgEngineEffector>();
-
- agServices.AddSingleton<IUi, UiConsole>();
- agServices.AddSingleton<IEnvironment, AgEnvironment>();
- agServices.AddTransient<IRoom, AgRoom>();
- agServices.Configure<AgConfig>(agConfig.CopyTo);
- agServices.Configure<ArConfig>(arConfig.CopyTo);
- var agProvider = agServices.BuildServiceProvider();
- var agThread = agProvider.GetService<AgAgent>();
- _thread = new Thread(agThread.Run)
- {
- Name = nameof(AgAgent)
- };
- _thread.Start();
- }
-
- public static void Join()
- {
- _thread.Join();
- }
-
- public AgAgent(IEnvironment environment, IOptions<AgConfig> options, AgState state, IUi ui,
- AgDustSensor agDustSensor,
- AgEngineEffector engineEffector, AgVaccumEffector vaccumEffector)
- {
- _agDustSensor = agDustSensor;
- _engineEffector = engineEffector;
- _vaccumEffector = vaccumEffector;
- _environment = environment;
- _state = state;
- _ui = ui;
- _options = options.Value;
- _state.SleepTime = _options.SleepTime;
- }
-
- private void Run()
- {
- var running = true;
-
- _environment.Setup();
- _state.DustyRooms = _environment.FindDustyRoomsWithoutJewel();
-
- while (running)
- {
- if (_state.SleepTime > 0)
- {
- Thread.Sleep(_state.SleepTime);
- }
- UpdateSensors();
- _ui.Update();
- UpdateState();
- Think();
- Work();
- }
- }
-
- public void UpdateSensors()
- {
- _agDustSensor.Update();
- }
-
- public void UpdateState()
- {
- var dustyRooms = _environment.FindDustyRooms();//TODO Compute average on xx last values
- if (_options.AutoAdjustSleepTime)
- {
- if (dustyRooms.Count > _state.DustyRooms.Count)
- {
- _state.SleepTime += _state.SleepTime / 2;
- }
- else if (dustyRooms.Count < _state.DustyRooms.Count)
- {
- _state.SleepTime -= _state.SleepTime / 2;
- }
- }
- _state.DustyRooms = dustyRooms;
- }
-
- public void Think()
- {
- if (_state.Destination == null && _state.DustyRooms.Any())
- {
- _state.Destination = _state.DustyRooms.OrderBy(room => room.Distance(_engineEffector)).First();
- }
- }
-
- public void Work()
- {
- if (_environment.GetRoomState(_engineEffector.X, _engineEffector.Y).HasFlag(RoomState.Jewel))
- {
- _vaccumEffector.Pick();
- }
- if (_environment.GetRoomState(_engineEffector.X, _engineEffector.Y).HasFlag(RoomState.Dust))
- {
- _vaccumEffector.Vaccum();
- }
- if (_state.Destination != null && _engineEffector.IsInRoom(_state.Destination))
- {
- _state.Destination = null;
- }
- if (_state.Destination != null)
- {
- if (_state.Destination.X < _engineEffector.X)
- {
- _engineEffector.Move(-1, 0);
- }
- else if (_state.Destination.X > _engineEffector.X)
- {
- _engineEffector.Move(1, 0);
- }
- else if (_state.Destination.Y < _engineEffector.Y)
- {
- _engineEffector.Move(0, -1);
- }
- else if (_state.Destination.Y > _engineEffector.Y)
- {
- _engineEffector.Move(0, 1);
- }
- }
- }
- }
- }
|