public void AttachingAMonstor_WillReduceItsHitPoints()
        {
            var state = MeleeWeapon.FormatState("Wooden Club", "Me1", 1, 12, -1, 1, 7.5, 0, 50);

            var testNum           = 1;
            var fakeRandomNumbers = GetGenerator(testNum);
            var registry          = new DispatchRegistry();
            var dispatcher        = new Dispatcher(registry);
            var fakeLogger        = new FakeLogger(_output);
            var mazeDescriptor    = FakeMazeDescriptorBuilder.Build(1, 1, 4, 2);

            var builder = new LevelBuilder(fakeRandomNumbers, mazeDescriptor, fakeLogger, dispatcher, registry);

            builder.Build(testNum);

            var me = ActorBuilder.Build <Me>(Coordinate.NotSet, registry, Me.FormatState(10, 10));

            dispatcher.EnqueueTeleport(me);
            var monster = ActorBuilder.Build <Monster>(Coordinate.NotSet, registry, Monster.FormatState(10, 10));

            dispatcher.EnqueueTeleport(monster);
            dispatcher.Dispatch();

            var weapon = new MeleeWeapon(fakeRandomNumbers, registry, dispatcher, state);

            dispatcher.EnqueueUse(weapon, Compass8Points.East);
            dispatcher.Dispatch();

            monster = (Monster)registry.GetDispatchee(monster.UniqueId);
            var expected = "HitPoints [7], ArmourClass [10]";
            var actual   = $"HitPoints [{monster.HitPoints}], ArmourClass [{monster.ArmourClass}]";

            Assert.Equal(expected, actual);
        }
Ejemplo n.º 2
0
        public void Move_Me_CanMoveIntoEmptySpace()
        {
            var testNum    = 1;
            var registry   = new DispatchRegistry();
            var dispatcher = new Dispatcher(registry);

            var fakeRandomNumbers = GetGenerator(testNum);
            var fakeLogger        = new FakeLogger(_output);
            var mazeDescriptor    = FakeMazeDescriptorBuilder.Build(1, 1, 4, 2);

            var builder = new LevelBuilder(fakeRandomNumbers, mazeDescriptor, fakeLogger, dispatcher, registry);

            builder.Build(GetLevel(testNum));
            var me = ActorBuilder.Build <Me>(Coordinate.NotSet, registry, Me.FormatState(10, 10));

            dispatcher.EnqueueTeleport(me);
            dispatcher.Dispatch();

            // t+1
            dispatcher.EnqueueMove(me, Compass8Points.South);
            dispatcher.Dispatch();

            var expected = GetExpectation(testNum);
            var actual   = registry.GetDispatchee("Maze1").ToString();

            _output.WriteLine(expected);
            _output.WriteLine('='.ToPaddedString(10));
            _output.WriteLine(actual);

            Assert.Equal(expected, actual);
        }
        public void WhenBuiltDispatcher_ShouldHaveMeInMaze(int testNum, int blocksPerTile)
        {
            var registry   = new DispatchRegistry();
            var dispatcher = new Dispatcher(registry);

            var fakeRandomNumbers = GetGenerator(testNum);
            var fakeLogger        = new FakeLogger(_output);
            var mazeDescriptor    = FakeMazeDescriptorBuilder.Build(1, 1, 4, blocksPerTile);

            var builder = new LevelBuilder(fakeRandomNumbers, mazeDescriptor, fakeLogger, dispatcher, registry);

            builder.Build(testNum);
            var me = new Me(Coordinate.NotSet, registry, Me.FormatState(10, 10));

            dispatcher.EnqueueTeleport(me);
            dispatcher.Dispatch();

            var maze   = registry.GetDispatchee("Maze1");
            var actual = maze.ToString();

            var expected = GetExpectation(testNum);

            _output.WriteLine(expected);
            _output.WriteLine('='.ToPaddedString(10));
            _output.WriteLine(actual);

            Assert.Equal(expected, actual);
        }
Ejemplo n.º 4
0
        public static T Build <T>(Coordinate coordinate, DispatchRegistry registry, string state)
            where T : IDispatchee, ICloner <T>
        {
            var type = typeof(T);

            return(Build <T>(type, coordinate, registry, state));
        }
Ejemplo n.º 5
0
        internal static Tiles ConnectDoors(this Tiles tilesWithUnconnectedDoors, DispatchRegistry registry)
        {
            IList <Door> GetDoors()
            {
                var doorNames = tilesWithUnconnectedDoors.GetTilesOfType <Door>();

                return(doorNames.Select(registry.GetDispatchee)
                       .Cast <Door>()
                       .ToList());
            }

            var doors = GetDoors();

            var tilesWithConnectedDoors = tilesWithUnconnectedDoors;

            while (doors.Count > 0)
            {
                var firstDoor      = doors.First();
                var doorsToConnect = doors.Where(door => door.DoorId == firstDoor.DoorId).ToList();
                doorsToConnect.Count.ThrowIfNotEqual(2, "doorsToConnect.Count");

                var first  = doorsToConnect[0];
                var second = doorsToConnect[1];

                tilesWithConnectedDoors = ConnectDoors(tilesWithConnectedDoors, first, second, registry);
                doorsToConnect.ForEach(door => doors.Remove(door));
            }

            return(tilesWithConnectedDoors);
        }
Ejemplo n.º 6
0
        public void PlaceDoor_InRectangularTestRooms(StandardTestRoom testRoom)
        {
            var fakeRandomNumbers = new FakeRandomNumberGenerator();

            void SetupStandardRoom()
            {
                fakeRandomNumbers.PopulateRandomForTestRoom(testRoom)
                ;
            }

            void SetupDoorForStandardRoom()
            {
                fakeRandomNumbers
                .AddCoordinates(0, 0)               // Door placement, top left corner, will try again
                .AddCoordinates(9, 0)               // Door placement, btm left corner, will try again
                .AddCoordinates(9, 5)               // Door placement, btm right corner, will try again
                .AddCoordinates(0, 5)               // Door placement, top right corner, will try again
                .AddCoordinates(0, 3)               // Door placement, vertical wall, will try again
                .AddCoordinates(4, 0)               // Door placement, horizontal wall, will try again
                .AddCoordinates(4, 3)               // Door placement, vertical wall to start walk from
                .AddDirection(Compass8Points.North) // direction to walk to find a wall and place a door
                .AddCoordinates(4, 3)               // Door placement, vertical wall to start walk from
                .AddDirection(Compass8Points.East)  // direction to walk to find a wall and place a door
                .AddCoordinates(4, 3)               // Door placement, vertical wall to start walk from
                .AddDirection(Compass8Points.South) // direction to walk to find a wall and place a door
                .AddCoordinates(4, 3)               // Door placement, vertical wall to start walk from
                .AddDirection(Compass8Points.West)  // direction to walk to find a wall and place a door
                ;
            }

            var registry = new DispatchRegistry();

            SetupStandardRoom();
            SetupDoorForStandardRoom();

            var fakeLogger = new FakeLogger(_output);

            var builder = new RoomBuilder(fakeRandomNumbers, fakeLogger, registry);

            var mazeDescriptor = FakeMazeDescriptorBuilder.MazeRoomsWithTwoBlocks();
            var detail         = mazeDescriptor[1];
            var room           = builder.BuildRoom(detail.BlocksPerRoom, detail.TilesPerBlock);

            room = room.AddDoor(1);
            room = room.AddDoor(2);
            room = room.AddDoor(3);
            room = room.AddDoor(4);

            var expected = GetExpectationForTestRoom(testRoom);
            var actual   = room.ToString();

            _output.WriteLine('='.ToPaddedString(10));
            _output.WriteLine(expected);
            _output.WriteLine('='.ToPaddedString(10));
            _output.WriteLine(actual);
            _output.WriteLine('='.ToPaddedString(10));

            Assert.Equal(expected, actual);
        }
Ejemplo n.º 7
0
        public static IDispatchee Build(char actor, Coordinate coordinate, DispatchRegistry registry)
        {
            if (ActorBuilderMethods.TryGetValue(actor, out var builder))
            {
                return(builder(actor, coordinate, registry));
            }

            throw new ArgumentException($"Unable to find Actor Builder for [{actor}]");
        }
Ejemplo n.º 8
0
        internal Maze(DispatchRegistry registry, IRandomNumberGenerator randomNumbers, int rows, int columns)
            : base(Coordinate.NotSet, registry)
        {
            randomNumbers.ThrowIfNull(nameof(randomNumbers));

            _randomNumbers = randomNumbers;

            _tiles = new Tiles.Tiles(rows, columns, Registry, _randomNumbers);
        }
Ejemplo n.º 9
0
        internal Room(RoomBlocks blocks, DispatchRegistry registry, IRandomNumberGenerator randomNumbers, int tilesPerBlock)
            : base(Coordinate.NotSet, registry)
        {
            blocks.ThrowIfNull(nameof(blocks));
            randomNumbers.ThrowIfNull(nameof(randomNumbers));

            _randomNumbers = randomNumbers;

            Tiles = new RoomTiles(blocks.RowUpperBound, blocks.ColumnUpperBound, tilesPerBlock, Registry, _randomNumbers);
        }
Ejemplo n.º 10
0
        public RoomBuilder(IRandomNumberGenerator randomNumberGenerator, ILog logger, DispatchRegistry registry)
        {
            randomNumberGenerator.ThrowIfNull(nameof(randomNumberGenerator));
            logger.ThrowIfNull(nameof(logger));
            registry.ThrowIfNull(nameof(registry));

            _randomNumberGenerator = randomNumberGenerator;
            _logger   = logger;
            _registry = registry;
        }
Ejemplo n.º 11
0
        public static T Build <T>(Type type, Coordinate coordinate, DispatchRegistry registry, string state)
            where T : IDispatchee, ICloner <T>
        {
            if (TypeBuilderMethods.TryGetValue(type, out var builder))
            {
                return((T)builder(coordinate, registry, state));
            }

            throw new TypeInitializationException(typeof(T).FullName, null);
        }
Ejemplo n.º 12
0
        public RoomTiles(int blockRows, int blockColumns, int tilesPerBlock, DispatchRegistry registry, IRandomNumberGenerator randomNumbers)
            : base((blockRows + 1) * tilesPerBlock + 2, (blockColumns + 1) * tilesPerBlock + 2, registry, randomNumbers)
        {
            randomNumbers.ThrowIfNull(nameof(randomNumbers));
            registry.ThrowIfNull(nameof(registry));
            blockRows.ThrowIfBelow(0, nameof(blockRows));
            blockColumns.ThrowIfBelow(0, nameof(blockColumns));
            tilesPerBlock.ThrowIfBelow(1, nameof(tilesPerBlock));

            TilesPerBlock = tilesPerBlock;
        }
Ejemplo n.º 13
0
        internal static IDispatchee GetDispatchee(this Tiles tiles, Coordinate coordinates,
                                                  DispatchRegistry registry)
        {
            if (!tiles.IsInside(coordinates) || tiles.IsEmptyTile(coordinates))
            {
                return(null);
            }

            var uniqueId = tiles[coordinates];

            return(registry.GetDispatchee(uniqueId));
        }
Ejemplo n.º 14
0
        public MeleeWeapon(IRandomNumberGenerator randomNumbers, DispatchRegistry registry, Dispatcher dispatcher, string state)
            : base(Coordinate.NotSet, registry)
        {
            randomNumbers.ThrowIfNull(nameof(randomNumbers));
            dispatcher.ThrowIfNull(nameof(dispatcher));

            _randomNumbers = randomNumbers;
            _dispatcher    = dispatcher;

            var parameters = state.ToParameters();

            UpdateState(this, parameters);
        }
Ejemplo n.º 15
0
        public MazeBuilder(IRandomNumberGenerator randomNumberGenerator, RoomBuilder roomBuilder, IMazeDescriptor descriptor, ILog logger, DispatchRegistry registry)
        {
            randomNumberGenerator.ThrowIfNull(nameof(randomNumberGenerator));
            roomBuilder.ThrowIfNull(nameof(roomBuilder));
            descriptor.ThrowIfNull(nameof(descriptor));
            logger.ThrowIfNull(nameof(logger));
            registry.ThrowIfNull(nameof(registry));

            _randomNumberGenerator = randomNumberGenerator;
            _roomBuilder           = roomBuilder;
            _descriptor            = descriptor;
            _logger   = logger;
            _registry = registry;
        }
        public void BuildTilesFromInputString(int testNumber)
        {
            var input             = GetInputString(testNumber);
            var registry          = new DispatchRegistry();
            var fakeRandomNumbers = new FakeRandomNumberGenerator();
            var tiles             = TilesBuilder.BuildTiles(input, registry, fakeRandomNumbers);

            var actual   = tiles.ToString();
            var expected = GetExpectedTiles(testNumber);

            _output.WriteLine('='.ToPaddedString(10));
            _output.WriteLine(expected);
            _output.WriteLine('='.ToPaddedString(10));
            _output.WriteLine(actual);
            _output.WriteLine('='.ToPaddedString(10));

            Assert.Equal(expected, actual);
        }
        public void BuildRoom_ShouldBuildARoom_WithWalls(StandardTestRoom testRoom)
        {
            var fakeRandomNumbers = new FakeRandomNumberGenerator().PopulateRandomForTestRoom(testRoom);
            var registry          = new DispatchRegistry();
            var builder           = new RoomBuilder(fakeRandomNumbers, new FakeLogger(_output), registry);

            var room   = builder.BuildRoom(GetNumBlocks(testRoom), 4);
            var actual = room.ToString();

            var expected = StandardTestRooms.GetExpectation(testRoom);

            _output.WriteLine('='.ToPaddedString(10));
            _output.WriteLine("Test Room " + testRoom);
            _output.WriteLine(expected);
            _output.WriteLine('='.ToPaddedString(10));
            _output.WriteLine(actual);

            Assert.Equal(expected, actual);
        }
        internal static Tiles PositionRoomsInTiles(this Tiles tiles, DispatchRegistry registry, IEnumerable <Room> rooms)
        {
            var tilesWithRooms = tiles;

            foreach (var room in rooms)
            {
                var roomIsPositioned = false;

                var tilesChange = new List <(string Name, Coordinate coordinates)>();
                while (!roomIsPositioned)
                {
                    var(topLeft, topRight, bottomLeft, bottomRight) = AttemptToPositionRoomInsideTiles(tilesWithRooms, room);

                    var bigEnough = AreTilesBigEnough(topLeft, topRight, bottomLeft, bottomRight);
                    if (!bigEnough)
                    {
                        tilesWithRooms = Tiles.Grow(tilesWithRooms);
                        continue;
                    }

                    if (IsTooCloseToEdge(tilesWithRooms, topLeft, topRight, bottomLeft, bottomRight))
                    {
                        continue;
                    }
                    if (IsTooCloseToARoom(tilesWithRooms, topLeft, topRight, bottomLeft, bottomRight))
                    {
                        continue;
                    }

                    var changes = PositionRoom(room, registry, topLeft, topRight, bottomLeft);
                    tilesChange.AddRange(changes);
                    roomIsPositioned = true;
                }

                var changedTileState = tilesChange.ToTilesState();
                tilesWithRooms = tilesWithRooms.Clone(changedTileState);
            }

            return(tilesWithRooms);
        }
Ejemplo n.º 19
0
        private static Tiles BuildTilesRegistry(string inputTiles, DispatchRegistry registry,
                                                IRandomNumberGenerator randomNumbers)
        {
            string[] ExtractLines()
            {
                var newLineChars = Environment.NewLine.ToCharArray();

                return(inputTiles.Split(newLineChars));
            }

            IEnumerable <string> RemoveEmptyStrings(string[] lines)
            {
                return(lines.Where(line => !string.IsNullOrWhiteSpace(line)));
            }

            (int MaxRows, int MaxColumns) GetUpperBounds(List <string> lines)
            {
                int maxRow     = lines.Count;
                var maxColumns = lines.Max(line => line.Length);

                return(maxRow, maxColumns);
            }

            var linesWithBlanks = ExtractLines();
            var linesToProcess  = RemoveEmptyStrings(linesWithBlanks).ToList();

            var stateChange = StateChangeForInput(registry, linesToProcess);

            var(rows, columns) = GetUpperBounds(linesToProcess);

            var tiles      = new Tiles(rows, columns, registry, randomNumbers);
            var tilesState = stateChange.ToTilesState();

            tiles = tiles.Clone(tilesState);

            return(tiles);
        }
Ejemplo n.º 20
0
        private static TilesChange StateChangeForInput(DispatchRegistry registry, IList <string> lines)
        {
            var tilesChanged = new TilesChange();

            var row = 0;

            foreach (var line in lines)
            {
                var column = 0;
                foreach (var actorChar in line)
                {
                    var coordinates = new Coordinate(row, column);
                    var actor       = ActorBuilder.Build(actorChar, coordinates, registry);

                    tilesChanged.Add((actor?.UniqueId, coordinates));

                    column++;
                }

                row++;
            }

            return(tilesChanged);
        }
Ejemplo n.º 21
0
 public Monster(Coordinate coordinate, DispatchRegistry registry, string state) 
     : base(coordinate, registry, state)
 {
 }
Ejemplo n.º 22
0
 internal Rock(Coordinate coordinate, DispatchRegistry registry, string _) : base(coordinate, registry)
 {
 }
Ejemplo n.º 23
0
        public static Tiles BuildTiles(string inputTiles, DispatchRegistry registry, IRandomNumberGenerator randomNumbers)
        {
            var tiles = BuildTilesRegistry(inputTiles, registry, randomNumbers);

            return(tiles);
        }
Ejemplo n.º 24
0
        public void PlaceTwoRooms_WhereFirstAndSecondDoNotOverlap()
        {
            var fakeRandomNumbers = new FakeRandomNumberGenerator();

            void SetupTwoRooms()
            {
                fakeRandomNumbers
                .PopulateRandomForRoomCount(2)
                .PopulateRandomForTestRoom(StandardTestRoom.First)
                .PopulateRandomForTestRoom(StandardTestRoom.First)
                ;
            }

            void SetupDoors()
            {
                fakeRandomNumbers
                .AddCoordinates(2, 2)              // Door placement, empty tile to start walk from
                .AddDirection(Compass8Points.West) // direction to walk to find a wall and place a door
                .AddCoordinates(3, 3)              // Door placement, empty tile to start walk from
                .AddDirection(Compass8Points.East) // direction to walk to find a wall and place a door
                ;
            }

            void SetupCoordinatesForPlacingFirstRoom()
            {
                fakeRandomNumbers
                .AddCoordinates(1, 1)     // too close to edge of maze, should fail
                .AddCoordinates(2, 2)     // too close to edge of maze, should fail
                .AddCoordinates(3, 3)     // should succeed
                ;
            }

            void SetupCoordinatesForPlacingSecondRoom()
            {
                fakeRandomNumbers
                .AddCoordinates(4, 4)     // overlaps first so should fail
                .AddCoordinates(6, 6)     // too near first so should fail
                .AddCoordinates(17, 10)   // does not overlap and not close so should succeed
                ;
            }

            var registry   = new DispatchRegistry();
            var dispatcher = new Dispatcher(registry);

            SetupTwoRooms();
            SetupDoors();
            SetupCoordinatesForPlacingFirstRoom();
            SetupCoordinatesForPlacingSecondRoom();

            var fakeLogger     = new FakeLogger(_output);
            var mazeDescriptor = FakeMazeDescriptorBuilder.MazeRoomsWithTwoBlocks();

            var builder = new LevelBuilder(fakeRandomNumbers, mazeDescriptor, fakeLogger, dispatcher, registry);

            builder.Build(1, connectTunnels: false);

            var expected     = GetExpectation(1);
            var actual       = (Maze)registry.GetDispatchee("Maze1");
            var actualString = actual.ToString();

            _output.WriteLine('='.ToPaddedString(10));
            _output.WriteLine(expected);
            _output.WriteLine('='.ToPaddedString(10));
            _output.WriteLine(actualString);
            _output.WriteLine('='.ToPaddedString(10));

            Assert.Equal(expected, actualString);
        }
Ejemplo n.º 25
0
        protected Character(Coordinate coordinates, DispatchRegistry registry, string state) : base(coordinates, registry)
        {
            var extracted = state.ToParameters();

            UpdateState(this as T, extracted);
        }
Ejemplo n.º 26
0
 private Maze(DispatchRegistry registry, IRandomNumberGenerator randomNumbers, Tiles.Tiles tiles) : base(Coordinate.NotSet, registry)
 {
     _randomNumbers = randomNumbers;
     _tiles         = tiles.Clone();
 }
        private static IList <(string Name, Coordinate coordinates)> PositionRoom(Room room, DispatchRegistry registry,
                                                                                  Coordinate topLeft, Coordinate topRight, Coordinate bottomLeft)
        {
            var rows    = bottomLeft.Row - topLeft.Row;
            var columns = topRight.Column - topLeft.Column;

            var tileChanges = new List <(string Name, Coordinate coordinates)>();

            for (var row = 0; row <= rows; row++)
            {
                for (var column = 0; column <= columns; column++)
                {
                    var roomCoordinates = new Coordinate(row, column);
                    var roomTileName    = room.Tiles[roomCoordinates];
                    var mazeCoordinates = topLeft + roomCoordinates;

                    (string Name, Coordinate Coordinates)tile = (null, mazeCoordinates);
                    if (!roomTileName.IsNullOrEmpty())
                    {
                        var roomTile = registry.GetDispatchee(roomTileName);
                        var state    = Maze.FormatState(mazeCoordinates);
                        var mazeTile = roomTile.CloneDispatchee(state);
                        tile.Name = mazeTile.UniqueId;
                    }

                    tileChanges.Add(tile);
                }
            }

            return(tileChanges);
        }
Ejemplo n.º 28
0
        public void PlaceTwoRooms_WherePlacingTheSecondRoomCausesMazeToGrow()
        {
            var fakeRandomNumbers = new FakeRandomNumberGenerator();

            void SetupTwoRooms()
            {
                fakeRandomNumbers
                .PopulateRandomForRoomCount(2)
                .PopulateRandomForTestRoom(StandardTestRoom.Second)
                .PopulateRandomForTestRoom(StandardTestRoom.Second)
                ;
            }

            void SetupDoorForFirstRoom()
            {
                fakeRandomNumbers
                .AddCoordinates(0, 0)               // Door placement, should be empty tile to walk from, but it is a wall, top left corner
                .AddCoordinates(3, 3)               // Door placement, empty tile to start walk from
                .AddDirection(Compass8Points.South) // direction to walk to find a wall and place a door
                ;
            }

            void SetupDoorForSecondRoom()
            {
                fakeRandomNumbers
                .AddCoordinates(5, 9)               // Door placement, should be empty tile to walk from, but it is a wall, bottom right corner
                .AddCoordinates(4, 8)               // Door placement, empty tile to start walk from
                .AddDirection(Compass8Points.North) // direction to walk to find a wall and place a door
                ;
            }

            void SetupCoordinatesForPlacingFirstRoom()
            {
                fakeRandomNumbers
                .AddCoordinates(3, 3)     // should succeed
                ;
            }

            void SetupCoordinatesForPlacingSecondRoom()
            {
                fakeRandomNumbers
                .AddCoordinates(17, 15)     // placing room outside of maze
                .AddCoordinates(17, 15)     // placing room outside of maze
                .AddCoordinates(17, 15)     // placing room outside of maze, show grow after third attempt
                .AddCoordinates(17, 15)     // placing room outside of old maze, now inside new maze so succeeds
                ;
            }

            var registry   = new DispatchRegistry();
            var dispatcher = new Dispatcher(registry);

            SetupTwoRooms();
            SetupDoorForFirstRoom();
            SetupDoorForSecondRoom();
            SetupCoordinatesForPlacingFirstRoom();
            SetupCoordinatesForPlacingSecondRoom();

            var fakeLogger     = new FakeLogger(_output);
            var mazeDescriptor = FakeMazeDescriptorBuilder.MazeRoomsWithTwoBlocks();

            var builder = new LevelBuilder(fakeRandomNumbers, mazeDescriptor, fakeLogger, dispatcher, registry);

            builder.Build(1, connectTunnels: false);

            var expected     = GetExpectation(2);
            var actual       = (Maze)registry.GetDispatchee("Maze1");
            var actualString = actual.ToString();

            _output.WriteLine('='.ToPaddedString(10));
            _output.WriteLine(expected);
            _output.WriteLine('='.ToPaddedString(10));
            _output.WriteLine(actualString);
            _output.WriteLine('='.ToPaddedString(10));

            Assert.Equal(expected, actualString);
        }
        public static IDispatchee GetDispatchee(this ExtractedParameters parameters, string name, DispatchRegistry registry)
        {
            var value = parameters.ToString(name);

            return(registry.GetDispatchee(value));
        }
Ejemplo n.º 30
0
        internal Door(Coordinate coordinates, DispatchRegistry registry, string state) : base(coordinates, registry)
        {
            var doorId = int.Parse(state);

            DoorId = doorId;
        }