Czoko_Smieciarka/Trunk/MonoGameView/Algorithms/BFS.cs
2019-05-14 23:05:37 +02:00

228 lines
7.9 KiB
C#

using CzokoŚmieciarka.MonoGameView.DataModels.Enums;
using CzokoŚmieciarka.MonoGameView.DataModels.Interfaces;
using CzokoŚmieciarka.MonoGameView.DataModels.Interfaces.GarbageCollector;
using CzokoŚmieciarka.MonoGameView.DataModels.Interfaces.TrashCans;
using CzokoŚmieciarka.MonoGameView.DataModels.Models;
using CzokoŚmieciarka.MonoGameView.DataModels.Models.Steps;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Xna.Framework.Content;
using System.Threading;
using CzokoŚmieciarka.MonoGameView.DataModels.GeneralModels.Models;
namespace MonoGameView.Algorithms
{
public class BFS
{
public GarbageCollector Collector { get; set; }
public ICloneable[,] Grid { get; set; }
public BFS(GarbageCollector collector, ICloneable[,] grid)
{
this.Collector = collector;
this.Grid = grid;
}
int count = 0;
public List<Coords> Houses { get; set; }
public KeyValuePair<List<IStep>,int> BestPath(ContentManager content, GarbageCollector collector, ICloneable[,] grid)
{
Houses = new List<Coords>();
for (int x = 0; x < grid.GetLength(0); x++)
{
for (int y = 0; y < grid.GetLength(1); y++)
{
if (grid[x, y] is House)
{
Houses.Add(new Coords(x, y));
}
}
}
var r = SearchBfs(content, collector, grid, 0);
Console.WriteLine($"Counts : {count}");
if (r.Key == null) return new KeyValuePair<List<IStep>,int>(new List<IStep>(), 0);
return r;
}
List<IStep> PossibleSteps(AGarbageCollector collector, ICloneable[,] grid)
{
var result = new List<IStep>();
var itemdupa = grid[collector.Coords.X, collector.Coords.Y];
if (grid[collector.Coords.X, collector.Coords.Y] is House)
{
var collectSteps = new List<IStep>()
{
new CollectStep(GarbageType.Glass),
new CollectStep(GarbageType.Organic),
new CollectStep(GarbageType.Paper),
new CollectStep(GarbageType.PlasticMetal)
};
foreach (var item in collectSteps)
{
var copyCollector = (AGarbageCollector)collector.Clone();
var copyGrid = CopyGrid(grid);
if (item.Invoke(copyCollector, copyGrid))
result.Add(item);
}
}
if (grid[collector.Coords.X, collector.Coords.Y] is ADump)
{
var collectSteps = new List<IStep>()
{
new SpillStep(GarbageType.Glass),
new SpillStep(GarbageType.Organic),
new SpillStep(GarbageType.Paper),
new SpillStep(GarbageType.PlasticMetal)
};
foreach (var item in collectSteps)
{
var copyCollector = (AGarbageCollector)collector.Clone();
var copyGrid = CopyGrid(grid);
if (item.Invoke(copyCollector, copyGrid))
result.Add(item);
}
}
if (!(grid[collector.Coords.X, collector.Coords.Y] is Dump && collector.TrashContainers.Any(x => x.FillPercent > 0 && (grid[collector.Coords.X, collector.Coords.Y] as Dump).TypeOfGarbage.GarbageType == x.TypeOfGarbage.GarbageType))
&& !(grid[collector.Coords.X, collector.Coords.Y] is House
&& (grid[collector.Coords.X, collector.Coords.Y] as House).TrashCans.Any(j => j.FillPercent > 0 && collector.TrashContainers.Any(i => i.FillPercent < 1 && i.Garbage.TypeOfGarbage.GarbageType == j.TypeOfGarbage.GarbageType))))
{
var moveSteps = new List<IStep>()
{
new MoveStep(Direction.Up),
new MoveStep(Direction.Down),
new MoveStep(Direction.Left),
new MoveStep(Direction.Right)
};
var filteredMoveSteps = new List<IStep>();
foreach (var item in moveSteps)
{
var copyCollector = (AGarbageCollector)collector.Clone();
if (item.Invoke(copyCollector, grid))
{
var gcx = copyCollector.Coords.X;
var gcy = copyCollector.Coords.Y;
if (grid[gcx, gcy] is Road1 || grid[gcx, gcy] is House || (grid[gcx, gcy] is ADump && copyCollector.TrashContainers.Any(x => x.FillPercent > 0)))
{
result.Add(item);
}
}
}
}
return result;
}
KeyValuePair<List<IStep>, int> SearchBfs(ContentManager content, GarbageCollector collector, ICloneable[,] grid, int length)
{
//Thread.Sleep(1);
int count = 0;
var nodes = new Queue<Tuple<List<IStep>, GarbageCollector, ICloneable[,]>>();
nodes.Enqueue(new Tuple<List<IStep>, GarbageCollector, ICloneable[,]>(new List<IStep>(), collector, grid));
while (true)
{
//Console.WriteLine(count);
//Console.WriteLine(nodes.Count);
//var nodes2 = new List<Tuple<List<IStep>, GarbageCollector, ICloneable[,]>>();
while (true)
{
count++;
var item = nodes.Dequeue();
//Thread.Sleep(100);
/*this.Collector.Coords = item.Item2.Coords;
this.Collector.TrashContainers = item.Item2.TrashContainers;
for (int x = 0; x < item.Item3.GetLength(0); x++)
{
for (int y = 0; y < item.Item3.GetLength(1); y++)
{
this.Grid[x, y] = item.Item3[x, y];
}
}*/
if (Houses.All(c => (item.Item3[c.X, c.Y] as IGarbageLocalization).TrashCans.All(j => j.FillPercent == 0.0))
&&
item.Item2.TrashContainers.All(i => i.FillPercent == 0.0)
)
{
Console.WriteLine(count);
return new KeyValuePair<List<IStep>, int>(item.Item1, count);
}
if (true)//item.Item2.Counter <= 12)
{
foreach (var step in PossibleSteps(item.Item2, item.Item3))
{
var collectorClone = (GarbageCollector)item.Item2.Clone();
var gridClone = CopyGrid(item.Item3);
step.Invoke(collectorClone, gridClone);
var steps = new List<IStep>();
steps.AddRange(item.Item1);
steps.Add(step);
nodes.Enqueue(new Tuple<List<IStep>, GarbageCollector, ICloneable[,]>(steps, collectorClone, gridClone));
}
}
}
}
}
private ICloneable[,] CopyGrid(ICloneable[,] grid)
{
ICloneable[,] result = new ICloneable[grid.GetLength(0), grid.GetLength(1)];
for (int x = 0; x < grid.GetLength(0); x++)
{
for (int y = 0; y < grid.GetLength(1); y++)
{
result[x, y] = (ICloneable)grid[x, y].Clone();
}
}
return result;
}
}
}