Exemplo n.º 1
0
        private List <SectorConstrainedPosition> FindPositions(IEnumerable <EnemyMove> moves)
        {
            List <SectorConstrainedPosition> positions       = new List <SectorConstrainedPosition>();
            SectorConstrainedPosition        currentPosition = new SectorConstrainedPosition(0, 0, null);

            positions.Add(currentPosition);
            foreach (var move in moves)
            {
                if (!move.IsMovement && move.HasSector)
                {
                    currentPosition = new SectorConstrainedPosition(currentPosition.X, currentPosition.Y, move.Sector);
                    positions[positions.Count - 1] = currentPosition;
                    continue;
                }
                SectorConstrainedPosition newPosition;

                if (move.IsMovement)
                {
                    switch (move.Movement)
                    {
                    case Direction.East:
                        newPosition = new SectorConstrainedPosition(currentPosition.X + 1,
                                                                    currentPosition.Y,
                                                                    move.Sector);
                        break;

                    case Direction.North:
                        newPosition = new SectorConstrainedPosition(currentPosition.X,
                                                                    currentPosition.Y - 1,
                                                                    move.Sector);
                        break;

                    case Direction.South:
                        newPosition = new SectorConstrainedPosition(currentPosition.X,
                                                                    currentPosition.Y + 1,
                                                                    move.Sector);
                        break;

                    case Direction.West:
                        newPosition = new SectorConstrainedPosition(currentPosition.X - 1,
                                                                    currentPosition.Y,
                                                                    move.Sector);
                        break;

                    default:
                        throw new InvalidOperationException($"Invalid move {move}");
                    }

                    positions.Add(newPosition);
                    currentPosition = newPosition;
                }
            }

            int xMin = positions.Min(p => p.X);
            int yMin = positions.Min(p => p.Y);

            int xOffset = xMin < 0 ? Math.Abs(xMin) : 0;
            int yOffset = yMin < 0 ? Math.Abs(yMin) : 0;

            return(positions.Select(p =>
                                    new SectorConstrainedPosition(p.X + xOffset, p.Y + yOffset, p.SectorConstraint)).ToList());
        }
Exemplo n.º 2
0
        public IEnumerable <Position> LocateEnemy(CancellationToken cancellation, IEnumerable <EnemyMove> moves)
        {
            if (moves.Count() < 3)
            {
                return(Enumerable.Empty <Position>());
            }

            var positions = FindPositions(moves);
            var search    = new OverlayGrid(_grid.Width, _grid.Height, positions);
            Dictionary <Sector, OverlayGrid> sectorGrids =
                positions.Where(p => p.IsSectorConstrained)
                .GroupBy(p => p.SectorConstraint.Value)
                .ToDictionary(p => p.Key,
                              g => new OverlayGrid(_grid.Width, _grid.Height, g.ToList()));


            List <Position> offsetMatches = new List <Position>();

            do
            {
                if (cancellation.IsCancellationRequested)
                {
                    Console.Error.WriteLine("CANCELLING TARGETTING");
                    break;
                }

                var mask = search.Mask(_grid.GridBinary);

                if (PathDoesNotIntersectWithIslands(mask) &&
                    NoSectorCollisions(sectorGrids))
                {
                    offsetMatches.Add(search.CurrentOffset);
                    // Console.Error.WriteLine($"Found a place the enemy could be hiding offset {offset}");
                }

                if (!search.CanMoveRight && !search.CanMoveDown)
                {
                    break;
                }

                if (search.CanMoveRight)
                {
                    search.ShiftRight();
                    foreach (var sectorGrid in sectorGrids.Values)
                    {
                        sectorGrid.ShiftRight();
                    }
                    continue;
                }

                search.ShiftToOriginalX();
                search.ShiftDown();
                foreach (var sectorGrid in sectorGrids.Values)
                {
                    sectorGrid.ShiftToOriginalX();
                    sectorGrid.ShiftDown();
                }
            } while (true);

            SectorConstrainedPosition lastPosition = positions[positions.Count - 1];

            return(offsetMatches.Select(m => new Position(m.X + lastPosition.X, m.Y + lastPosition.Y)));
        }