Exemple #1
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;
        }
Exemple #2
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;
            
        }