예제 #1
0
        public void SenseMapCurrentHash()
        {
            var map      = BoxResMap(50, 50);
            var senseMap = new SenseMap(map);

            senseMap.AddSenseSource(new SenseSource(SourceType.RIPPLE, (20, 20), 10, Radius.CIRCLE));

            senseMap.Calculate();

            // Inefficient copy but fine for testing
            HashSet <Coord> currentSenseMap = new HashSet <Coord>(senseMap.CurrentSenseMap);

            for (int x = 0; x < map.Width; x++)
            {
                for (int y = 0; y < map.Height; y++)
                {
                    if (senseMap[x, y] > 0.0)
                    {
                        Assert.AreEqual(true, currentSenseMap.Contains((x, y)));
                    }
                    else
                    {
                        Assert.AreEqual(false, currentSenseMap.Contains((x, y)));
                    }
                }
            }
        }
예제 #2
0
        public void RippleCircleValue()
        {
            int    MAP_SIZE   = 30;
            int    RADIUS     = 10;
            Radius RAD_TYPE   = Radius.CIRCLE;
            Coord  SOURCE_POS = Coord.Get(15, 15);

            BoxResMap resMap   = new BoxResMap(MAP_SIZE, MAP_SIZE);
            SenseMap  senseMap = new SenseMap(resMap);

            var source = new SenseSource(SourceType.RIPPLE, SOURCE_POS, RADIUS, RAD_TYPE);

            senseMap.AddSenseSource(source);

            senseMap.Calculate();

            Console.WriteLine("Map on 10x10, light source at (2, 3), 3 circle radius, using ripple is: ");
            for (int x = 0; x < MAP_SIZE; x++)
            {
                for (int y = 0; y < MAP_SIZE; y++)
                {
                    Console.Write($"{senseMap[x, y].ToString("N4")} ");
                }
                Console.WriteLine();
            }
        }
예제 #3
0
        public void GlobalSetupSingleSource()
        {
            CreateSenseMap();

            // Create single source at center
            var source = new SenseSource(SourceAlgo, _senseMap.Bounds().Center, SourceRadius, (Radius)SourceShape);

            _senseMap.AddSenseSource(source);
        }
예제 #4
0
        public void EqualLargeMap()
        {
            var testResMap = TestResMap(17, 17);
            var testFOVMap = new LambdaTranslationMap <double, bool>(testResMap, d => d >= 1.0 ? false : true);

            testResMap[8, 8] = 0.0;             // Make sure start is free
            var myFov      = new FOV(testFOVMap);
            var myLighting = new SenseMap(testResMap);

            // Circle at 8, 8; radius 7
            myLighting.AddSenseSource(new SenseSource(SourceType.SHADOW, (8, 8), 7, Radius.CIRCLE));
            myFov.Calculate(8, 8, 7, Radius.CIRCLE);
            myLighting.Calculate();
            Console.WriteLine("LOS: ");
            for (int x = 0; x < testResMap.Width; x++)
            {
                for (int y = 0; y < testResMap.Height; y++)
                {
                    Console.Write($"{myFov[x, y].ToString("N2")}\t");
                }
                Console.WriteLine();
            }
            Console.WriteLine("\nLighting:");
            for (int x = 0; x < testResMap.Width; x++)
            {
                for (int y = 0; y < testResMap.Height; y++)
                {
                    Console.Write($"{myLighting[x, y].ToString("N2")}\t");
                }
                Console.WriteLine();
            }
            for (int x = 0; x < testResMap.Width; x++)
            {
                for (int y = 0; y < testResMap.Height; y++)
                {
                    System.Console.WriteLine($"We have ({x},{y}) fov {myFov[x, y]}, lighting {myLighting[(x, y)]}");
                    Assert.AreEqual(myFov[x, y], myLighting[x, y]);                     // Both got the same results
                }
            }
        }
예제 #5
0
        public void CircleRadius()
        {
            var testFOVMap = EmptyFOVMap(17, 17);
            var testResMap = new LambdaTranslationMap <bool, double>(testFOVMap, b => 0.0);
            var myFov      = new FOV(testFOVMap);
            var myLighting = new SenseMap(testResMap);

            // Circle at 8, 8; radius 7

            myLighting.AddSenseSource(new SenseSource(SourceType.SHADOW, (8, 8), 7, Radius.CIRCLE));
            myFov.Calculate(8, 8, 7, Radius.CIRCLE);
            myLighting.Calculate();
            for (int x = 0; x < testResMap.Width; x++)
            {
                for (int y = 0; y < testResMap.Height; y++)
                {
                    Console.Write(myLighting[x, y].ToString("0.00") + " ");
                    Assert.AreEqual(myFov[x, y], myLighting[x, y]);                     // Both got the same results
                }
                Console.WriteLine();
            }
        }
예제 #6
0
        private bool testSenseMap(SourceType algorithm, Radius shape)
        {
            var map = rectResMap(MAP_WIDTH, MAP_HEIGHT);

            // Start out at false
            bool[,] radiusMap = new bool[MAP_WIDTH, MAP_HEIGHT];
            bool[,] losMap    = new bool[MAP_WIDTH, MAP_HEIGHT];

            var los         = new SenseMap(map);
            var lightSource = new SenseSource(algorithm, CENTER, RADIUS_LEGNTH, shape);

            los.AddSenseSource(lightSource);
            los.Calculate();

            for (int x = 0; x < MAP_WIDTH; x++)
            {
                for (int y = 0; y < MAP_HEIGHT; y++)
                {
                    if (los[x, y] > 0)
                    {
                        losMap[x, y] = true;
                    }
                }
            }

            var radArea = new RadiusAreaProvider(CENTER, RADIUS_LEGNTH, shape);

            foreach (var pos in radArea.CalculatePositions())
            {
                radiusMap[pos.X, pos.Y] = true;
            }

            Console.WriteLine("Radius Shape: ");
            printArray(radiusMap);

            Console.WriteLine("LOS Shape: ");
            printArray(losMap);

            return(equivalentArrays(radiusMap, losMap));
        }
예제 #7
0
        public void ManualPrintSenseMap()
        {
            var map = new ArrayMap <bool>(30, 30);

            QuickGenerators.GenerateRectangleMap(map);

            var resMap   = new ResMap(map);
            var senseMap = new SenseMap(resMap);

            var source  = new SenseSource(SourceType.SHADOW, 12, 15, 10, Radius.CIRCLE);
            var source2 = new SenseSource(SourceType.SHADOW, 18, 15, 10, Radius.CIRCLE);

            senseMap.AddSenseSource(source);
            senseMap.AddSenseSource(source2);

            senseMap.Calculate();

            Console.WriteLine(senseMap);
            Console.WriteLine();
            Console.WriteLine(senseMap.ToString(3));
            Console.WriteLine();
            Console.WriteLine(source);
        }
예제 #8
0
        public void FOVSenseMapEquivalency()
        {
            ArrayMap <bool> map = new ArrayMap <bool>(100, 100);

            QuickGenerators.GenerateRectangleMap(map);

            var positions = Enumerable.Range(0, 100).Select(x => map.RandomPosition(true)).ToList();

            // Make 2-layer thick walls to verify wall-lighting is working properly
            foreach (var pos in map.Positions())
            {
                if (pos.X == 1 || pos.Y == 1 || pos.X == map.Width - 2 || pos.Y == map.Height - 2)
                {
                    map[pos] = false;
                }
            }

            var fov         = new FOV(map);
            var senseMap    = new SenseMap(new LambdaTranslationMap <bool, double>(map, x => x ? 0.0 : 1.0));
            var senseSource = new SenseSource(SourceType.SHADOW, map.RandomPosition(true), 5, Distance.EUCLIDEAN);

            senseMap.AddSenseSource(senseSource);


            foreach (var curPos in positions)
            {
                if (!map[curPos])
                {
                    continue;
                }

                senseSource.Position = curPos;
                fov.Calculate(senseSource.Position, senseSource.Radius, senseSource.DistanceCalc);
                senseMap.Calculate();

                foreach (var pos in map.Positions())
                {
                    bool success = fov.BooleanFOV[pos] == (senseMap[pos] > 0.0 ? true : false);

                    if (!success)
                    {
                        Console.WriteLine($"Failed on pos {pos} with source at {senseSource.Position}.");
                        Console.WriteLine($"FOV: {fov[pos]}, SenseMap: {senseMap[pos]}");
                        Console.WriteLine($"Distance between source and fail point: {Distance.EUCLIDEAN.Calculate(senseSource.Position, pos)}, source radius: {senseSource.Radius}");
                    }

                    Assert.AreEqual(true, success);
                }
            }


            var degreesList = Enumerable.Range(0, 360).ToList();

            degreesList.FisherYatesShuffle();
            var spanList = Enumerable.Range(1, 359).ToList();

            spanList.FisherYatesShuffle();

            var degrees = degreesList.Take(30).ToList();
            var spans   = spanList.Take(30).ToList();

            senseSource.IsAngleRestricted = true;
            // Test angle-based shadowcasting
            foreach (var curPos in positions.Take(1))
            {
                if (!map[curPos])
                {
                    continue;
                }

                foreach (var degree in degrees)
                {
                    foreach (var span in spans)
                    {
                        senseSource.Angle = degree;
                        senseSource.Span  = span;

                        senseSource.Position = curPos;
                        fov.Calculate(senseSource.Position, senseSource.Radius, senseSource.DistanceCalc, senseSource.Angle, senseSource.Span);
                        senseMap.Calculate();

                        foreach (var pos in map.Positions())
                        {
                            bool success = fov.BooleanFOV[pos] == (senseMap[pos] > 0.0 ? true : false);

                            if (!success)
                            {
                                Console.WriteLine($"Failed on pos {pos} with source at {senseSource.Position}, angle: {senseSource.Angle}, span: {senseSource.Span}.");
                                Console.WriteLine($"FOV: {fov[pos]}, SenseMap: {senseMap[pos]}");
                                Console.WriteLine($"Distance between source and fail point: {Distance.EUCLIDEAN.Calculate(senseSource.Position, pos)}, source radius: {senseSource.Radius}");
                            }

                            Assert.AreEqual(true, success);
                        }
                    }
                }
            }
        }