private static IEnumerable<Vector> GetElements(Map map, Predicate<MapCell> predicate)
 {
     for(int i = 0; i < map.Width; i++)
         for(int j = 0; j < map.Height; j++)
             if(predicate(map.GetCell(i, j)))
                 yield return new Vector(i, j);
 }
Esempio n. 2
0
        private void Update(Map newMap)
        {
            var robotFailed = false;

            var activeMoves = new SortedSet<Tuple<Vector, Vector, MapCell>>(new TupleVectorComparer());
            foreach (var rockPos in activeRocks.Concat(newMap.activeRocks).Distinct())
            {
                var cell = newMap.GetCell(rockPos);
                var rockMove = TryToMoveRock(rockPos, cell, newMap);
                if (rockMove == null) continue;
                var newRockPos = rockPos.Add(rockMove);
                if (cell == MapCell.LambdaRock && newMap.GetCell(newRockPos.Sub(new Vector(0, 1))) != MapCell.Empty)
                    activeMoves.Add(Tuple.Create(rockPos, newRockPos, MapCell.Lambda));
                else
                    activeMoves.Add(Tuple.Create(rockPos, newRockPos, cell));
            }

            newMap.GrowthLeft--;
            if (newMap.GrowthLeft == 0)
            {
                newMap.GrowthLeft = newMap.Growth;
                foreach (var beardPos in newMap.Beard)
                    for (var x = -1; x <= 1; x++)
                        for (var y = -1; y <= 1; y++)
                        {
                            var newBeardPos = beardPos.Add(new Vector(x, y));
                            if (newMap.GetCell(newBeardPos) == MapCell.Empty)
                                activeMoves.Add(Tuple.Create(beardPos, newBeardPos, MapCell.Beard));
                        }
            }

            var newActiveRocks = new SortedSet<Vector>(new VectorComparer());
            foreach (var activeMove in activeMoves)
            {
                var fromPos = activeMove.Item1;
                var toPos = activeMove.Item2;
                var fromCell = newMap.GetCell(fromPos);
                var toCell = newMap.GetCell(toPos);
                if (fromCell.IsRock())
                {
                    if (!toCell.IsRock()) newActiveRocks.Add(toPos);

                    newMap.field = newMap.SetCell(toPos, activeMove.Item3);
                    newMap.field = newMap.SetCell(fromPos, MapCell.Empty);

                    robotFailed |= IsRobotKilledByRock(toPos.X, toPos.Y, newMap);
                    CheckNearRocks(newActiveRocks, fromPos.X, fromPos.Y, newMap);
                    newMap.Beard.Remove(toPos);
                }
                else if(fromCell == MapCell.Beard)
                {
                    newMap.field = newMap.SetCell(toPos, MapCell.Beard);
                    newMap.Beard.Add(toPos);
                }
            }
            newMap.activeRocks = newActiveRocks;

            if (newMap.TotalLambdaCount == newMap.LambdasGathered)
                newMap.field = newMap.SetCell(Lift, MapCell.OpenedLift);

            robotFailed |= IsRobotKilledByFlood(newMap);
            if (robotFailed)
                newMap.State = CheckResult.Fail;
        }
Esempio n. 3
0
 private static Vector TryToMoveRock(Vector p, MapCell xyCell, Map mapToUse)
 {
     int x = p.X;
     int y = p.Y;
     if (xyCell.IsRock())
     {
         var upCell = mapToUse.GetCell(x, y - 1);
         if (upCell == MapCell.Empty)
         {
             return new Vector(0, -1);
         }
         if (upCell.IsRock()
             && mapToUse.GetCell(x + 1, y) == MapCell.Empty && mapToUse.GetCell(x + 1, y - 1) == MapCell.Empty)
         {
             return new Vector(1, -1);
         }
         if (upCell.IsRock()
             && (mapToUse.GetCell(x + 1, y) != MapCell.Empty || mapToUse.GetCell(x + 1, y - 1) != MapCell.Empty)
             && mapToUse.GetCell(x - 1, y) == MapCell.Empty && mapToUse.GetCell(x - 1, y - 1) == MapCell.Empty)
         {
             return new Vector(-1, -1);
         }
         if (upCell == MapCell.Lambda
             && mapToUse.GetCell(x + 1, y) == MapCell.Empty && mapToUse.GetCell(x + 1, y - 1) == MapCell.Empty)
         {
             return new Vector(1, -1);
         }
     }
     return null;
 }
Esempio n. 4
0
 private static bool IsRobotKilledByRock(int x, int y, Map mapToUse)
 {
     return mapToUse.GetCell(x, y - 1) == MapCell.Robot;
 }
Esempio n. 5
0
 private static void CheckNearRocks(SortedSet<Vector> updateableRocks, int x, int y, Map mapToUse)
 {
     for (var rockX = x - 1; rockX <= x + 1; rockX++)
         for (var rockY = y; rockY <= y + 1; rockY++)
         {
             var rockPos = new Vector(rockX, rockY);
             if (TryToMoveRock(rockPos, mapToUse.GetCell(rockPos), mapToUse) != null)
                 updateableRocks.Add(rockPos);
         }
 }
Esempio n. 6
0
        private RobotMove FindMovableRock(Map map)
        {
            var left = new Vector(-1, 0);
            var right = new Vector(1, 0);
            var up = new Vector(0, 1);

            var leftRobot = map.Robot.Add(left);
            var rightRobot = map.Robot.Add(right);
            var upRobot = map.Robot.Add(up);

            var leftCheck = map.GetCell(leftRobot) != MapCell.Wall && map.IsSafeMove(map.Robot, map.Robot.Add(left), 1, map.WaterproofLeft);
            var rightCheck = map.GetCell(rightRobot) != MapCell.Wall && map.IsSafeMove(map.Robot, map.Robot.Add(right), 1, map.WaterproofLeft);

            if (map.GetCell(leftRobot).IsRock() && map.GetCell(leftRobot.Add(left)) == MapCell.Empty && leftCheck)
                return RobotMove.Left;
            if (map.GetCell(rightRobot).IsRock() && map.GetCell(rightRobot.Add(right)) == MapCell.Empty && rightCheck)
                return RobotMove.Right;

            if (map.GetCell(upRobot).IsRock() && map.GetCell(leftRobot).IsMovable() && leftCheck)
                return RobotMove.Left;
            if (map.GetCell(upRobot).IsRock() && map.GetCell(rightRobot).IsMovable() && rightCheck)
                return RobotMove.Right;

            var waveRun = new WaveRun(map, map.Robot);
            moveRockTarget = waveRun.EnumerateTargets(
                (lmap, position, used) =>
                    {
                        if (lmap.GetCell(position.Add(up)).IsRock() && (lmap.GetCell(position.Add(left)).IsMovable() || lmap.GetCell(position.Add(right)).IsMovable()))
                            return true;
                        if (lmap.GetCell(position).IsMovable() && lmap.GetCell(position.Add(left)).IsRock() && lmap.GetCell(position.Add(left).Add(left)).IsRockMovable())
                            return true;
                        if (lmap.GetCell(position).IsMovable() && lmap.GetCell(position.Add(right)).IsRock() && lmap.GetCell(position.Add(right).Add(right)).IsRockMovable())
                            return true;
                        if (lmap.GetCell(position) == MapCell.Earth && lmap.GetCell(position.Add(right)).IsRock()
                                && lmap.GetCell(position.Add(right).Add(right)) != MapCell.Wall && !lmap.GetCell(position.Add(right).Add(right)).IsRock())
                            return true;
                        if (lmap.GetCell(position) == MapCell.Earth && lmap.GetCell(position.Add(left)).IsRock()
                                && lmap.GetCell(position.Add(right).Add(right)) != MapCell.Wall && !lmap.GetCell(position.Add(right).Add(right)).IsRock())
                            return true;
                        return false;
                    }).FirstOrDefault();

            if(moveRockTarget == null)
                return RobotMove.Abort;

            return moveRockTarget.Item2.Any() ? moveRockTarget.Item2.Peek() : RobotMove.Abort;
        }
Esempio n. 7
0
        private Tuple<Vector, Stack<RobotMove>> FindBestTarget(Map map, bool checkBestIsNotBad = true)
        {
            var waveRun = new WaveRun(map, map.Robot, checkBestIsNotBad ? 400000 : 1000);
            Tuple<Vector, Stack<RobotMove>> result = null;

            if(checkBestIsNotBad)
            {
                var orderedMoves = waveRun
                    .EnumerateTargets((lmap, pos, stepNumber) => lmap.GetCell(pos) == MapCell.Lambda
                        || (lmap.LambdasGathered != lmap.TotalLambdaCount && lmap.GetCell(pos) == MapCell.Razor))
                    .Where(tuple => specialTargetType != SpecialTargetType.Banned || specialTarget == null || (tuple.Item1.X != specialTarget.X && tuple.Item1.Y != specialTarget.Y))
                    .Take(9)
                    .OrderBy(t => CalculateTargetBadness(t, map)).ToArray();
                result = orderedMoves.FirstOrDefault();
            }
            else result = waveRun.EnumerateTargets((lmap, pos, stepNumber) => lmap.GetCell(pos) == MapCell.Lambda
                || (lmap.LambdasGathered != lmap.TotalLambdaCount && lmap.GetCell(pos) == MapCell.Razor)).FirstOrDefault();
            if(result != null) return result;
            if(waveRun.Lift != null && map.GetCell(waveRun.Lift.Item1) == MapCell.OpenedLift)
                return waveRun.Lift;
            return null;
        }