Пример #1
0
        public void Make(int Seed, String Filename)
        {
            System.Console.WriteLine("Generating Map [{0}]", Filename);
            Random Gen = new Random(Seed);

            xml.Version      = 1;
            xml.Date         = DateTime.Now;
            xml.Generator    = Generator.MAIDynamicRooms;
            xml.Seed         = Seed;
            xml.LOS          = LOS;
            xml.LOSSpecified = true;
            xml.Start        = new Coord( );
            xml.Goal         = new Coord( );
            if (UseCorners)
            {
                xml.Start.X = 0;
                xml.Start.Y = 0;
                xml.Goal.X  = xml.Width - 1;
                xml.Goal.Y  = xml.Height - 1;
            }
            else
            {
                double Dis;
                do
                {
                    xml.Start.X = Gen.Next(xml.Width);
                    xml.Start.Y = Gen.Next(xml.Height);
                    xml.Goal.X  = Gen.Next(xml.Width);
                    xml.Goal.Y  = Gen.Next(xml.Height);
                    Dis         = Distance.OctileDistance(xml.Start.X, xml.Goal.X, xml.Start.Y, xml.Goal.Y);
                } while (Dis < MinHDistance || Dis > MaxHDistance);
            }
            GenericGridWorldDynamicState DS = new GenericGridWorldDynamicState( );
            GenericGridWorldStaticState  SS = new GenericGridWorldStaticState(xml.Height, xml.Width, DS);

            DS.AddWorldObject(new Unit(xml.Start.X, xml.Start.Y,
                                       xml.Height, xml.Width, xml.Goal.X, xml.Goal.Y, LOS, 0));

            int RoomWidth  = xml.Width / this.NumHorzRooms;
            int RoomHeight = xml.Height / this.NumVertRooms;

            bool[,] TilesBlocked = new bool[xml.Width, xml.Height];

            for (int Y = 0; Y < xml.Height; Y++)
            {
                for (int X = 0; X < xml.Width; X++)
                {
                    SS.Tiles[Y][X] = new PassableTile <GenericGridWorldStaticState,
                                                       GenericGridWorldDynamicState>(X, Y, xml.Height, xml.Width);
                    TilesBlocked[X, Y] = false;
                }
            }

            // Vert Walls
            for (int Y = RoomHeight; Y < xml.Height; Y += RoomHeight)
            {
                for (int X = 0; X < xml.Width; X++)
                {
                    if (!(X == xml.Start.X && Y == xml.Start.Y) && !(Y == xml.Goal.Y && X == xml.Goal.X))
                    {
                        SS.Tiles[Y][X] = new BlockedTile <GenericGridWorldStaticState,
                                                          GenericGridWorldDynamicState>(X, Y, xml.Height, xml.Width);
                        TilesBlocked[X, Y] = true;
                    }
                }
            }
            // Horz Walls
            for (int X = RoomWidth; X < xml.Width; X += RoomWidth)
            {
                for (int Y = 0; Y < xml.Height; Y++)
                {
                    if (!(X == xml.Start.X && Y == xml.Start.Y) && !(Y == xml.Goal.Y && X == xml.Goal.X))
                    {
                        SS.Tiles[Y][X] = new BlockedTile <GenericGridWorldStaticState,
                                                          GenericGridWorldDynamicState>(X, Y, xml.Height, xml.Width);
                        TilesBlocked[X, Y] = true;
                    }
                }
            }

            List <Door> Doors = new List <Door>( );

            // Vert Doors
            for (int Y = RoomHeight; Y < xml.Height; Y += RoomHeight)
            {
                for (int X = RoomWidth / 2; X < xml.Width; X += RoomWidth)
                {
                    if (!(X == xml.Start.X && Y == xml.Start.Y) && !(Y == xml.Goal.Y && X == xml.Goal.X))
                    {
                        SS.Tiles[Y][X] = new PassableTile <GenericGridWorldStaticState,
                                                           GenericGridWorldDynamicState>(X, Y, xml.Height, xml.Width);
                        if ((X / RoomWidth) % VertRoomModifier == 0)
                        {
                            Doors.Add(new Door( )
                            {
                                Open = true, X = X, Y = Y
                            });
                            TilesBlocked[X, Y] = false;
                        }
                    }
                }
            }
            // Horz Doors
            for (int X = RoomWidth; X < xml.Width; X += RoomWidth)
            {
                for (int Y = RoomHeight / 2; Y < xml.Height; Y += RoomHeight)
                {
                    if (!(X == xml.Start.X && Y == xml.Start.Y) && !(Y == xml.Goal.Y && X == xml.Goal.X))
                    {
                        SS.Tiles[Y][X] = new PassableTile <GenericGridWorldStaticState,
                                                           GenericGridWorldDynamicState>(X, Y, xml.Height, xml.Width);
                        if ((Y / RoomHeight) % HorzRoomModifier == 0)
                        {
                            Doors.Add(new Door( )
                            {
                                Open = true, X = X, Y = Y
                            });
                            TilesBlocked[X, Y] = false;
                        }
                    }
                }
            }

            xml.Tiles = GridWorldFormat.ToTileString(SS, DS);

            try {
                var sol = new AStar <
                    GenericGridWorldStaticState, GenericGridWorldDynamicState>(
                    new SingleUnitOctileDistanceHeuristic( ), true, null)
                          .Compute(SS, SS.InitialDynamicState, new DestinationsReachedGoal( ),
                                   GridWorldOperator.Ops).First( );
                xml.OptimalSolutionCost          = sol.Cost.ToDouble( );
                xml.OptimalSolutionCostSpecified = true;
                if (!UseCorners && (xml.OptimalSolutionCost < MinAStarDistance ||
                                    xml.OptimalSolutionCost > MaxAStarDistance))
                {
                    throw new ChokepointGridWorldMaker.MapCreationFailed( );
                }
                System.Console.WriteLine("\tMap Generated Solution Cost [{0}]", sol.Cost);
            } catch (PathNotFoundException) {
                System.Console.WriteLine("\tMap Generation Failed [{0}]", Filename);
                throw new ChokepointGridWorldMaker.MapCreationFailed( );
            }

            List <Step> ChangeList = new List <Step>( );

            Step         step = new Step( );
            int          sN;
            List <Coord> Changes;
            List <Door>  DoorChanges;

            // Add one for skipped.
            step.StepNum = 0;
            step.Changes = new Coord[] { };
            ChangeList.Add(step);

            for (sN = 1; sN < NumSteps + 1; sN++)
            {
                step         = new Step( );
                step.StepNum = sN;
                do
                {
                    Changes     = new List <Coord>( );
                    DoorChanges = new List <Door>( );
                    foreach (Door D in Doors)
                    {
                        if (D.Open)
                        {
                            if (Gen.NextDouble( ) < ChanceClose)
                            {
                                D.Open = false;
                                Changes.Add(new Coord( )
                                {
                                    X = D.X, Y = D.Y
                                });
                                DoorChanges.Add(D);
                                TilesBlocked[D.X, D.Y] = true;
                            }
                        }
                        else
                        {
                            if (Gen.NextDouble( ) < ChanceOpen)
                            {
                                D.Open = true;
                                Changes.Add(new Coord( )
                                {
                                    X = D.X, Y = D.Y
                                });
                                DoorChanges.Add(D);
                                TilesBlocked[D.X, D.Y] = false;
                            }
                        }
                    }
                } while (!ResolveReachability(DoorChanges, Changes, TilesBlocked,
                                              new Point(xml.Goal.X, xml.Goal.Y), xml.Width, xml.Height));
                step.Changes = Changes.ToArray( );
                ChangeList.Insert(ChangeList.Count, step);
            }

            // Add one more step to guarentee repeatablity.
            step         = new Step( );
            step.StepNum = sN;

            Changes = new List <Coord>( );
            foreach (Door D in Doors)
            {
                if (!D.Open)
                {
                    Changes.Add(new Coord( )
                    {
                        X = D.X, Y = D.Y
                    });
                }
            }
            step.Changes = Changes.ToArray( );
            ChangeList.Insert(ChangeList.Count, step);

            xml.ChangeList              = new ChangeList( );
            xml.ChangeList.Repeatable   = true;
            xml.ChangeList.BlockOnAgent = false;
            xml.ChangeList.Steps        = ChangeList.ToArray( );
            System.Console.WriteLine("\tMap Generated [{0}]", Filename);
            XmlSerializer s = new XmlSerializer(typeof(Map));
            TextWriter    w = new StreamWriter(Filename);

            s.Serialize(w, xml);
            w.Close( );
        }
Пример #2
0
        public void Make(int Seed, String Filename)
        {
            System.Console.WriteLine("Generating Map [{0}]", Filename);
            Random Gen = new Random(Seed);

            xml.Version   = 1;
            xml.Date      = DateTime.Now;
            xml.Generator = Generator.MAIDynamicChokepoint;
            xml.Seed      = Seed;
            xml.LOS       = LOS;
            xml.Start     = new Coord( );
            xml.Start.X   = Gen.Next(xml.Width);
            xml.Start.Y   = Gen.Next(xml.Height);
            xml.Goal      = new Coord( );
            xml.Goal.X    = Gen.Next(xml.Width);
            xml.Goal.Y    = Gen.Next(xml.Height);
            GenericGridWorldDynamicState DS = new GenericGridWorldDynamicState( );
            GenericGridWorldStaticState  SS = new GenericGridWorldStaticState(xml.Height, xml.Width, DS);

            DS.AddWorldObject(new Unit(xml.Start.X, xml.Start.Y,
                                       xml.Height, xml.Width, xml.Goal.X, xml.Goal.Y, LOS, 0));

            bool[][] tiles = new bool[xml.Height][];
            for (int i = 0; i < xml.Height; i++)
            {
                tiles[i] = new bool[xml.Width];
            }

            LinkedList <Point> ChokePoints = new LinkedList <Point>( );

            for (int i = 0; i < NumChokepoints; i++)
            {
                ChokePoints.AddFirst(new Point(Gen.Next(xml.Width), Gen.Next(xml.Height)));
            }

            for (int Y = 0; Y < xml.Height; Y++)
            {
                for (int X = 0; X < xml.Width; X++)
                {
                    if (ChokePoints.Any(cp => Distance.OctileDistance(cp.X, X, cp.Y, Y) <= ChokepointRadius))
                    {
                        SS.Tiles[Y][X] = new ChokeTile <GenericGridWorldStaticState,
                                                        GenericGridWorldDynamicState>(X, Y, xml.Height, xml.Width);
                        tiles[Y][X] = false;
                    }
                    else
                    {
                        SS.Tiles[Y][X] = new PassableTile <GenericGridWorldStaticState,
                                                           GenericGridWorldDynamicState>(X, Y, xml.Height, xml.Width);
                        tiles[Y][X] = false;
                    }
                }
            }

            Point U = new Point(xml.Start.X, xml.Start.Y);

            foreach (var From in ChokePoints)
            {
                foreach (var To in ChokePoints)
                {
                    DrawLine(From, To, xml, SS, U, tiles);
                }
            }

            xml.Tiles = GridWorldFormat.ToTileString(SS, DS);

            try {
                var sol = new AStar <
                    GenericGridWorldStaticState, GenericGridWorldDynamicState>(
                    new SingleUnitOctileDistanceHeuristic( ), true, null)
                          .Compute(SS, SS.InitialDynamicState, new DestinationsReachedGoal( ),
                                   GridWorldOperator.Ops).First( );
                System.Console.WriteLine("\tMap Generated Solution Cost [{0}]", sol.Cost);
            } catch (PathNotFoundException) {
                System.Console.WriteLine("\tMap Generation Failed [{0}]", Filename);
                throw new MapCreationFailed( );
            }

            LinkedList <Point> AgentsLocs = new LinkedList <Point>(ChokePoints.Take(NumAgents));
            LinkedList <Agent> Agents     = new LinkedList <Agent>( );

            foreach (Point Loc in AgentsLocs)
            {
                Agents.AddFirst(new Agent( )
                {
                    Location = Loc, Dst = Loc, Start = Loc
                });
            }

            LinkedList <Step> ChangeList = new LinkedList <Step>( );

            for (int sN = 0; sN < NumSteps || !AllAtStart(Agents); sN++)
            {
                Step step = new Step( );
                step.StepNum = sN;
                List <Coord> Changes = new List <Coord>( );
                if (sN == 0)
                {
                    foreach (Agent Agent in Agents)
                    {
                        ToogleCircle(tiles, Agent.Location, AgentRadius, Changes, xml.Width, xml.Height,
                                     Agent.Location, Agents, AgentRadius, false);
                    }
                }

                foreach (Agent Agent in Agents)
                {
                    if (sN < NumSteps && sN != 0 && Agent.Location.Equals(Agent.Dst) && (Gen.NextDouble( ) < MoveRate))
                    {
                        var NotReserved = ChokePoints.Where(x => !Agents.Any(a => a.Dst.Equals(x)));
                        if (NotReserved.Count( ) > 0)
                        {
                            Agent.Dst = NotReserved.Skip(Gen.Next(NotReserved.Count( ))).First( );
                        }
                    }
                    else if (!(sN < NumSteps))
                    {
                        Agent.Dst = Agent.Start;
                    }
                    if (!Agent.Location.Equals(Agent.Dst))
                    {
                        ToogleCircle(tiles, Agent.Location, AgentRadius, Changes, xml.Width, xml.Height,
                                     Agent.Location, Agents, AgentRadius, false);

                        Agent.Location = NextAll(Agent.Location, xml.Width, xml.Height, Agent.Dst);
                        ToogleCircle(tiles, Agent.Location, AgentRadius, Changes, xml.Width, xml.Height,
                                     Agent.Location, Agents, AgentRadius, false);
                    }
                }
                step.Changes = Optimize(Changes).ToArray( );
                ChangeList.AddLast(step);
            }
            xml.ChangeList              = new ChangeList( );
            xml.ChangeList.Repeatable   = true;
            xml.ChangeList.BlockOnAgent = true;
            xml.ChangeList.Steps        = ChangeList.ToArray( );
            System.Console.WriteLine("\tMap Generated [{0}]", Filename);
            XmlSerializer s = new XmlSerializer(typeof(Map));
            TextWriter    w = new StreamWriter(Filename);

            s.Serialize(w, xml);
            w.Close( );
        }