public void WritePerformanceDirect() { const int width = 150; const int height = 150; var grid = new int[width, height]; var immutableGrid = ImmutableGrid <int> .Create(width, height); var gridTime = BenchmarkHelper( width, height, (x, y) => grid[x, y] = x + y); var immutableGridTime = BenchmarkHelper( width, height, (x, y) => immutableGrid.Set(x, y, x + y)); // Use the builder for many updates :) // This looks ugly but still 1/2 time of nested immutable // dictionary var factor = immutableGridTime / gridTime; #if DEBUG Assert.IsTrue(factor < 800, "Factor was " + factor); #else Assert.IsTrue(factor < 700, "Factor was " + factor); #endif }
public void CreateBuilder() { var builder = ImmutableGrid <int> .CreateBuilder(2, 3); Assert.AreEqual(2, builder.Width); Assert.AreEqual(3, builder.Height); }
public void CreateReferenceType() { var grid = ImmutableGrid <object> .Create(10, 20); Assert.AreEqual(10, grid.Width); Assert.AreEqual(20, grid.Height); Assert.IsTrue(grid.All(x => x.Item2 == default(object))); }
public void CreateValueType() { var grid = ImmutableGrid <int> .Create(10, 20); Assert.AreEqual(10, grid.Width); Assert.AreEqual(20, grid.Height); Assert.IsTrue(grid.All(x => x.Item2 == default(int))); }
public void Set() { var source = ImmutableGrid <int> .Create(2, 2).Set(0, 0, 5); var grid = source.Set(0, 0, 6); Assert.AreEqual(6, grid[0, 0]); Assert.AreEqual(5, source[0, 0]); }
public void Indexer() { var grid = ImmutableGrid <int> .Create(2, 2) .Set(0, 0, 5) .Set(0, 1, 6); Assert.AreEqual(5, grid[0, 0]); Assert.AreEqual(6, grid[0, 1]); }
public void ToBuilder() { var source = ImmutableGrid <int> .Create(2, 2).Set(0, 0, 5); var grid = source.ToBuilder().Set(1, 1, 3).Build(); Assert.AreEqual(5, grid[0, 0]); Assert.AreEqual(3, grid[1, 1]); Assert.AreEqual(5, source[0, 0]); Assert.AreEqual(default(int), source[1, 1]); }
static SimpleLevel() { Player = Actor.Create( 1, ActorTypes.Player, "Player", HitPoints.Create(10, 10)); Monster = Actor.Create( 2, ActorTypes.Monster, "Monster", HitPoints.Create(10, 10)); Floor = Tile.Create(TileTypes.Floor, "Floor"); Wall = Tile.Create(TileTypes.Wall, "Wall"); OpenDoor = Tile.Create(TileTypes.OpenDoor, "OpenDoor"); ClosedDoor = Tile.Create(TileTypes.ClosedDoor, "ClosedDoor"); // . = Floor // # = Wall // C = ClosedDoor // O = OpenDoor // M = Monster // P = Player // // 3|.#P. // 2|##O# // 1|.C.. // 0|.#.M // +---- // 0123 var tiles = ImmutableGrid <Tile> .CreateBuilder(Size.Create(4, 4)) .Set(0, 0, Floor) .Set(0, 1, Wall) .Set(0, 2, Floor) .Set(0, 3, Floor) .Set(1, 0, Wall) .Set(1, 1, ClosedDoor) .Set(1, 2, Wall) .Set(1, 3, Wall) .Set(2, 0, Wall) .Set(2, 1, Wall) .Set(2, 2, OpenDoor) .Set(2, 3, Wall) .Set(3, 0, Floor) .Set(3, 1, Wall) .Set(3, 2, Floor) .Set(3, 3, Floor) .Build(); Level = Level .Create(tiles, ImmutableDictionary <long, ActorState> .Empty) .SpawnActor(Monster, Vector.Create(0, 3)) .SpawnActor(Player, Vector.Create(3, 2)); }
public static Level Create(Size size) { var walker = from x in Enumerable.Range(0, size.Width) from y in Enumerable.Range(0, size.Height) select Vector.Create(x, y); var gridBuilder = ImmutableGrid <Tile> .CreateBuilder(size); walker.ForEach(location => gridBuilder.Set(location, Tile.Void)); return(new Level( gridBuilder.Build(), ImmutableDictionary <long, ActorState> .Empty)); }
public void TestCreateIsVisible(Vector location, bool expected) { var min = Vector.Create(5, 5); var max = Vector.Create(15, 15); Func <Vector, Vector> mapper = vector => Vector.Create(vector.X - min.X, vector.Y - min.Y); var viewPort = ImmutableGrid <bool> .CreateBuilder(max.X - min.X + 1, max.Y - min.Y + 1) .Set(5, 5, true) .Build(); var isVisible = LineOfSight .CreateIsVisible(min, max, mapper, viewPort)(location); Assert.AreEqual(expected, isVisible); }
public static Func <Vector, bool> CalculateVisibleRegion( this Vector location, int radius, Func <Vector, bool> blocksLineOfSight) { // Not as fast as a shadowcast because we visit tiles closer // to location multiple times when ray casting out from // location to each target. The cost is worth it as we are // sure what players/monsters can target matches what the // player can see as built on the same ray cast. var min = location + (Directions.SouthWest * radius); var max = location + (Directions.NorthEast * radius); var viewPortStorage = ImmutableGrid <bool> .CreateBuilder(max.X - min.X + 1, max.Y - min.Y + 1); Func <Vector, Vector> viewPortMapper = vector => Vector.Create(vector.X - min.X, vector.Y - min.Y); Func <Vector, IEnumerable <Vector> > castRay = endPoint => CastRay(location, endPoint, true, true) .Where(point => location.DistanceFrom(point) < radius); Action <IEnumerable <Vector> > traceRay = ray => { ray.Until( rayPoint => { viewPortStorage.Set(viewPortMapper(rayPoint), true); return(blocksLineOfSight(rayPoint)); }); }; RayEndPoints(min, max).Select(castRay).ForEach(traceRay); return(CreateIsVisible( min, max, viewPortMapper, viewPortStorage.Build())); }
public void ReadPerformance() { const int width = 150; const int height = 150; var grid = new int[width, height]; var immutableGrid = ImmutableGrid <int> .Create(width, height); var gridTime = BenchmarkHelper( width, height, (x, y) => { var cell = grid[x, y]; }); var immutableGridTime = BenchmarkHelper( width, height, (x, y) => { var cell = immutableGrid[x, y]; }); var factor = immutableGridTime / gridTime; #if DEBUG Assert.IsTrue(factor < 5, "Factor was " + factor); #else Assert.IsTrue(factor < 2, "Factor was " + factor); #endif }
public void WritePerformanceBuilder() { const int width = 150; const int height = 150; var grid = new int[width, height]; var immutableGrid = ImmutableGrid <int> .CreateBuilder(width, height); var gridTime = BenchmarkHelper( width, height, (x, y) => grid[x, y] = x + y); var immutableGridTime = BenchmarkHelper( width, height, (x, y) => immutableGrid.Set(x, y, x + y)); var factor = immutableGridTime / gridTime; #if DEBUG Assert.IsTrue(factor < 5, "Factor was " + factor); #else Assert.IsTrue(factor < 4, "Factor was " + factor); #endif }