118 lines
4.7 KiB
C#
118 lines
4.7 KiB
C#
using CzokoŚmieciarka.DataModels.Enums;
|
|
using CzokoŚmieciarka.DataModels.Interfaces;
|
|
using CzokoŚmieciarka.DataModels.Interfaces.RoutePlanningEngine;
|
|
using CzokoŚmieciarka.DataModels.Interfaces.TrashCans;
|
|
using CzokoŚmieciarka.DataModels.Models;
|
|
using CzokoŚmieciarka.DataModels.Models.Steps;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
|
|
namespace Czoko_Smieciarka.AI_Naive
|
|
{
|
|
public class RoutePlanningEngine : IRoutePlanningEngine
|
|
{
|
|
public IGarbageCollector Collector { get; }
|
|
public IEnumerable<IGarbageLocalization> Cans { get; }
|
|
public IEnumerable<ADump> Dumps { get; }
|
|
|
|
enum State { TravelToDump, TravelToCan, Wait, Finish }
|
|
public Coords Destination { get; set; }
|
|
public object DestinationObject { get; set; }
|
|
private State CurrentState { get; set; }
|
|
|
|
public IEnumerable<IStep> CalculateStep()
|
|
{
|
|
return PerformMove();
|
|
}
|
|
|
|
public RoutePlanningEngine(IGarbageCollector collector, IEnumerable<IGarbageLocalization> cans, IEnumerable<ADump> dumps)
|
|
{
|
|
this.Collector = collector.Clone() as IGarbageCollector;
|
|
this.Cans = cans;
|
|
this.Dumps = dumps;
|
|
this.CurrentState = State.Wait;
|
|
}
|
|
|
|
|
|
private IEnumerable<IStep> PerformMove()
|
|
{
|
|
|
|
switch (CurrentState)
|
|
{
|
|
case State.TravelToDump:
|
|
if (Destination == Collector.Position)
|
|
{
|
|
var dump = (DestinationObject as ADump);
|
|
var step = new SpillStep(Collector, dump, dump.TypeOfGarbage);
|
|
step.Invoke();
|
|
yield return step;
|
|
this.CurrentState = State.Wait;
|
|
} else
|
|
{
|
|
var dif = Destination - Collector.Position;
|
|
Direction nextDirection = (dif.X == 0) ?
|
|
((dif.Y > 0) ? Direction.Up : Direction.Down) :
|
|
((dif.X > 0) ? Direction.Right : Direction.Left);
|
|
|
|
var step = new MoveStep(nextDirection, Collector);
|
|
step.Invoke();
|
|
yield return step;
|
|
}
|
|
break;
|
|
case State.TravelToCan:
|
|
if (Destination == Collector.Position)
|
|
{
|
|
var garbage = (DestinationObject as IGarbageLocalization);
|
|
foreach (var item in garbage.TrashCans)
|
|
{
|
|
var step = new CollectStep(Collector, garbage, item.TypeOfGarbage);
|
|
step.Invoke();
|
|
yield return step;
|
|
}
|
|
|
|
this.CurrentState = State.Wait;
|
|
}
|
|
else
|
|
{
|
|
var dif = Destination - Collector.Position;
|
|
Direction nextDirection = (dif.X == 0) ?
|
|
((dif.Y > 0) ? Direction.Up : Direction.Down) :
|
|
((dif.X > 0) ? Direction.Right : Direction.Left);
|
|
|
|
var step = new MoveStep(nextDirection, Collector);
|
|
step.Invoke();
|
|
yield return step;
|
|
}
|
|
break;
|
|
case State.Wait:
|
|
var notEmpty = Collector.TrashContainers.Where(i => i.FillPercent > 0);
|
|
if (notEmpty.Any())
|
|
{
|
|
var destDump = Dumps.First(i => i.TypeOfGarbage == notEmpty.First().TypeOfGarbage);
|
|
this.Destination = destDump.Localization;
|
|
this.CurrentState = State.TravelToDump;
|
|
} else
|
|
{
|
|
var notEmptyCans = Cans.Where(i => i.TrashCans.Any(j => j.FillPercent > 0));
|
|
if (notEmptyCans.Any())
|
|
{
|
|
this.Destination = notEmptyCans.First().Coords;
|
|
this.CurrentState = State.TravelToCan;
|
|
} else
|
|
{
|
|
this.CurrentState = State.Finish;
|
|
}
|
|
}
|
|
break;
|
|
case State.Finish:
|
|
yield break;
|
|
}
|
|
foreach (var item in PerformMove())
|
|
{
|
|
yield return item;
|
|
}
|
|
}
|
|
}
|
|
}
|