public static Dictionary <int, LocationGroup> GetAreasToBoxesTouchPoints(INavigator navigator) { var areasToBoxTouchPoints = new Dictionary <int, LocationGroup>(); navigator.Foreach(new[] { Sokoban.EMPTY, Sokoban.LOCATION, Sokoban.KEEPER, Sokoban.KEEPER_ON_LOCATION }, (areaId, position) => { if (!areasToBoxTouchPoints.ContainsKey(areaId)) { areasToBoxTouchPoints.Add(areaId, new LocationGroup(areaId) { }); } areasToBoxTouchPoints[areaId].Positions.Add(position); navigator.ForeachNeighbors(position, (neighbor, key, cellType) => { if (neighbor.HasValue && (cellType == Sokoban.BOX || cellType == Sokoban.BOX_ON_LOCATION)) { areasToBoxTouchPoints[areaId].EntryPoints.Add(new SokobanPathItem() { Position = position, //neighbor.Value, Key = key, //navigator.GetOppositeKey(key), StepsToTarget = 1 }); } }); }); return(areasToBoxTouchPoints); }
private static List <int> GetBoxesToExit(INavigator navigator, SokobanPathItem entryPoint) { var boxes = new List <int>(); //var areasToBoxTouchPoints = GetAreasToBoxesTouchPoints(navigator); //var keeperPos = navigator.GetKeeperPosition(); //var keeperArea = areasToBoxTouchPoints.Where(x => x.Value.Positions.Contains(keeperPos)).First(); navigator.Foreach(new[] { Sokoban.BOX_ON_LOCATION }, (box) => { var keeperPos = navigator.GetKeeperPosition(); var keeperTarget = navigator.GetPosition(navigator.GetOppositeKey(entryPoint.Key), keeperPos); var targetBoxPos = entryPoint.Position; if (navigator.CanDrag(keeperPos, box, keeperTarget.Value, targetBoxPos)) { boxes.Add(box); } //var keeperToBoxTouchPoints = keeperArea.Value.EntryPoints.Where(ep => navigator.GetPosition(ep.Key, ep.Position).Value == box).ToList(); //var isKeeperCanTouchBox = keeperToBoxTouchPoints.Count > 0; //if (isKeeperCanTouchBox && CanDrag(box, navigator, entryPoint, keeperToBoxTouchPoints)) //{ // boxes.Add(box); //} }); return(boxes); }
public static Dictionary <int, LocationGroup> GetLocationGroups(INavigator navigator) { var locationGroups = new Dictionary <int, LocationGroup>(); navigator.Foreach(new[] { Sokoban.LOCATION, Sokoban.KEEPER_ON_LOCATION, Sokoban.BOX_ON_LOCATION }, (areaId, position) => { if (!locationGroups.ContainsKey(areaId)) { locationGroups.Add(areaId, new LocationGroup(areaId) { }); } locationGroups[areaId].Positions.Add(position); foreach (var key in Sokoban.SupportedKeys) { var neighbor1 = navigator.GetPosition(key, position); if (neighbor1.HasValue && (navigator[neighbor1.Value] == Sokoban.EMPTY || navigator[neighbor1.Value] == Sokoban.KEEPER || navigator[neighbor1.Value] == Sokoban.BOX)) { var neighbor2 = navigator.GetPosition(key, neighbor1.Value); if (neighbor2.HasValue && (navigator[neighbor2.Value] == Sokoban.EMPTY || navigator[neighbor2.Value] == Sokoban.KEEPER || navigator[neighbor2.Value] == Sokoban.BOX)) { var oppositeKey = key == Key.Up ? Key.Down : key == Key.Down ? Key.Up : key == Key.Left ? Key.Right : Key.Left; locationGroups[areaId].EntryPoints.Add(new SokobanPathItem() { Position = neighbor1.Value, Key = oppositeKey, StepsToTarget = 1 }); } } } }); return(locationGroups); }