コード例 #1
0
ファイル: Graph.cs プロジェクト: UserNT/SokobanSolver
        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);
        }
コード例 #2
0
ファイル: Graph.cs プロジェクト: UserNT/SokobanSolver
        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);
        }
コード例 #3
0
ファイル: Graph.cs プロジェクト: UserNT/SokobanSolver
        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);
        }