Пример #1
0
        public T_Move SetToInterceptCourse(T_Move move, T_Reveal reveal, Dictionary<T_Move, T_Reveal> merchantsDict)
        {
            //Pick the closest merchant, either newly revealed or existing.
            double distance = 1000000000000000;
            T_Move closestKey = null;
            Vec2D location = new Vec2D(GetLocation(move, reveal));
            foreach (T_Move key in merchantsDict.Keys)
            {
                double thisDistance = new Vec2D(location).ScalerDistanceTo(new Vec2D(GetLocation(key,merchantsDict[key])));
                if (thisDistance < distance)
                {
                    closestKey = key;
                    distance = thisDistance;
                }
            } 

            double merchantSpeed = closestKey.Throttle*GetMaxSpeed(closestKey);
            Vec2D merchantStart = new Vec2D(GetLocation(closestKey, merchantsDict[closestKey]));
            Vec2D merchantDestination = new Vec2D((LocationValue)closestKey.Location.Item);
            Vec2D interceptPoint = GetInterceptPoint(merchantStart, merchantDestination, merchantSpeed, location, GetMaxSpeed(move));

            move.Location = new T_Location();
            move.Location.Item = interceptPoint.ToLocationValue();
            Console.WriteLine("setting pirate " + move.ID + " on intercept course to merchant " + closestKey.ID);
            return move;
        }
Пример #2
0
        public T_Move SetToInterceptCourse(T_Move move, T_Reveal reveal, Dictionary <T_Move, T_Reveal> merchantsDict)
        {
            //Pick the closest merchant, either newly revealed or existing.
            double distance   = 1000000000000000;
            T_Move closestKey = null;
            Vec2D  location   = new Vec2D(GetLocation(move, reveal));

            foreach (T_Move key in merchantsDict.Keys)
            {
                double thisDistance = new Vec2D(location).ScalerDistanceTo(new Vec2D(GetLocation(key, merchantsDict[key])));
                if (thisDistance < distance)
                {
                    closestKey = key;
                    distance   = thisDistance;
                }
            }

            double merchantSpeed       = closestKey.Throttle * GetMaxSpeed(closestKey);
            Vec2D  merchantStart       = new Vec2D(GetLocation(closestKey, merchantsDict[closestKey]));
            Vec2D  merchantDestination = new Vec2D((LocationValue)closestKey.Location.Item);
            Vec2D  interceptPoint      = GetInterceptPoint(merchantStart, merchantDestination, merchantSpeed, location, GetMaxSpeed(move));

            move.Location      = new T_Location();
            move.Location.Item = interceptPoint.ToLocationValue();
            Console.WriteLine("setting pirate " + move.ID + " on intercept course to merchant " + closestKey.ID);
            return(move);
        }
Пример #3
0
        /// <summary>
        /// Calculates an intercept course for "imminent threat" pirates
        /// </summary>
        /// <param name="currentItem"></param>
        /// <param name="dmID"></param>

        public override void Generate(T_Item currentItem, String dmID)
        {
            if (currentItem.Parameters.ThreatType == T_ThreatType.Nonimminent)
            {
                return;
            }

            Dictionary <T_Move, T_Reveal> dict = GetActionsAsDictionary(currentItem.Action);
            //This dictionary is a copy
            Dictionary <T_Move, T_Reveal> newDict = new Dictionary <T_Move, T_Reveal>(dict);

            //Find that pirate
            T_Move   move   = null;
            T_Reveal reveal = null;

            foreach (T_Move key in dict.Keys)
            {
                if (dict[key] == null)
                {
                    if (ddd.GetSeamateObject(key.ID).Owner == "Pirate DM")
                    {
                        move   = key;
                        reveal = dict[key];
                        newDict.Remove(key);
                        break;
                    }
                }
                else
                {
                    if (dict[key].Owner == "Pirate DM")
                    {
                        move   = key;
                        reveal = dict[key];
                        newDict.Remove(key);
                        break;
                    }
                }
            }
            if (move == null)
            {
                return;
            }



            move = SetToInterceptCourse(move, reveal, newDict);


            //Reset the pirate's move and reveal in dictionary.
            newDict[move] = reveal;

            //Translate dictionary back into action array.
            currentItem.Action = GetActionsFromDictionary(newDict);
        }
Пример #4
0
 public LocationValue GetLocation(T_Move move, T_Reveal reveal)
 {
     if (reveal == null)
     {
         return(ddd.GetSeamateObject(move.ID).Location);
     }
     else
     {
         return((LocationValue)reveal.Location.Item);
     }
 }
Пример #5
0
 public String GetOwner(T_Move move, T_Reveal reveal)
 {
     if (reveal == null)
     {
         return(ddd.GetSeamateObject(move.ID).Owner);
     }
     else
     {
         return(reveal.Owner);
     }
 }
Пример #6
0
        /// <summary>
        /// Creates a new reveal event and returns it.
        /// </summary>
        /// <param name="id">Vessel ID</param>
        /// <param name="owner">Name of DM</param>
        /// <param name="location">Location for reveal</param>
        /// <returns></returns>
        protected T_Reveal MakeReveal(String id, String owner, Vec2D location)
        {
            T_Reveal reveal = new T_Reveal();

            reveal.ID                      = id;
            reveal.Owner                   = owner;
            reveal.State                   = "FullyFunctional";
            reveal.Location                = new T_Location();
            reveal.StartupParameters       = new T_StartupParameters();
            reveal.StartupParameters.Items = new string[0];
            reveal.Location.Item           = location.ToLocationValue();
            return(reveal);
        }
Пример #7
0
        /// <summary>
        /// Sets IFF on or off.  This is a setting in the reveal event.
        /// 
        /// </summary>
        /// <param name="on"></param>
        /// <param name="isPirate"></param>
        /// <param name="reveal"></param>
        protected T_Reveal SetIFF(bool on, bool isPirate, T_Threat threat, T_Reveal reveal)
        {
            //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 (on && !isPirate)
                    SetIFFOn(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 && threat == T_Threat.Unambiguous)
                    SetIFFOn(isPirate, reveal);

            }
            return reveal;
        }
Пример #8
0
        public void SetIFF(bool isPirate, T_Reveal reveal)
        {
            String iff = "";

            if (isPirate)
            {
                iff = "Pirate";
            }
            else
            {
                iff = "Friendly";
            }

            reveal.StartupParameters.Items = new string[2];
            reveal.StartupParameters.Items.SetValue("ObjectName", 0);
            reveal.StartupParameters.Items.SetValue(iff, 1);
            Console.WriteLine("Just set IFF for vessel " + reveal.ID);
        }
Пример #9
0
        /// <summary>
        /// Adds a new move and reveal event to action list.  THis adds a previously unrevealed vessel into play
        /// Move event will be a "dummy" empty move with no destination defined yet
        /// </summary>
        /// <param name="id"></param>
        /// <param name="location"></param>
        protected void CreateRevealAndEmptyMove(String id, String owner, Vec2D location)
        {
            T_Reveal reveal = new T_Reveal();

            reveal.ID                      = id;
            reveal.Owner                   = owner;
            reveal.State                   = "FullyFunctional";
            reveal.Location                = new T_Location();
            reveal.StartupParameters       = new T_StartupParameters();
            reveal.StartupParameters.Items = new string[0];
            reveal.Location.Item           = location.ToLocationValue();

            T_Move move = new T_Move();

            move.ID       = id;
            move.Location = new T_Location();

            actions.Add(reveal);
            actions.Add(move);
        }
Пример #10
0
        /// <summary>
        /// Sets IFF on or off.  This is a setting in the reveal event.
        ///
        /// </summary>
        /// <param name="on"></param>
        /// <param name="isPirate"></param>
        /// <param name="reveal"></param>
        protected T_Reveal SetIFF(bool on, bool isPirate, T_Threat threat, T_Reveal reveal)
        {
            //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 (on && !isPirate)
                {
                    SetIFFOn(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 && threat == T_Threat.Unambiguous)
                {
                    SetIFFOn(isPirate, reveal);
                }
            }
            return(reveal);
        }
Пример #11
0
        //public void IdentifyActions(Object[] actions)
        //{

        //    if (actions.Length == 0) return;

        //    //What we will have at this point: one pirate (primary), one merchant (primary), or one pirate (primary) and one merchant (secondary).
        //    bool doSecondPass = false;
        //    foreach (Object action in actions)
        //    {
        //        //Get move actions
        //        T_Move tempMove = action as T_Move;

        //        if (tempMove != null) //it's a move
        //        {
        //            DDDAdapter.SeamateObject seamateObject = ddd.GetSeamateObject(tempMove.ID);

        //            if (seamateObject != null) //object is already in play
        //            {

        //                if (seamateObject.Owner == "Pirate DM")
        //                {
        //                    isPirate = true;
        //                    //Pirate is always primary if he exists
        //                    if (primaryMove == null) primaryMove = tempMove;
        //                    else
        //                    {
        //                        secondaryMove = primaryMove;
        //                        primaryMove = tempMove;
        //                    }
        //                }
        //                else //it's a merchant
        //                {
        //                    if (primaryMove == null) primaryMove = tempMove;
        //                    else secondaryMove = tempMove;
        //                }
        //            }
        //            else //object is not yet in play - has just been revealed
        //            {
        //                //how do we figure out who owns it?!!
        //                doSecondPass = true;
        //            }
        //        }
        //        else
        //        {
        //            T_Reveal tempReveal = action as T_Reveal;
        //            if (tempReveal.Owner == "Pirate DM")
        //            {
        //                isPirate = true;
        //                if (primaryReveal == null) primaryReveal = tempReveal;
        //                else
        //                {
        //                    secondaryReveal = primaryReveal;
        //                    primaryReveal = tempReveal;
        //                }
        //            }
        //            else //merchant
        //            {
        //                if (primaryReveal == null) primaryReveal = tempReveal;
        //                else secondaryReveal = tempReveal;
        //            }
        //        }
        //    }

        //    //Do second pass only to match up reveals with unmarked move actions
        //    if (doSecondPass)
        //    {
        //        foreach (Object action in actions)
        //        {
        //            T_Move tempMove = action as T_Move;
        //            if (tempMove != null && ddd.GetSeamateObject(tempMove.ID) == null)
        //            {
        //                if (primaryReveal.ID == tempMove.ID)
        //                    primaryMove = tempMove;
        //                else secondaryMove = tempMove;
        //            }
        //        }
        //    }

        //    if (primaryReveal != null)
        //        location = (LocationValue)primaryReveal.Location.Item;
        //    else
        //        location = ddd.GetSeamateObject(primaryMove.ID).Location;
        //}

        /// <summary>
        /// Goes through the list of actions to create a dictionary of reveal and move events.
        /// </summary>
        /// <param name="actions"></param>
        public Dictionary <T_Move, T_Reveal> GetActionsAsDictionary(Object[] actions)
        {
            Dictionary <T_Move, T_Reveal> dict = new Dictionary <T_Move, T_Reveal>();

            if (actions.Length == 0)
            {
                return(dict);
            }

            //What we will have at this point: one pirate (primary) and a bunch of merchants!

            //Set all moves as keys.  They are good keys because every vessel will be moved exactly once.
            foreach (Object action in actions)
            {
                T_Move tempMove = action as T_Move;
                if (tempMove != null) //it's a move
                {
                    dict.Add(tempMove, null);
                }
            }

            //Set all reveals as values.  Some keys will have null values because some vessels are already in play.
            foreach (Object action in actions)
            {
                T_Reveal tempReveal = action as T_Reveal;
                if (tempReveal != null) //&& ddd.GetSeamateObject(tempMove.ID) == null) // ? weird?
                {
                    foreach (T_Move key in dict.Keys)
                    {
                        if (key.ID == tempReveal.ID)
                        {
                            dict[key] = tempReveal;
                            break;
                        }
                    }
                }
            }

            return(dict);
        }
Пример #12
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;
            
        }
Пример #13
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();
        }
Пример #14
0
        public override void Generate(T_Item currentItem, String dmID)
        {
            dict = GetActionsAsDictionary(currentItem.Action);

            //This generator modifies move events e.g. keys, so write changes to this one because we'll be
            //iterating over the original.
            Dictionary <T_Move, T_Reveal> newDict = new Dictionary <T_Move, T_Reveal>();


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

                bool isPirate  = (GetOwner(move, reveal) == "Pirate DM");
                bool ambiguity = !(currentItem.Parameters.Threat == T_Threat.Unambiguous); //Vessel's desired perceived ambiguity
                //If it's a merchant and resources are available, always make merchants UNambiguous (so IFF is likely to be on). Per Courtney -Lisa
                if (!isPirate && currentItem.Parameters.PlayerResources == T_ResourceAvailability.Available)
                {
                    ambiguity = false;
                }

                //Is it in a sea lane?  If it is being newly revealed, yes because it's already in an entry region
                //and entry regions are the ends of sea lanes. Otherwise, check.
                List <PolygonValue> seaLanes = ddd.GetAllSeaLanes();
                bool locationInSeaLane       = false;
                if (reveal != null)
                {
                    locationInSeaLane = true;
                }
                else
                {
                    LocationValue location = GetLocation(move, reveal);
                    foreach (PolygonValue seaLane in seaLanes)
                    {
                        if (Polygon2D.IsPointInside(new Polygon2D(seaLane), new Vec2D(location)))
                        {
                            locationInSeaLane = true;
                        }
                    }
                }
                bool onInterceptCourse = isPirate; //all pirates are on intercept course, no merchant can be
                bool hasIFFon          = false;
                if (reveal == null)                //Object already exists in play
                {
                    String displayName = ddd.GetSeamateObject(move.ID).ObjectName;
                    if (!displayName.StartsWith("unknown"))
                    {
                        hasIFFon = true;
                    }
                }


                //Pick row from ambiguity table using existing constraints.
                bool[] selectedRow = PickRowFromAmbiguityTable(onInterceptCourse, hasIFFon, locationInSeaLane, ambiguity);


                reveal             = SetIFF(selectedRow[0], isPirate, currentItem.Parameters.Threat, reveal); //alters reveal event
                move.Throttle      = GetNewSpeed(selectedRow[1], move);
                move.Location.Item = GetNewDestination(selectedRow[2], onInterceptCourse).ToLocationValue();

                //Add modified move and reveal to new dictionary.
                newDict[move] = reveal;
            }
            currentItem.Action = GetActionsFromDictionary(newDict);
        }
Пример #15
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);
        }
Пример #16
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);
        }
Пример #17
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();
        }