Czoko_Smieciarka/Trunk/MonoGameView/Algorithms/DFS.cs

198 lines
7.0 KiB
C#
Raw Normal View History

2019-04-22 14:38:11 +02:00
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;
2019-04-22 14:32:18 +02:00
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
2019-04-22 14:38:11 +02:00
using Microsoft.Xna.Framework.Content;
2019-04-22 14:32:18 +02:00
2019-04-22 14:38:11 +02:00
namespace CzokoŚmieciarka.MonoGameView.Algorithms
2019-04-22 14:32:18 +02:00
{
public class DFS
{
public DFS()
{
2019-04-23 06:32:35 +02:00
2019-04-22 14:32:18 +02:00
}
int count = 0;
2019-04-23 06:32:35 +02:00
public List<Coords> Houses { get; set; }
2019-04-22 14:32:18 +02:00
2019-04-23 06:32:35 +02:00
public List<IStep> BestPath(ContentManager content, GarbageCollector collector, ICloneable[,] grid)
2019-04-22 14:32:18 +02:00
{
2019-04-23 06:32:35 +02:00
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));
}
}
}
2019-04-22 14:38:11 +02:00
var r=Search(content, collector, grid, 0).Key;
2019-04-23 06:32:35 +02:00
2019-04-22 14:38:11 +02:00
if (r == null) return new List<IStep>();
2019-04-22 14:32:18 +02:00
return r;
2019-04-23 06:32:35 +02:00
2019-04-22 14:32:18 +02:00
}
2019-04-23 06:32:35 +02:00
List<IStep> PossibleSteps(ContentManager content, AGarbageCollector collector, ICloneable[,] grid)
2019-04-22 14:32:18 +02:00
{
var result = new List<IStep>();
2019-04-23 09:30:16 +02:00
if (!(collector.TrashContainers.Any(x => x.FillPercent > 0) && grid[collector.Coords.X,collector.Coords.Y] is ADump))
2019-04-22 14:32:18 +02:00
{
2019-04-23 09:30:16 +02:00
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)
2019-04-22 14:32:18 +02:00
{
2019-04-23 09:30:16 +02:00
var copyCollector = (AGarbageCollector)collector.Clone();
try
2019-04-22 14:32:18 +02:00
{
2019-04-23 09:30:16 +02:00
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);
}
2019-04-22 14:32:18 +02:00
}
2019-04-23 09:30:16 +02:00
catch (Exception e)
{
2019-04-22 14:32:18 +02:00
2019-04-23 09:30:16 +02:00
}
2019-04-22 14:32:18 +02:00
}
2019-04-23 09:30:16 +02:00
2019-04-22 14:32:18 +02:00
}
2019-04-23 06:32:35 +02:00
if (grid[collector.Coords.X, collector.Coords.Y] is IGarbageLocalization)
{
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);
try
{
item.Invoke(copyCollector, copyGrid);
result.Add(item);
}
catch (Exception e)
{
}
}
}
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);
try
{
item.Invoke(copyCollector, copyGrid);
result.Add(item);
2019-04-22 14:32:18 +02:00
2019-04-23 06:32:35 +02:00
}
catch (Exception e)
{
}
}
}
2019-04-22 14:32:18 +02:00
return result;
}
2019-04-23 06:32:35 +02:00
KeyValuePair<List<IStep>, int> Search(ContentManager content, GarbageCollector collector, ICloneable[,] grid, int length)
2019-04-22 14:32:18 +02:00
{
2019-04-23 09:30:16 +02:00
if (length > 100) return new KeyValuePair<List<IStep>, int>(null,length);
2019-04-22 14:32:18 +02:00
count++;
2019-04-23 06:32:35 +02:00
if (Houses.All(c => (grid[c.X, c.Y] as IGarbageLocalization).TrashCans.All(j => j.FillPercent == 0.0))
&&
collector.TrashContainers.All(i => i.FillPercent == 0.0)
)
{
return new KeyValuePair<List<IStep>, int>(new List<IStep>(), length);
}
var possibleSteps = PossibleSteps(content, collector, grid);
2019-04-22 14:32:18 +02:00
foreach (var item in possibleSteps)
{
2019-04-23 06:32:35 +02:00
var copyCollector = (GarbageCollector)collector.Clone();
var copyGrid = CopyGrid(grid);
2019-04-22 14:32:18 +02:00
//if (copyGrid[copyCollector.Coords.X, copyCollector.Coords.Y] is IRoad1) copyGrid[copyCollector.Coords.X, copyCollector.Coords.Y] = new Road2();
item.Invoke(copyCollector, copyGrid);
2019-04-22 14:38:11 +02:00
var s = Search(content, copyCollector, copyGrid, length + 1);
2019-04-22 14:32:18 +02:00
if (s.Key != null)
{
s.Key.Insert(0, item);
return s;
}
}
return new KeyValuePair<List<IStep>, int>(null, length);
/*var min = int.MaxValue;
var min_index = 0;
for (int i = 0; i < mapped.Count; i++)
{
if (mapped.ElementAt(i).Value <= min)
{
min = mapped.ElementAt(i).Value;
min_index = i;
}
}
return mapped.ElementAt(min_index);
*/
}
2019-04-23 06:32:35 +02:00
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;
}
2019-04-22 14:32:18 +02:00
}
}