示例#1
0
        private Vec2D MakeLocationInEntryRegions(List <PolygonValue> acceptableEntryRegions)
        {
            PolygonValue entryRegion = acceptableEntryRegions.ElementAt(random.Next(acceptableEntryRegions.Count));
            Vec2D        location    = new Polygon2D(entryRegion).PointInside();

            return(location);
        }
示例#2
0
        /// <summary>
        /// Makes a point which is in the closest entry region to the group of pirates,
        /// TODO: but not in the same entry region as any of them.
        /// </summary>
        /// <param name="pirates">The move events representing pirates</param>
        /// <param name="entryRegions">All entry regions</param>
        /// <returns>A random point in the closest entry region to the group of pirates</returns>
        private Vec2D GetPointInClosestEntryRegion(Dictionary <T_Move, T_Reveal> pirates, List <PolygonValue> entryRegions)
        {
            Vec2D        point           = new Vec2D(0, 0);
            double       closestDistance = 100000000;
            PolygonValue closestRegion   = null;

            Shuffle(entryRegions);
            T_Move        randomPirate = pirates.Keys.ToList().ElementAt(0);
            LocationValue location     = GetLocation(randomPirate, pirates[randomPirate]);

            foreach (PolygonValue entryRegion in entryRegions)
            {
                Polygon2D entry2D  = new Polygon2D(entryRegion);
                double    distance = Polygon2D.ScalarDistanceToPolygon(entry2D, new Vec2D(location));

                if (distance < oneGroupingDistance)
                {
                    point = entry2D.PointInside();
                    break;
                }
                else
                {
                    if (distance < closestDistance)
                    {
                        closestDistance = distance;
                        closestRegion   = entryRegion;
                    }
                }
            }
            if (point == null)
            {
                point = new Polygon2D(closestRegion).PointInside();
            }
            return(point);
        }
示例#3
0
 public void FromPolygon(PolygonValue p)
 {
     this.xPoints.Clear();
     this.yPoints.Clear();
     foreach (PolygonValue.PolygonPoint pp in p.points)
     {
         this.AddVertex(new Vec2D(pp.X, pp.Y));
     }
 }
示例#4
0
        public PolygonValue GetPolygonValue()
        {
            PolygonValue p = new PolygonValue();

            for (int i = 0; i < xPoints.Count; i++)
            {
                p.points.Add(new PolygonValue.PolygonPoint(xPoints[i], yPoints[i]));
            }

            return(p);
        }
示例#5
0
        private List <Vec2D> MakeLocationsInEntryRegions(int numPirates, List <PolygonValue> acceptableEntryRegions)
        {
            List <Vec2D> locations = new List <Vec2D>();

            for (int i = 0; i < numPirates; i++)
            {
                PolygonValue entryRegion = acceptableEntryRegions.ElementAt(random.Next(acceptableEntryRegions.Count));
                Vec2D        location    = new Polygon2D(entryRegion).PointInside();
                locations.Add(location);
            }
            return(locations);
        }
示例#6
0
        private PolygonValue GetFirescoutAORegion()
        {
            if (Firescout_AO == null)
            {
                Firescout_AO = new PolygonValue();
                Firescout_AO.points.Add(new PolygonValue.PolygonPoint(39000, 8400));
                Firescout_AO.points.Add(new PolygonValue.PolygonPoint(125800, 8700));
                Firescout_AO.points.Add(new PolygonValue.PolygonPoint(126500, 88200));
                Firescout_AO.points.Add(new PolygonValue.PolygonPoint(109600, 86950));
                Firescout_AO.points.Add(new PolygonValue.PolygonPoint(93000, 82400));
                Firescout_AO.points.Add(new PolygonValue.PolygonPoint(79200, 76000));
                Firescout_AO.points.Add(new PolygonValue.PolygonPoint(66400, 66500));
                Firescout_AO.points.Add(new PolygonValue.PolygonPoint(55800, 55900));
                Firescout_AO.points.Add(new PolygonValue.PolygonPoint(45700, 40700));
                Firescout_AO.points.Add(new PolygonValue.PolygonPoint(40500, 24000));
                Firescout_AO.points.Add(new PolygonValue.PolygonPoint(39000, 8400));
            }

            return(Firescout_AO);
        }
示例#7
0
        private PolygonValue GetBamsAORegion()
        {
            if (BAMS_AO == null)
            {
                BAMS_AO = new PolygonValue();
                BAMS_AO.points.Add(new PolygonValue.PolygonPoint(200, 76200));
                BAMS_AO.points.Add(new PolygonValue.PolygonPoint(0, 8800));
                BAMS_AO.points.Add(new PolygonValue.PolygonPoint(39100, 8600));
                BAMS_AO.points.Add(new PolygonValue.PolygonPoint(40500, 24000));
                BAMS_AO.points.Add(new PolygonValue.PolygonPoint(45700, 40700));
                BAMS_AO.points.Add(new PolygonValue.PolygonPoint(55800, 55900));
                BAMS_AO.points.Add(new PolygonValue.PolygonPoint(66400, 66500));
                BAMS_AO.points.Add(new PolygonValue.PolygonPoint(79200, 76000));
                BAMS_AO.points.Add(new PolygonValue.PolygonPoint(93000, 82400));
                BAMS_AO.points.Add(new PolygonValue.PolygonPoint(109600, 86950));
                BAMS_AO.points.Add(new PolygonValue.PolygonPoint(126500, 88200));
                BAMS_AO.points.Add(new PolygonValue.PolygonPoint(126200, 103200));
                BAMS_AO.points.Add(new PolygonValue.PolygonPoint(28900, 103200));
                BAMS_AO.points.Add(new PolygonValue.PolygonPoint(200, 76200));
            }

            return(BAMS_AO);
        }
示例#8
0
        private List <Vec2D> MakeLocationsForGroup(T_Groupings grouping, int numPirates, List <PolygonValue> entryRegions)
        {
            //For two groupings, just return all the entry regions.  We'll probably get a good distribution.
            if (grouping == T_Groupings.Two)
            {
                return(MakeLocationsInEntryRegions(numPirates, entryRegions));
            }

            //For one groupings, pick a random entry region to start the group.
            PolygonValue        entryRegion            = entryRegions.ElementAt(random.Next(entryRegions.Count));
            List <PolygonValue> acceptableEntryRegions = new List <PolygonValue>();

            foreach (PolygonValue region in entryRegions)
            {
                Vec2D pointFromNewRegion   = new Vec2D(region.points.ElementAt(0).X, region.points.ElementAt(0).Y);
                Vec2D pointFromFirstRegion = new Vec2D(entryRegion.points.ElementAt(0).X, entryRegion.points.ElementAt(0).Y);
                if (pointFromNewRegion.ScalerDistanceTo(pointFromFirstRegion) < oneGroupingDistance)
                {
                    acceptableEntryRegions.Add(region);
                }
            }
            return(MakeLocationsInEntryRegions(numPirates, acceptableEntryRegions));
        }
示例#9
0
        public static Vec2D FindIntersect(PolygonValue poly1, PolygonValue poly2)
        {
            List <Vec2D> intersections = new List <Vec2D>(); //with polys, we might have 2 intersections, should we find the middle of the two?
            List <PolygonValue.PolygonPoint> p2Points = poly2.points;
            Vec2D     intersect = null;
            Polygon2D p2d       = new Polygon2D();

            PolygonValue.PolygonPoint p0;
            PolygonValue.PolygonPoint p1;
            p2d.FromPolygon(poly1);
            for (int i = 0; i < p2Points.Count - 1; i++)
            {
                p0        = p2Points[i];
                p1        = p2Points[i + 1];
                intersect = FindIntersect(p2d, new Vec2D(p0.X, p0.Y), new Vec2D(p1.X, p1.Y));
                if (intersect != null)
                {
                    intersections.Add(intersect);
                }
            }
            //then once more from len-1 to 0
            p0        = p2Points[p2Points.Count - 1];
            p1        = p2Points[0];
            intersect = FindIntersect(p2d, new Vec2D(p0.X, p0.Y), new Vec2D(p1.X, p1.Y));
            //intersect = FindIntersect(poly1, p2Points[p2Points.Count - 1], p2Points[0]);
            if (intersect != null)
            {
                intersections.Add(intersect);
            }

            if (intersections.Count > 0)
            {
                return(AverageVectors(intersections));
            }

            return(null);
        }
示例#10
0
        private void ProcessRegion(SimulationEvent ev)
        {
            String id = ((StringValue)ev["ID"]).value;
            AttributeCollectionValue atts = ((AttributeCollectionValue)ev["Attributes"]);
            PolygonValue             pv   = atts.attributes["Polygon"] as PolygonValue;

            if (atts.attributes.ContainsKey("CurrentAbsolutePolygon"))
            {
                pv = atts["CurrentAbsolutePolygon"] as PolygonValue;
            }
            if (id.StartsWith("SeaLane-"))
            {
                if (!_seaLanes.ContainsKey(id))
                {
                    _seaLanes.Add(id, pv);
                }
                else
                {
                    _seaLanes[id] = pv;
                }
            }
            else if (id.StartsWith("Entry-"))
            {
                if (!_entryPoints.ContainsKey(id))
                {
                    _entryPoints.Add(id, pv);
                }
                else
                {
                    _entryPoints[id] = pv;
                }
            }
            else if (id.StartsWith("AO-"))
            {
                //AO's handled differently now
            }
        }
示例#11
0
        /// <summary>
        /// Makes a random point on the boundary of a polygon.
        /// </summary>
        /// <param name="area"></param>
        /// <returns></returns>
        protected LocationValue GetPointOnBoundary(PolygonValue area)
        {
            int i = random.Next(area.points.Count);

            PolygonValue.PolygonPoint startPP = area.points[i];
            PolygonValue.PolygonPoint endPP;
            if (i == 0)
            {
                endPP = area.points[i + 1];
            }
            else
            {
                endPP = area.points[i - 1];
            }
            //Use slope intercept form
            Vec2D  start     = new Vec2D(startPP.X, startPP.Y);
            Vec2D  end       = new Vec2D(endPP.X, endPP.Y);
            double slope     = (end.Y - start.Y) / (end.X - start.X);
            double intercept = start.Y - start.X * slope;
            double newX      = random.Next((int)Math.Min(start.X, end.X), (int)Math.Max(start.X, end.X)); //choose new X between existing X values
            double newY      = slope * newX + intercept;

            return(new Vec2D(newX, newY).ToLocationValue());
        }
示例#12
0
        //Pirate generator -- generates or chooses several pirates or friendly vessels in DM domain
        //So either creates a RevealEvent or chooses existing vessel for MoveEvent

        public override void Generate(T_Item currentItem, String dmID)
        {
            if (currentItem.Parameters.Threat == T_Threat.None)
            {
                return;
            }


            actions = currentItem.Action.ToList();

            // Do some setup
            bool isPirate = !(currentItem.Parameters.Threat == T_Threat.None);

            if (isPirate)
            {
                owner = "Pirate DM";
            }
            else
            {
                owner = "Merchant DM";
            }

            PolygonValue domainPV = this.ddd.GetDecisionMakersAreaOfResponsibility(dmID);

            domain = new Polygon2D(domainPV);
            List <string> unrevealedObjectIDs = ddd.GetAllUnrevealedObjectIds(isPirate, true, null);


            //How many pirates should we generate?  These numbers may need tweaking
            int minPirates = Properties.Settings.Default.minPirates;
            int maxPirates = Properties.Settings.Default.maxPirates;
            int numPirates = random.Next(minPirates, maxPirates);


            //Are there any pirates we can reuse, already in play?
            List <DDDAdapter.SeamateObject> reusableVessels = revealedSeaVessels.FindAll(IsReusable);

            if (reusableVessels.Count > 0 && Properties.Settings.Default.reusePirates)
            {
                for (int i = 0; i < numPirates; i++)
                {
                    if (reusableVessels.Count > 0)
                    {
                        DDDAdapter.SeamateObject vessel = reusableVessels[0];
                        reusableVessels.Remove(vessel);
                        CreateEmptyMove(vessel);
                    }
                    else
                    {
                        Vec2D  location = MakeLocationInEntryRegions(entryRegions);
                        string id       = unrevealedObjectIDs[random.Next(unrevealedObjectIDs.Count())];
                        unrevealedObjectIDs.Remove(id);
                        CreateRevealAndEmptyMove(id, owner, location);
                    }
                }


                ////See if any existing pirates can be paired under "grouping" distance constraints
                //List<List<DDDAdapter.SeamateObject>> groupedPirates = GroupVessels(currentItem.Parameters.Groupings, numPirates, reusableVessels);
                //List<List<DDDAdapter.SeamateObject>> groupsOfNumPirateSize = groupedPirates.FindAll(delegate(List<DDDAdapter.SeamateObject> g) { return g.Count >= numPirates; });

                ////Any groups of numPirates?
                //if (groupsOfNumPirateSize.Count > 0)
                //{
                //    //if yes, make dummy move events for them and add to actions list.  done.
                //    foreach (DDDAdapter.SeamateObject pirate in groupsOfNumPirateSize.ElementAt(0))
                //        CreateEmptyMove(pirate);
                //}
                //else
                //{
                //    //Can any of these smaller groupings include an entry region too, so we can add new pirates?
                //    groupedPirates.Sort(delegate(List<DDDAdapter.SeamateObject> g1, List<DDDAdapter.SeamateObject> g2) { return g1.Count.CompareTo(g2.Count); }); //sort by size, largest first
                //    foreach (List<DDDAdapter.SeamateObject> group in groupedPirates)
                //    {
                //        List<PolygonValue> matchingEntryRegions = GetMatchingEntryRegions(currentItem.Parameters.Groupings, group, entryRegions);
                //        if (matchingEntryRegions.Count > 0)
                //        {
                //            //if yes, then make dummy move events for the pirates in grouping, then
                //            foreach (DDDAdapter.SeamateObject pirate in groupsOfNumPirateSize.ElementAt(0))
                //                CreateEmptyMove(pirate);
                //            //Create as many remaining pirates as we need distributed randomly among suitable entry regions.
                //            List<Vec2D> locations = MakeLocationsInEntryRegions(numPirates - group.Count, matchingEntryRegions);
                //            foreach (Vec2D location in locations)
                //            {
                //                string id = unrevealedObjectIDs[random.Next(unrevealedObjectIDs.Count())];
                //                unrevealedObjectIDs.Remove(id);
                //                CreateRevealAndEmptyMove(id, owner, location);
                //            }
                //            break;
                //        }
                //    }

                //    //if no, we couldn't include an entry region (where new pirates would be created) with any existing pirates
                //    if (actions.Count == 0)
                //        //TODO: maybe should make smaller num of pirates if above min rather than making all new?
                //        MakeAllNewPirates(currentItem.Parameters.Groupings,numPirates,entryRegions,unrevealedObjectIDs);
                //}
            }
            //no reusable vessels, we have to create all new pirates
            else
            {
                MakeAllNewPirates(currentItem.Parameters.Groupings, numPirates, entryRegions, unrevealedObjectIDs);
            }

            currentItem.Action = actions.ToArray();
        }
示例#13
0
 /// <summary>
 /// A constructor.
 /// </summary>
 public SimActiveRegion()
 {
     m_shape = new PolygonValue();
 }
示例#14
0
        public override void Generate(T_Item currentItem, String dmID)
        {
            //Identify what's already in actions list.
            foreach (Object action in currentItem.Action)
            {
                if (action as T_Move != null)
                {
                    primaryMove = (T_Move)action;
                }
                if (action as T_Reveal != null)
                {
                    primaryReveal = (T_Reveal)action;
                }
            }
            LocationValue location          = GetLocation(primaryMove, primaryReveal);
            bool          isPirate          = GetOwner(primaryMove, primaryReveal) == "Pirate DM";
            PolygonValue  pirateEntryRegion = null;

            if (isPirate)
            {
                foreach (PolygonValue region in entryRegions)
                {
                    if (Polygon2D.IsPointInside(new Polygon2D(region), new Vec2D(location)))
                    {
                        pirateEntryRegion = region;
                        break;
                    }
                }
            }


            List <Object> list = currentItem.Action.ToList();

            List <string> unrevealedObjectIDs = ddd.GetAllUnrevealedObjectIds(false, true, null);

            if (primaryReveal != null)
            {
                unrevealedObjectIDs.Remove(primaryReveal.ID);
            }


            int minStimuli = 0;

            //If threat type is imminent, we need to guarantee there will be a merchant for the pirate to attack.
            if (currentItem.Parameters.ThreatType == T_ThreatType.Imminent)
            {
                minStimuli = 1;
            }


            int maxStimuli;

            //If resources need to be available, then two is maximum of stimulus events.
            if (T_ResourceAvailability.Available == currentItem.Parameters.PlayerResources)
            {
                maxStimuli = 2;
            }
            //If resources are unavailable, there must be at least 3 total stimulus events, and max can be higher.
            else
            {
                minStimuli = 3;
                maxStimuli = 5;
            }

            int numStimuliToGenerate = this.changingNumber(minStimuli, 60, minStimuli, maxStimuli); //probably minStimuli but could be up to maxStimuli


            //If our probability criteria says we should add vessels, try and populate reusable objects list
            List <DDDAdapter.SeamateObject> reuseableObjects = new List <DDDAdapter.SeamateObject>();

            if (shouldAddNewVessel(revealedSeaVessels))
            {
                reuseableObjects = findObjectsInPlay(location, pirateEntryRegion, currentItem.Parameters.Groupings, false);
            }

            for (int i = 0; i < numStimuliToGenerate; i++)
            {
                T_Move move = new T_Move();

                //Try and recycle objects to create stimulus.
                if (reuseableObjects.Count != 0)
                {
                    Shuffle(reuseableObjects);
                    DDDAdapter.SeamateObject objectForReuse = null;
                    //see if any eligible vessels are stopped, if so, use one of them
                    foreach (DDDAdapter.SeamateObject possiblyStoppedVessel in reuseableObjects)
                    {
                        if (possiblyStoppedVessel.Throttle == 0) //yes, it is stopped
                        {
                            //Console.WriteLine("GRoupingGenerator: Picking a stopped vessel " + possiblyStoppedVessel.ID + " to reuse.");
                            objectForReuse = possiblyStoppedVessel;
                            break;
                        }
                    }
                    //randomly pick one of the suitable objects to create a stimulus
                    if (objectForReuse == null)
                    {
                        objectForReuse = reuseableObjects[random.Next(reuseableObjects.Count)];
                    }

                    move.ID = objectForReuse.ID;
                    reuseableObjects.Remove(objectForReuse);
                    //Console.WriteLine("GroupingGenerator: Moving existing merchant " + objectForReuse.ID);
                }
                else //Reveal and move new merchant.
                {
                    T_Reveal reveal = new T_Reveal();
                    reveal.Owner                   = "Merchant DM";
                    reveal.State                   = "FullyFunctional";
                    reveal.StartupParameters       = new T_StartupParameters();
                    reveal.StartupParameters.Items = new string[0];
                    reveal.ID = unrevealedObjectIDs[random.Next(unrevealedObjectIDs.Count)]; //pick a random new object
                    unrevealedObjectIDs.Remove(reveal.ID);                                   //take it out of the available list

                    //ADDED 11/10/11:  To make sure that the merchants don't end up in the same entry region as a newly created pirate,
                    //if there's a new pirate, instead of iterating over all entry regions we'll remove the pirate's region from the list first.
                    if (pirateEntryRegion != null)
                    {
                        entryRegions.Remove(pirateEntryRegion);
                    }

                    Vec2D point = null;

                    //If two grouping, pick points in entry regions until one is > 100 away
                    if (currentItem.Parameters.Groupings == T_Groupings.Two)
                    {
                        while (true)
                        {
                            point = new Polygon2D(entryRegions[random.Next(entryRegions.Count)]).PointInside();
                            if (point.ScalerDistanceTo(new Vec2D(location)) > twoGroupingDistance)
                            {
                                break;
                            }
                        }
                    }
                    //If one grouping, see if any entry region is within 50km.  If so, pick a point in that entry region.
                    //It's possible that no entry region may be within 50km.  In that case, pick a point in the closest one.

                    if (currentItem.Parameters.Groupings == T_Groupings.One)
                    {
                        double       closestDistance = 100000000;
                        PolygonValue closestRegion   = null;
                        Shuffle(entryRegions);

                        foreach (PolygonValue entryRegion in entryRegions)
                        {
                            Polygon2D entry2D  = new Polygon2D(entryRegion);
                            double    distance = Polygon2D.ScalarDistanceToPolygon(entry2D, new Vec2D(location));

                            if (distance < oneGroupingDistance)
                            {
                                point = entry2D.PointInside();
                                break;
                            }
                            else
                            {
                                if (distance < closestDistance)
                                {
                                    closestDistance = distance;
                                    closestRegion   = entryRegion;
                                }
                            }
                        }
                        if (point == null)
                        {
                            //Console.WriteLine("GroupingGenerator: Unable to place vessel in an entry region AND <100km away.  Placing in closest entry region " + closestDistance + " away.");
                            point = new Polygon2D(closestRegion).PointInside();
                        }
                    }
                    reveal.Location      = new T_Location();
                    reveal.Location.Item = point.ToLocationValue();
                    list.Add(reveal);

                    move.ID = reveal.ID;
                    //Console.WriteLine("GroupingGenerator: Revealing new merchant " + reveal.ID + " and moving it");
                }

                move.Location = new T_Location();
                list.Add(move);
            }

            currentItem.Action = list.ToArray();
        }
示例#15
0
        //isPirate here refers to the objects we are trying to find, e.g. isPirate = true means find pirates
        private List <SeamateAdapter.DDD.DDDAdapter.SeamateObject> findObjectsInPlay(LocationValue nearby, PolygonValue pirateEntryRegion, T_Groupings grouping, bool isPirate)
        {
            List <DDDAdapter.SeamateObject> vessels = new List <DDDAdapter.SeamateObject>();

            foreach (DDDAdapter.SeamateObject vessel in ddd.GetAllRevealedSeaVessels())
            {
                if (isPirate && vessel.Owner == "Pirate DM" || !isPirate && vessel.Owner == "Merchant DM")
                {
                }
                else
                {
                    continue;
                }
                double distance = new Vec2D(vessel.Location).ScalerDistanceTo(new Vec2D(nearby));
                bool   inSameEntryRegionAsPirate = false;
                if (pirateEntryRegion != null)
                {
                    inSameEntryRegionAsPirate = Polygon2D.IsPointInside(new Polygon2D(pirateEntryRegion), new Vec2D(vessel.Location));
                }

                if (grouping == T_Groupings.One && distance < oneGroupingDistance && !inSameEntryRegionAsPirate)
                {
                    vessels.Add(vessel);
                }
                else if (grouping == T_Groupings.Two && distance > twoGroupingDistance && !inSameEntryRegionAsPirate)
                {
                    vessels.Add(vessel);
                }
            }
            return(vessels);
        }
示例#16
0
        public bool SpecialGenerate(T_Item currentItem, String dmID)
        {
            Dictionary <T_Move, T_Reveal> dict    = GetActionsAsDictionary(currentItem.Action);
            Dictionary <T_Move, T_Reveal> newDict = new Dictionary <T_Move, T_Reveal>();

            List <PolygonValue> seaLanes = ddd.GetAllSeaLanes();
            PolygonValue        domain   = this.ddd.GetDecisionMakersAreaOfResponsibility(dmID);


            foreach (T_Move key in dict.Keys)
            {
                T_Move   move   = key;
                T_Reveal reveal = dict[key];


                //Is this vessel a pirate?
                bool isPirate = false;
                if (reveal != null) //there's a reveal event
                {
                    if (reveal.Owner == "Pirate DM")
                    {
                        isPirate = true;
                    }
                }
                else if (ddd.GetSeamateObject(move.ID).Owner == "Pirate DM")
                {
                    isPirate = true;
                }


                //Vessel's desired perceived ambiguity
                bool ambiguity = true;
                if (currentItem.Parameters.Threat == T_Threat.Unambiguous)
                {
                    ambiguity = false;
                }
                //If it's a merchant and resources aren't unavailable, always make merchants UNambiguous (so IFF is likely to be on)
                if (!isPirate && currentItem.Parameters.PlayerResources == T_ResourceAvailability.Available)
                {
                    ambiguity = false;
                }


                //Is it in a sea lane?  If it is already in play check, Yes if it is being revealed in an entry region
                bool          locationInSeaLane = false;
                LocationValue location;
                if (reveal == null) //already in play
                {
                    location = ddd.GetSeamateObject(move.ID).Location;
                }
                else
                {
                    location = (LocationValue)reveal.Location.Item;
                }

                foreach (PolygonValue seaLane in seaLanes)
                {
                    Polygon2D seaLane2D = new Polygon2D(seaLane);
                    if (Polygon2D.IsPointInside(seaLane2D, new Vec2D(location)))
                    {
                        locationInSeaLane = true;
                        break;
                    }
                }

                //Intercept course
                bool onInterceptCourse = false;
                if (currentItem.Parameters.ThreatType == T_ThreatType.Imminent && isPirate)
                {
                    onInterceptCourse = true;
                }

                //IFF
                bool hasIFFon = false;

                //Is its IFF already on?
                if (move == null) //Object already exists in play
                {
                    String displayName = ddd.GetSeamateObject(move.ID).ObjectName;
                    if (!displayName.StartsWith("unknown")) //Object has IFF set on
                    {
                        hasIFFon = true;
                    }
                }


                //Pick row from ambiguity table using existing constraints.
                Shuffle(ambiguityTable);
                bool[] selectedRow = null;
                foreach (bool[] row in ambiguityTable)
                {
                    if ((!onInterceptCourse || row[2]) &&       //if onInterceptCourse is true, only allow course to be "on"/true ... if onInterceptCourse is false, either value is OK
                        (!hasIFFon || row[0]) &&                //same as above for hasIFFon and IFF
                        (!locationInSeaLane || row[3]) &&       //same as above for inSeaLane and location
                        ambiguity == row[4])                    // ambiguity must match

                    {
                        selectedRow = row;
                    }
                }
                if (selectedRow == null)
                {
                    return(false);
                    //Console.WriteLine("Impossible scenario");
                    //selectedRow = ambiguityTable[random.Next(ambiguityTable.Length)];
                    //TODO: Wipe out actions, go back to Threat Generator and make a new object
                }
                // Console.WriteLine("AmbiguityGenerator: Making settings for an " + currentItem.Parameters.ThreatType.ToString() + " vessel.  IFF should be on?" + selectedRow[0]);

                //Create scenario described in ambiguity table

                //IFF =================================
                //If we're revealing a new vessel, we can set its IFF on if we need to.  Default is off so we don't
                // have to do anything.  We can't change existing ships.
                if (reveal != null)
                {
                    if (selectedRow[0] && !isPirate)
                    {
                        SetIFF(isPirate, reveal);
                    }

                    //If it's a pirate, ignore what it says in the ambiguity table.
                    //Unambiguous == IFF ON always.  Ambiguous = IFF OFF always
                    if (isPirate && currentItem.Parameters.Threat == T_Threat.Unambiguous)
                    {
                        SetIFF(isPirate, reveal);
                    }
                }

                //SPEED ===============================
                double maxSpeed = GetMaxSpeed(move);

                double newSpeed;
                if (selectedRow[1])  //speed 69-84 m/s
                {
                    newSpeed = random.Next(69, Math.Max((int)maxSpeed, 84));
                }
                else
                {  //speed <69 or >84 m/s
                    if (maxSpeed > 84)
                    {
                        newSpeed = random.Next(84, (int)maxSpeed);
                    }
                    else
                    {
                        newSpeed = random.Next(20, 68);
                    }
                }
                move.Throttle = ((double)newSpeed / (double)maxSpeed);



                //COURSE =================================
                if (selectedRow[2])
                {
                    if (onInterceptCourse) // we will take care of this later
                    {
                    }
                    else //if (locationInSeaLane)
                    {
                        //pick any entry region and send it there.
                        Polygon2D entryRegion2D = new Polygon2D(entryRegions[random.Next(entryRegions.Count)]);
                        Vec2D     point         = entryRegion2D.PointInside();
                        move.Location      = new T_Location();
                        move.Location.Item = point.ToLocationValue();
                    }
                }
                else
                {
                    //just send it anywhere ... probably won't be in a sea lane
                    Vec2D point = new Polygon2D(domain).PointInside(); //TODO: this should be in whole scenario boundaries, not just DM domain
                    move.Location      = new T_Location();
                    move.Location.Item = point.ToLocationValue();

                    //TODO:  Send it to the edge of the universe.  Just kidding ... to edge of sea region.
                    ddd.GetDecisionMakersAreaOfResponsibility("BAMS DM");
                    ddd.GetDecisionMakersAreaOfResponsibility("Firescout DM");
                }
                //Add modified move and reveal back to dictionary.
                newDict[move] = reveal;
            }
            currentItem.Action = GetActionsFromDictionary(newDict);
            return(true);
        }
示例#17
0
 public Polygon2D(PolygonValue value)
 {
     this.FromPolygon(value);
 }
示例#18
0
        //Threat generator -- generates or chooses ONE pirate or friendly vessel in DM domain
        //So either creates a RevealEvent or chooses existing vessel for MoveEvent
        public List <DDDAdapter.SeamateObject> GenerateWithTriedItems(T_Item currentItem, String dmID, List <DDDAdapter.SeamateObject> triedVessels)
        {
            //make a copy of the input which we'll modify and return at the end
            List <DDDAdapter.SeamateObject> returnTriedVessels = new List <DDDAdapter.SeamateObject>(triedVessels);

            String owner;
            bool   isPirate;

            if (currentItem.Parameters.Threat == T_Threat.None)
            {
                isPirate = false;
                owner    = "Merchant DM";
            }
            else
            {
                isPirate = true;
                owner    = "Pirate DM";
            }


            PolygonValue domainPV = this.ddd.GetDecisionMakersAreaOfResponsibility(dmID);
            Polygon2D    domain   = new Polygon2D(domainPV);

            List <Object> actions = new List <object>();

            if (shouldAddNewVessel(revealedSeaVessels))
            {
                Console.WriteLine("ThreatGenerator: I'm trying to reuse a vessel because there are " + revealedSeaVessels.Count + " in play already and/or probability told me to.");
                List <DDDAdapter.SeamateObject> vessels = new List <DDDAdapter.SeamateObject>();
                //Find all vessels of the appropriate type (pirate or merchant) within the BAMS/Firescout's range.
                foreach (DDDAdapter.SeamateObject vessel in revealedSeaVessels)
                {
                    if (vessel.Owner == owner && Polygon2D.IsPointInside(domain, new Vec2D(vessel.Location)))
                    {
                        vessels.Add(vessel);
                    }
                }
                Console.WriteLine("ThreatGenerator: Found " + vessels.Count + " to reuse");

                if (vessels.Count > 0)
                {
                    //manage the list of previously tried objects
                    if (triedVessels.Count == vessels.Count)
                    {
                        returnTriedVessels = new List <DDDAdapter.SeamateObject>();
                    }
                    foreach (DDDAdapter.SeamateObject alreadyTried in returnTriedVessels)
                    {
                        vessels.Remove(alreadyTried);
                    }

                    Shuffle(vessels);
                    DDDAdapter.SeamateObject vessel = null;
                    //see if any eligible vessels are stopped, if so, use one of them
                    foreach (DDDAdapter.SeamateObject possiblyStoppedVessel in vessels)
                    {
                        if (possiblyStoppedVessel.Throttle == 0) //yes, it is stopped
                        {
                            Console.WriteLine("ThreatGenerator: Picking a stopped vessel " + possiblyStoppedVessel.ID + " to reuse.");
                            vessel = possiblyStoppedVessel;
                            break;
                        }
                    }
                    //we didn't find any stopped vessels, so pick a random eligible one.
                    if (vessel == null)
                    {
                        vessel = vessels[random.Next(vessels.Count)];
                    }
                    returnTriedVessels.Add(vessel);
                    T_Move move = new T_Move();
                    move.ID       = vessel.ID;
                    move.Location = new T_Location();

                    actions.Add(move);
                }
            }

            if (actions.Count() == 0) //we couldn't find a ship or need more vessels
            {                         //reveal a random new one
                Console.WriteLine("ThreatGenerator: I'm revealing a new vessel, either couldn't find a ship or need more vessels.");
                List <string> unrevealedObjectIDs = ddd.GetAllUnrevealedObjectIds(isPirate, true, null);

                T_Reveal reveal = new T_Reveal();
                reveal.ID                      = unrevealedObjectIDs[random.Next(unrevealedObjectIDs.Count())];
                reveal.Owner                   = owner;
                reveal.State                   = "FullyFunctional";
                reveal.Location                = new T_Location();
                reveal.StartupParameters       = new T_StartupParameters();
                reveal.StartupParameters.Items = new string[0];

                T_Move move = new T_Move();
                move.ID       = reveal.ID;
                move.Location = new T_Location();
                Vec2D point;
                List <PolygonValue> entryRegions = ddd.GetAllEntryRegions();
                //TODO: Write a safe PointInsideMultipleDomains() function.  This could theoretically loop forever with a terrible scenario
                while (true)
                {
                    point = new Polygon2D(entryRegions[random.Next(entryRegions.Count)]).PointInside();
                    if (Polygon2D.IsPointInside(domain, point))
                    {
                        break;
                    }
                }
                reveal.Location.Item = point.ToLocationValue();

                actions.Add(reveal);
                actions.Add(move);
                Console.WriteLine("ThreatGenerator: Just revealed a pirate " + reveal.ID);
            }


            currentItem.Action = actions.ToArray();
            return(returnTriedVessels);
        }