コード例 #1
0
        private void CalculateAdConstraints(AdvertisementTask order, int position)
        {
            _currentAdPosition = position;
            _currentAdCount    = 1;
            _currentAd         = order;
            if (!_taksAssessments.TryGetValue(order.ID, out TaskScore assesedTask))
            {
                assesedTask = new TaskScore()
                {
                    AdConstraints   = _currentAd,
                    ScoringFunction = ScoringFunction,
                };
                assesedTask.BreaksPositions.Add(_breakData.ID, new SortedSet <int>());
                _taksAssessments.Add(order.ID, assesedTask);
            }
            assesedTask.BreaksPositions[_breakData.ID].Add(position);
            _currentlyAssessed = assesedTask;
            Instance.BrandIncompatibilityCost.TryGetValue(_currentAd.Brand.ID, out var currentAdWeights);
            _currentAdIncompatibilityCosts = currentAdWeights;

            UpdateSimpleStatsForCurrentAd(position);

            for (int i = 0; i < _schedule.Count; i++)
            {
                if (i != _currentAdPosition)
                {
                    CheckAdToAdCompatibility(_schedule.Order[i], i);
                }
            }
            if (_currentAdCount > _currentAd.MaxPerBlock)
            {
                _currentlyAssessed.SelfIncompatibilityConflicts += 1;
            }
        }
コード例 #2
0
 private List<int> GetPossibleInserts(TaskScore taskScore, BreakSchedule breakSchedule)
 {
     List<int> added = new List<int>();
     if(!taskScore.BreaksPositions.TryGetValue(breakSchedule.ID, out var breakPositions))
     {
         breakPositions = new SortedSet<int>();
     }
     //make it a list copy
     var positionsList = breakPositions.ToList();
     int arrIndex = 0;
     for(int possiblePos = 0; possiblePos < breakSchedule.Order.Count + 1; )
     {
         if (added.Count >= MaxInsertedPerBreak) break;
         if (breakPositions.Count >= taskScore.AdConstraints.MaxPerBlock) break;
         if (breakSchedule.UnitFill + (added.Count + 1) * taskScore.AdConstraints.AdSpanUnits > breakSchedule.BreakData.SpanUnits + MaxBreakExtensionUnits) break;
         int nextPos = breakPositions.Count > arrIndex ? positionsList[arrIndex] : 999999999;
         if (possiblePos + taskScore.AdConstraints.MinJobsBetweenSame <= nextPos)
         {
             added.Add(possiblePos);
             for(int j = arrIndex; j < breakPositions.Count; j++)
             {
                 positionsList[j] += 1;
             }
             positionsList.Insert(arrIndex, possiblePos);
             possiblePos += taskScore.AdConstraints.MinJobsBetweenSame + 1;
         }
         else
         {
             possiblePos = nextPos + taskScore.AdConstraints.MinJobsBetweenSame + 1;
         }
         arrIndex += 1;
     }
     return added;
 }
コード例 #3
0
        private void TryToScheduleOrder(TaskScore orderData)
        {
            var schedules = Solution.AdvertisementsScheduledOnBreaks.Values.Where(s =>
            {
                if (s.UnitFill > MaxBreakExtensionUnits + s.BreakData.SpanUnits)
                {
                    return(false);
                }
                if (Instance.GetTypeToBreakIncompatibility(orderData, s) == 1)
                {
                    return(false);
                }
                if (Instance.GetBulkBrandIncompatibilities(orderData.AdConstraints, s.Order).Contains(double.PositiveInfinity))
                {
                    return(false);
                }
                return(true);
            }).ToList();

            schedules.Shuffle(Random);
            foreach (var schedule in schedules)
            {
                if (CheckForNoSelfConflicts(orderData, schedule))
                {
                    PerformIfTransformationImprovesScore(orderData, schedule);
                }
                if (orderData.EndsSatisfied || CurrentTime.Elapsed >= TimeLimit)
                {
                    break;
                }
            }
        }
コード例 #4
0
        private bool InsertInRandomNonFilledBreak(TaskScore taskData)
        {
            List <BreakSchedule> breaksWithEnoughSpace = Solution.AdvertisementsScheduledOnBreaks.Values.Where
                                                         (
                b => b.BreakData.SpanUnits >= b.UnitFill + taskData.AdConstraints.AdSpanUnits
                                                         ).ToList();

            if (breaksWithEnoughSpace.Count == 0)
            {
                return(false);
            }
            int           breakNum = Random.Next(breaksWithEnoughSpace.Count);
            BreakSchedule schedule = breaksWithEnoughSpace[breakNum];
            int           position = Random.Next(schedule.Count + 1);
            Insert        insert   = new Insert()
            {
                TvBreak            = schedule.BreakData,
                AdvertisementOrder = taskData.AdConstraints,
                Position           = position,
                Instance           = Instance,
                Solution           = Solution,
            };

            insert.Asses();
            insert.Execute();
            Reporter.AddEntry(insert.GenerateReportEntry());
            return(true);
        }
コード例 #5
0
    private bool ThirstBucket()
    {
        float     score;
        int       TaskIndex = 1;
        TaskScore newScore;

        m_Scores.Clear();
        m_TBucketUI.ToggleTasks(true);

        // Drink from flask
        // Only score if we have water in flask
        if (m_Inventory.QueryFlask() > 0)
        {
            float Thirst = m_Stats.GetThirst();
            score    = Thirst / 100.0f;
            newScore = new TaskScore(score, TaskIndex, CharacterTaskDeployer.Task.Drinking);
            m_Scores.Add(newScore);
            m_TBucketText[TaskIndex].text = score.ToString("0.000");
        }
        TaskIndex++;

        // Refill flask
        if (m_Inventory.QueryFlask() < 100)
        {
            float Thirst = m_Stats.GetThirst() / 100.0f;
            float Flask  = 1.0f - (float)m_Inventory.QueryFlask() / m_Inventory.m_MaxWaterFlask;
            score    = Mathf.Pow((Flask + Thirst) / 2.0f, REFILL_EXPONENT);
            newScore = new TaskScore(score, TaskIndex, CharacterTaskDeployer.Task.RefillingFlask);
            m_Scores.Add(newScore);
            m_TBucketText[TaskIndex].text = score.ToString("0.000");
        }

        return(HandleScores(TaskIndex, m_TBucketText));
    }
コード例 #6
0
 private void ChooseMoveToPerform(List<int> positions, TaskScore taskScore, BreakSchedule breakSchedule)
 {
     foreach(var position in positions)
     {
         Insert move = new Insert()
         {
             Solution = Solution,
             Position = position,
             TvBreak = breakSchedule.BreakData,
             AdvertisementOrder = taskScore.AdConstraints,
         };
         move.Asses();
         if(move.OverallDifference.HasScoreImproved() && !move.OverallDifference.AnyCompatibilityIssuesIncreased())
         {
             move.Execute();
             Reporter.AddEntry(move.GenerateReportEntry());
             _numberOfMoves += 1;
             _movePerformed = true;
         }
         else
         {
             break;
         }
         if (CurrentTime.Elapsed >= TimeLimit) break;
     }
 }
コード例 #7
0
    private bool CampfireBucket()
    {
        float     score;
        TaskScore newScore;
        int       TaskIndex = 1;

        m_Scores.Clear();
        m_CFBucketUI.ToggleTasks(true);

        // Light campfire
        // Only score it if the campfire isn't lit
        if (!m_Campfire.IsLit() && m_Inventory.QueryLog() + m_Woodstore.QueryAmount() + m_Campfire.GetLogsRemaining() > 0)
        {
            float TimeUnlit = m_Campfire.GetUnlitTime();
            float MaxTime   = m_Campfire.m_WolfThreatTime;
            score    = Mathf.Min(Mathf.Pow(TimeUnlit / MaxTime, LIGHT_FIRE_EXPONENT) + LIGHT_FIRE_BASE, 1.0f);
            newScore = new TaskScore(score, TaskIndex, CharacterTaskDeployer.Task.Firelighting);
            m_Scores.Add(newScore);
            m_CFBucketText[TaskIndex].text = score.ToString("0.000");
        }
        TaskIndex++;

        // Add logs to fire
        // Only if we have logs AND the campfire isn't full
        if (m_Inventory.QueryLog() + m_Woodstore.QueryAmount() > 0 && m_Campfire.GetLogsRemaining() < m_Campfire.m_MaxLogs)
        {
            float FireRatio = 1.0f - (m_Campfire.GetAccurateLogsRemaining() / m_Campfire.m_MaxLogs);
            score    = Mathf.Max(FireRatio, 0.0f);
            newScore = new TaskScore(score, TaskIndex, CharacterTaskDeployer.Task.Firebuilding);
            m_Scores.Add(newScore);
            m_CFBucketText[TaskIndex].text = score.ToString("0.000");
        }
        TaskIndex++;

        // Chop wood
        // Only if there's space in inventory AND if theres trees available AND if the characters stats aren't too high
        if (m_Inventory.QuerySpace((int)Resource.Log) > 0 && m_Forest.GetActiveCount() > 0 && AbleToWork())
        {
            float CurrentWood = m_Woodstore.QueryAmount() + m_Inventory.QueryLog() + m_Campfire.GetLogsRemaining();
            float MaxWood     = m_Woodstore.m_StorageLimit + m_Campfire.m_MaxLogs;
            score    = Mathf.Min(1.0f - (CurrentWood / MaxWood), 1.0f);
            newScore = new TaskScore(score, TaskIndex, CharacterTaskDeployer.Task.Chopping);
            m_Scores.Add(newScore);
            m_CFBucketText[TaskIndex].text = score.ToString("0.000");
        }
        TaskIndex++;

        // Deposit logs
        // Only score if the character has logs and there is space in the store
        if (m_Inventory.QueryLog() > 0 && m_Woodstore.QuerySpace() > 0)
        {
            score    = (m_Inventory.QueryLog() * m_Inventory.m_LogWeight) / m_Inventory.QueryWeight();
            newScore = new TaskScore(score, TaskIndex, CharacterTaskDeployer.Task.Depositing, Resource.Log);
            m_Scores.Add(newScore);
            m_CFBucketText[TaskIndex].text = score.ToString("0.000");
        }

        return(HandleScores(TaskIndex, m_CFBucketText));
    }
コード例 #8
0
    private bool HandleScores(int numTasks, Text[] BucketText)
    {
        if (m_Scores.Count <= 0)
        {
            return(false);
        }
        m_Scores.Sort((v1, v2) => v1.score.CompareTo(v2.score));
        m_Scores.Reverse();
        float winningScore = m_Scores[0].score;
        float minScore     = winningScore - (winningScore * TaskPercentile);

        Color red = new Color(0.9f, 0.5f, 0.5f, 1.0f);
        Color yel = new Color(0.9f, 0.9f, 0.4f, 1.0f);
        Color toSet;

        foreach (TaskScore task in m_Scores)
        {
            toSet = yel;
            if (task.score < minScore)
            {
                BucketText[task.index + numTasks].text = "Elim.";
                toSet = red;
            }
            BucketText[task.index + numTasks].color = toSet;
            BucketText[task.index].color            = toSet;
        }

        m_Scores.RemoveAll(task => task.score < minScore);

        if (m_Scores.Count == 1)
        {
            m_NewTask = m_Scores[0];
            BucketText[m_NewTask.index + numTasks].text = "100%";
            BucketText[m_NewTask.index].color           = BucketText[m_NewTask.index + numTasks].color = Color.green;
            return(true);
        }
        else if (m_Scores.Count > 1)
        {
            WeighScores(numTasks, BucketText);
            m_NewTask = SelectTask();
            BucketText[m_NewTask.index].color = BucketText[m_NewTask.index + numTasks].color = Color.green;
            return(true);
        }
        else
        {
            return(false);
        }
    }
コード例 #9
0
        private void PerformIfTransformationImprovesScore(TaskScore taskScore, BreakSchedule breakSchedule)
        {
            Insert move = new Insert()
            {
                Solution           = Solution,
                Position           = breakSchedule.Count,
                TvBreak            = breakSchedule.BreakData,
                AdvertisementOrder = taskScore.AdConstraints,
            };

            move.Asses();
            if (move.OverallDifference.HasScoreImproved() && !move.OverallDifference.AnyCompatibilityIssuesIncreased())
            {
                move.Execute();
                Reporter.AddEntry(move.GenerateReportEntry());
                _numberOfMoves += 1;
                _movePerformed  = true;
            }
        }
コード例 #10
0
        private void InsertInRandomBreak(TaskScore taskData)
        {
            int           breakNum = Random.Next(Instance.Breaks.Count);
            TvBreak       tvBreak  = Instance.Breaks.Values.ToList()[breakNum];
            BreakSchedule schedule = Solution.AdvertisementsScheduledOnBreaks[tvBreak.ID];
            int           position = Random.Next(schedule.Count + 1);
            Insert        insert   = new Insert()
            {
                TvBreak            = schedule.BreakData,
                AdvertisementOrder = taskData.AdConstraints,
                Position           = position,
                Instance           = Instance,
                Solution           = Solution,
            };

            insert.Asses();
            insert.Execute();
            Reporter.AddEntry(insert.GenerateReportEntry());
        }
コード例 #11
0
 private void TryToScheduleOrder(TaskScore orderData)
 {
     var schedules = Solution.AdvertisementsScheduledOnBreaks.Values.Where(s =>
         {
             if (s.UnitFill > MaxBreakExtensionUnits + s.BreakData.SpanUnits) return false;
             if (Instance.GetTypeToBreakIncompatibility(orderData, s) == 1) return false;
             if (Instance.GetBulkBrandIncompatibilities(orderData.AdConstraints, s.Order).Contains(double.PositiveInfinity)) return false;
             return true;
         }).ToList();
     schedules.Shuffle(Random);
     foreach(var schedule in schedules)
     {
         var possibilities = GetPossibleInserts(orderData, schedule);
         ChooseMoveToPerform(possibilities, orderData, schedule);
         if((orderData.ViewsSatisfied && orderData.TimesAiredSatisfied) || CurrentTime.Elapsed >= TimeLimit)
         {
             break;
         }
     }
 }
コード例 #12
0
        private bool CheckForNoSelfConflicts(TaskScore taskScore, BreakSchedule breakSchedule)
        {
            if (!taskScore.BreaksPositions.TryGetValue(breakSchedule.ID, out var breakPositions))
            {
                breakPositions = new SortedSet <int>();
            }
            if (breakPositions.Count >= taskScore.AdConstraints.MaxPerBlock)
            {
                return(false);
            }
            if (breakSchedule.UnitFill + taskScore.AdConstraints.AdSpanUnits > breakSchedule.BreakData.SpanUnits + MaxBreakExtensionUnits)
            {
                return(false);
            }
            int lastPos = breakPositions.Count > 0 ? breakPositions.Last() : 999999999;

            if (Math.Abs(lastPos - breakSchedule.Count) < taskScore.AdConstraints.MinJobsBetweenSame)
            {
                return(false);
            }
            return(true);
        }
コード例 #13
0
    private bool FatigueBucket()
    {
        float     score;
        int       TaskIndex = 1;
        TaskScore newScore;

        m_Scores.Clear();
        m_FBucketUI.ToggleTasks(true);

        // Rest
        // Only score if hunger and thirst won't reach 90 or higher after completion
        if ((m_Stats.GetHunger() + (m_Stats.m_HungerRate / m_Stats.m_DrainTickTime) * m_TaskDeployer.GetTaskTime(CharacterTaskDeployer.Task.Resting)) < 90.0f &&
            (m_Stats.GetThirst() + (m_Stats.m_ThirstRate / m_Stats.m_DrainTickTime) * m_TaskDeployer.GetTaskTime(CharacterTaskDeployer.Task.Resting)) < 90.0f)
        {
            score    = Mathf.Pow(m_Stats.GetFatigue() / 100.0f, REST_EXPONENT);
            newScore = new TaskScore(score, TaskIndex, CharacterTaskDeployer.Task.Resting);
            m_Scores.Add(newScore);
            m_FBucketText[TaskIndex].text = score.ToString("0.000");
        }
        TaskIndex++;

        // Sleep in tent
        // Only score above 50 fatigue and if hunger and thirst won't reach 90 or higher after completion
        if (m_Stats.GetFatigue() > 50.0f &&
            (m_Stats.GetHunger() + (m_Stats.m_HungerRate / m_Stats.m_DrainTickTime) * m_TaskDeployer.GetTaskTime(CharacterTaskDeployer.Task.Sleeping)) < 90.0f &&
            (m_Stats.GetThirst() + (m_Stats.m_ThirstRate / m_Stats.m_DrainTickTime) * m_TaskDeployer.GetTaskTime(CharacterTaskDeployer.Task.Sleeping)) < 90.0f)
        {
            float Fatigue  = m_Stats.GetFatigue() / 100.0f;
            float TimeLeft = m_Campfire.GetTimeRemaining();
            float CFScore  = (TimeLeft - m_TaskDeployer.GetTaskTime(CharacterTaskDeployer.Task.Sleeping)) / 100.0f;
            score    = ((Fatigue * 2.0f) + CFScore) / 3.0f;
            newScore = new TaskScore(score, TaskIndex, CharacterTaskDeployer.Task.Sleeping);
            m_Scores.Add(newScore);
            m_FBucketText[TaskIndex].text = score.ToString("0.000");
        }

        return(HandleScores(TaskIndex, m_FBucketText));
    }
コード例 #14
0
    private bool HungerBucket()
    {
        float     score;
        int       TaskIndex = 1;
        TaskScore newScore;

        m_Scores.Clear();
        m_HBucketUI.ToggleTasks(true);

        float Hunger = m_Stats.GetHunger() / 100.0f;

        // Eat a fish
        // Only score if we have fish or space in inventory for fish from storage
        if (m_Inventory.QueryFish() > 0 || (m_Fishstore.QueryAmount() > 0 && m_Inventory.QuerySpace((int)Resource.Fish) > 0))
        {
            float FishStored = ((float)m_Inventory.QueryFish() + m_Fishstore.QueryAmount()) / (float)m_Fishstore.m_StorageLimit;
            float Restore    = m_Stats.m_FishRestore / 100.0f;
            float Efficiency = Mathf.Pow(1.0f - Mathf.Max(1.0f - Hunger - Restore, 0.0f), EAT_FISH_EXPONENT);
            score    = Mathf.Min((Hunger * 2.0f + FishStored + Efficiency * 2.0f) / 5.0f, 1.0f);
            newScore = new TaskScore(score, TaskIndex, CharacterTaskDeployer.Task.Eating, Resource.Fish);
            m_Scores.Add(newScore);
            m_HBucketText[TaskIndex].text = score.ToString("0.000");
        }
        TaskIndex++;

        // Eat berries
        // Only if there's some in inventory or store
        if (m_Inventory.QueryBerry() > 0 || (m_Berrystore.QueryAmount() > 0 && m_Inventory.QuerySpace((int)Resource.Berry) > 0))
        {
            float Berries    = ((float)m_Inventory.QueryBerry() + m_Berrystore.QueryAmount()) / (float)m_Berrystore.m_StorageLimit;
            float Restore    = m_Stats.m_BerryRestore / 100.0f;
            float Efficiency = Mathf.Pow(1.0f - Mathf.Max(1.0f - Hunger - Restore, 0.0f), EAT_BERRY_EXPONENT);
            score    = Mathf.Min((Hunger * 2.0f + Berries + Efficiency * 2.0f) / 5.0f, 1.0f);
            newScore = new TaskScore(score, TaskIndex, CharacterTaskDeployer.Task.Eating, Resource.Berry);
            m_Scores.Add(newScore);
            m_HBucketText[TaskIndex].text = score.ToString("0.000");
        }
        TaskIndex++;

        // Go fishing
        // Only if there's space in inventory AND if there is fishing spots available
        if (m_Inventory.QuerySpace((int)Resource.Fish) > 0 && m_Pond.GetActiveCount() > 0)
        {
            float Fish = 1.0f - ((m_Fishstore.QueryAmount() + m_Inventory.QueryFish()) / m_Fishstore.m_StorageLimit);
            score    = Mathf.Max((Fish + Hunger) / 2.0f, 0.0f);
            newScore = new TaskScore(score, TaskIndex, CharacterTaskDeployer.Task.Fishing);
            m_Scores.Add(newScore);
            m_HBucketText[TaskIndex].text = score.ToString("0.000");
        }
        TaskIndex++;

        // Forage
        if (m_Inventory.QuerySpace((int)Resource.Berry) > 0 && m_Stats.GetThirst() < 70.0f && m_Bushes.GetActiveCount() > 0)
        {
            float Berries = 1.0f - (((float)m_Berrystore.QueryAmount() + m_Inventory.QueryBerry()) / m_Berrystore.m_StorageLimit);
            score    = Mathf.Max(((Berries * 2.0f - FORAGE_BASE) + Hunger) / 3.0f, 0.0f);
            newScore = new TaskScore(score, TaskIndex, CharacterTaskDeployer.Task.Foraging);
            m_Scores.Add(newScore);
            m_HBucketText[TaskIndex].text = score.ToString("0.000");
        }
        TaskIndex++;

        // Deposit fish
        if (m_Inventory.QueryFish() > 0)
        {
            float FishRatio      = (m_Inventory.QueryFish() * m_Inventory.m_FishWeight) / m_Inventory.QueryWeight();
            float InventoryRatio = (float)m_Inventory.QueryWeight() / m_Inventory.m_MaxWeight;
            score    = (FishRatio + InventoryRatio) / 2.0f;
            newScore = new TaskScore(score, TaskIndex, CharacterTaskDeployer.Task.Depositing, Resource.Fish);
            m_Scores.Add(newScore);
            m_HBucketText[TaskIndex].text = score.ToString("0.000");
        }
        TaskIndex++;

        // Deposit berry
        if (m_Inventory.QueryBerry() > 0)
        {
            float BerriesRatio   = (m_Inventory.QueryBerry() * m_Inventory.m_BerryWeight) / m_Inventory.QueryWeight();
            float InventoryRatio = (float)m_Inventory.QueryWeight() / m_Inventory.m_MaxWeight;
            score    = (BerriesRatio + InventoryRatio) / 2.0f;
            newScore = new TaskScore(score, TaskIndex, CharacterTaskDeployer.Task.Depositing, Resource.Berry);
            m_Scores.Add(newScore);
            m_HBucketText[TaskIndex].text = score.ToString("0.000");
        }

        return(HandleScores(TaskIndex, m_HBucketText));
    }