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 MonoGameView.DataModels.Models; using CzokoŚmieciarka.MonoGameView.DataModels.GeneralModels.Models; namespace CzokoŚmieciarka.MonoGameView.Algorithms { public class DFS { public GarbageCollector Collector { get; set; } public ICloneable[,] Grid { get; set; } public DFS(GarbageCollector collector, ICloneable[,] grid) { this.Collector = collector; this.Grid = grid; } int count = 0; public List Houses { get; set; } public KeyValuePair,int> BestPath(ContentManager content, GarbageCollector collector, ICloneable[,] grid) { Houses = new List(); 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=Search(content, collector, grid, 0).Key; Console.WriteLine($"Counts : {count}"); if (r == null) return new KeyValuePair,int>(new List(),0); return new KeyValuePair, int>(r,count); } List PossibleSteps(AGarbageCollector collector, ICloneable[,] grid) { var result = new List(); if (grid[collector.Coords.X, collector.Coords.Y] is House) { var collectSteps = new List() { 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() { 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() { new MoveStep(Direction.Up), new MoveStep(Direction.Down), new MoveStep(Direction.Left), new MoveStep(Direction.Right) }; var filteredMoveSteps = new List(); 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, int> Search(ContentManager content, GarbageCollector collector, ICloneable[,] grid, int length) { //Thread.Sleep(10); /*this.Collector.Coords = collector.Coords; this.Collector.TrashContainers = collector.TrashContainers; for (int x = 0; x < grid.GetLength(0); x++) { for (int y = 0; y < grid.GetLength(1); y++) { this.Grid[x, y] = (ICloneable) grid[x, y].Clone(); } } */ //Console.WriteLine(collector.HouseCounter); if (collector.Counter> 1000 || length > 10000) return new KeyValuePair, int>(null,length); count++; 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, int>(new List(), length); } var possibleSteps = PossibleSteps(collector, grid); foreach (var item in possibleSteps) { var copyCollector = (GarbageCollector)collector.Clone(); var copyGrid = CopyGrid(grid); //if (copyGrid[copyCollector.Coords.X, copyCollector.Coords.Y] is IRoad1) copyGrid[copyCollector.Coords.X, copyCollector.Coords.Y] = new Road2(); item.Invoke(copyCollector, copyGrid); var s = Search(content, copyCollector, copyGrid, length + 1); if (s.Key != null) { s.Key.Insert(0, item); return s; } } return new KeyValuePair, 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); */ } 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; } } }