/// <summary> /// Executes given action for each element at target location. /// Target location is determined via combination of square, side and offset. /// For example /// Square = (leftX = 0, bottomY = 0, size = 10) /// Side = Vertical /// Offset = 0 /// Will result in /// Traversing all elements from /// (0,0) /// (0,1) /// ... /// (0,9) /// Changing offset to 1 will result in /// (1,0) /// (1,1) /// ... /// (1,9) /// being traversed. /// </summary> /// <param name="square">Information about a square from the grid.</param> /// <param name="side">Which side of a square is being traversed (vertical or horizontal).</param> /// <param name="action">Action that will be performed on all planets during traversal.</param> /// <param name="offset">Offset from leftX, bottomY in X for vertical side and Y for horizontal side.</param> public void Traverse(Square square, Side side, IPlanetAction action, int offset = 0) { var initialX = square.LeftX + (side == Side.Vertical ? offset : 0); var initialY = square.BottomY + (side == Side.Horizontal ? offset : 0); var finalX = (side == Side.Horizontal) ? initialX + square.Size : initialX + 1; var finalY = (side == Side.Vertical) ? initialY + square.Size : initialY + 1; var cachedTilePosition = _navigator.FindTile(new Position(initialX, initialY)); var cachedTile = _spaceGridTileCache.Get(cachedTilePosition); for (var x = initialX; x < finalX; x++) { for (var y = initialY; y < finalY; y++) { var position = new Position(x, y); var gridPosition = _navigator.Find(position); if (!cachedTilePosition.Equals(gridPosition.TilePosition)) { cachedTilePosition = gridPosition.TilePosition; cachedTile = _spaceGridTileCache.Get(cachedTilePosition); } var optPlanet = cachedTile.GetValue(gridPosition.ElementPosition); if (!optPlanet.HasValue) { continue; } action.Invoke(position, optPlanet.Value); } } }
/// <summary> /// Zooms a target view square. /// Even zoom values are responsible for top-right outlines of a target view square. /// Odd zoom values are responsible for left-bottom outlines of a target view square. /// For a selected outline - performs hideAction/showValue based on inside value. /// inside == true -> hide /// inside == false -> show /// </summary> private Square ZoomView(ref Square view, bool inside, IPlanetAction showAction, IPlanetAction hideAction) { var targetZoom = view.Size + (inside ? 0 : 1); var sideOffset = targetZoom % 2 == 0 ? view.Size : 0; var zoomOffset = targetZoom % 2 == 0 ? (inside ? -1 : 0) : (inside ? 0 : -1); var totalOffset = sideOffset + zoomOffset; var action = inside ? hideAction : showAction; var corner = new Position(view.LeftX + totalOffset, view.BottomY + totalOffset); var cornerPlanet = _spaceGrid.TryGetPlanet(corner); if (cornerPlanet != null) { action.Invoke(corner, cornerPlanet.Value); } _spaceGrid.Traverse(view, Side.Vertical, action, totalOffset); _spaceGrid.Traverse(view, Side.Horizontal, action, totalOffset); var viewSideOffset = inside ? -1 : 1; var viewPositionOffset = targetZoom % 2 != 0 ? (inside ? 1 : -1) : 0; return(new Square( view.Size + viewSideOffset, view.LeftX + viewPositionOffset, view.BottomY + viewPositionOffset )); }
public ObservablePlanets(SpaceGrid spaceGrid, int altViewCapacity, int playerRating) { _spaceGrid = spaceGrid; _observable = new Dictionary <Position, Planet>(); _altObservable = new Dictionary <Position, Planet>(); _readOnlyObservable = new ReadOnlyDictionary <Position, Planet>(_observable); _readOnlyAltObservable = new ReadOnlyDictionary <Position, Planet>(_altObservable); _altViewSet = new AltViewSet(altViewCapacity); Show = new ShowAction(this); Hide = new HideAction(this); AltShow = new AltShowAction(this); AltHide = new AltHideAction(this); CompositeShow = new CompositePlanetAction(this, new[] { Show, AltShow }); }
/// <summary> /// Executes given action for all the planets in given square /// </summary> /// <param name="square">Information about a square from the grid</param> /// <param name="action">Action that will be performed on all planets during traversal.</param> public void Traverse(Square square, IPlanetAction action) { for (var x = square.LeftX; x < square.LeftX + square.Size; x++) { for (var y = square.BottomY; y < square.BottomY + square.Size; y++) { var position = new Position(x, y); var optPlanet = TryGetPlanet(position); if (!optPlanet.HasValue) { continue; } action.Invoke(position, optPlanet.Value); } } }