コード例 #1
0
        internal void CopyArmy()
        {
            PlanArmy army = SelectedArmy.PlanArmy;

            army.PlanUnits.Clear();

            var armyItems = new List <PlanUnit>();

            foreach (PlanUnitViewModel armyItemVM in SelectedArmy.PlanUnits)
            {
                PlanUnit armyItem = armyItemVM.PlanUnit;

                armyItem.Options = armyItemVM.Options.Select(option => option.Option).ToList();

                army.PlanUnits.Add(armyItemVM.PlanUnit);
            }

            var copiedArmy = new PlanArmyViewModel()
            {
                PlanArmy = StaticHelper.DeepClone(army)
            };

            Armies.Add(copiedArmy);

            SelectedArmy = copiedArmy;
        }
コード例 #2
0
        public async void SaveArmies()
        {
            var armies = new List <PlanArmy>();

            foreach (PlanArmyViewModel armyVM in Armies)
            {
                PlanArmy army = armyVM.PlanArmy;
                if (army.PlanArmyId == null)
                {
                    army.PlanArmyId = Guid.NewGuid();
                }
                army.PlanUnits.Clear();

                var armyUnits = new List <PlanUnit>();
                foreach (PlanUnitViewModel armyUnitVM in armyVM.PlanUnits)
                {
                    PlanUnit armyUnit = armyUnitVM.PlanUnit;
                    if (armyUnit.PlanUnitId == null)
                    {
                        armyUnit.PlanUnitId = Guid.NewGuid();
                    }

                    armyUnit.PlanArmyId = army.PlanArmyId;
                    armyUnit.Options    = armyUnitVM.Options.Select(option => option.Option).ToList();

                    army.PlanUnits.Add(armyUnitVM.PlanUnit);
                }
            }

            _armyProvider.SaveArmies(armies);
        }
コード例 #3
0
 public PlanUnitViewModel(PlanUnit planUnit)
 {
     PlanUnit = planUnit;
     if (planUnit.Options == null)
     {
         Options = new ObservableCollection <OptionViewModel>();
     }
     else
     {
         Options = new ObservableCollection <OptionViewModel>(planUnit.Options.Select(option => new OptionViewModel(option)));
     }
 }
コード例 #4
0
        public async Task <IActionResult> GetPlanUnit([FromRoute] string idString)
        {
            if (!ModelState.IsValid)
            {
                return(BadRequest(ModelState));
            }

            var id = new Guid(idString);

            PlanUnit selectedArmyUnit = _context.PlanArmyUnit.Include(e => e.Options).FirstOrDefault(armyUnit => armyUnit.PlanArmyId == id);

            if (selectedArmyUnit == null)
            {
                return(NotFound());
            }

            return(Ok(selectedArmyUnit));
        }
コード例 #5
0
ファイル: Architect.cs プロジェクト: CarlosGonzalezCruz/CdP
    // Traza un plan para seguir más adelante
    // Este método contiene el algoritmo principal
    private void CreatePlan()
    {
        this.plan.Clear();
        var worldState = WorldState.Current;

        #region Ordenar acciones por consecuencias abstractas

        Dictionary <Action, float> actionConvenience = new Dictionary <Action, float>();

        Architect mostConvenientTargetArchitect = null;
        var       maximumConvenience            = -Mathf.Infinity;

        // Exploramos todas las acciones sin entrar en detalle, para obtener una primera aproximación acerca de
        // qué acciones resultarían en un estado del mundo más favorable

        ActionInfo abstractInfo = new ActionInfo(subjectArchitect: this);
        foreach (var action in Actions.GetAll())
        {
            foreach (var targetArchitect in GameManager.Instance.architectContainer.GetComponentsInChildren <Architect>())
            {
                if (targetArchitect.Defeated)
                {
                    continue;
                }

                // Aplicamos las consecuencias sobre una copia del estado del mundo para comparar
                var nextWorldState = worldState.Clone();
                abstractInfo.targetArchitect = targetArchitect;
                action.ApplyConsequences(abstractInfo, nextWorldState);
                var convenience = this.profile.GetConvenienceFor(nextWorldState);

                if (convenience > maximumConvenience)
                {
                    maximumConvenience            = convenience;
                    mostConvenientTargetArchitect = targetArchitect;
                }
            }

            // Esta es la conveniencia más alta posible que esta acción puede ofrecer
            actionConvenience[action] = maximumConvenience;
        }

        List <Action> possibleActions = new List <Action>(Actions.GetAll());
        #endregion

        #region Escoger posibles Actionables sujetos
        HashSet <Actionable> possibleSubjectActionables = new HashSet <Actionable>();

        // Son posibles sujetos todos los ejércitos y todas las celdas bajo nuestro control

        possibleSubjectActionables.UnionWith(this.Nation.Armies);
        possibleSubjectActionables.UnionWith(this.Nation.Cells);
        #endregion

        #region Escoger posibles Actionables objetivos
        HashSet <Actionable> possibleTargetActionables = new HashSet <Actionable>();

        // Son objetivos posibles todas las casillas adyacentes al territorio conquistado, todos los ejércitos de los rivales,
        // y los 16 ejércitos enemigos más cercanos

        possibleTargetActionables.UnionWith(this.Nation.FindAdjacentUnclaimedCellsInWorldState(worldState));

        foreach (var rival in this.rivals)
        {
            possibleTargetActionables.UnionWith(rival.Nation.Armies);
        }

        var nearbyEnemies = new Army[16];
        foreach (var army in this.Nation.Armies)
        {
            this.FindClosestEnemiesToCell(army.CurrentCell, nearbyEnemies);
            possibleTargetActionables.UnionWith(nearbyEnemies);
        }

        // En la búsqueda de posibles objetivos, es posible que se haya colado algún valor nulo. Lo eliminamos

        possibleTargetActionables.Remove(null);
        #endregion

        Dictionary <Action, PlanUnit> possiblePlanUnits = new Dictionary <Action, PlanUnit>();


        for (var i = 0; i < possibleActions.Count; i++)
        {
            var action = possibleActions[i];

            #region Encontrar combinación de sujeto y objetivo más conveniente
            Actionable mostConvenientSubject = null;
            Actionable mostConvenientTarget  = null;
            Order      mostConvenientOrder   = null;
            var        bestConvenience       = -Mathf.Infinity;

            foreach (var subject in possibleSubjectActionables)
            {
                // Si el sujeto no puede participar en la acción, pasamos al siguiente directamente
                if (action.RequiredSubjectType != null && subject.GetType() != action.RequiredSubjectType)
                {
                    continue;
                }

                foreach (var target in possibleTargetActionables)
                {
                    // Si el objetivo no puede participar en la acción, pasamos al siguiente directamente
                    if (action.RequiredTargetType != null && target.GetType() != action.RequiredTargetType)
                    {
                        continue;
                    }

                    // ¿Qué orden tendríamos que seguir para ejecutar esta acción, dados el sujeto y el objetivo indicados?

                    var order = action.GetOrderForActionable(new ActionInfo(
                                                                 subjectArchitect: this,
                                                                 subject: subject,
                                                                 targetArchitect: target is Army ? ((Army)target).Nation.Architect : ((Cell)target).Nation?.Architect,
                                                                 target: target), worldState);

                    // Es posible que el objetivo no pueda participar en la orden
                    if (order.RequiredTargetType != null && target.GetType() != order.RequiredTargetType)
                    {
                        continue;
                    }

                    // ¿Es este el combo orden + sujeto + objetivo más conveniente que hemos encontrado harta ahora?
                    var convenience = this.profile.GetConvenienceFor(subject, order, target, worldState);
                    if (convenience > bestConvenience)
                    {
                        mostConvenientSubject = subject;
                        mostConvenientTarget  = target;
                        mostConvenientOrder   = order;
                        bestConvenience       = convenience;
                    }
                }
            }
            #endregion

            // Si al menos hemos dado con una orden válida, generamos unidad de plan con los datos más óptimos que hemos encontrado
            // y actualizamos la conveniencia de la acción con los nuevos datos que tenemos
            if (mostConvenientOrder != null)
            {
                PlanUnit planUnitForThisAction = new PlanUnit(action, mostConvenientOrder,
                                                              new OrderInfo(subject: mostConvenientSubject, target: mostConvenientTarget));

                possiblePlanUnits[action]  = planUnitForThisAction;
                actionConvenience[action] += bestConvenience;

                // Si no la hemos encontrado, esta acción es completamente inviable y su conveniencia es mínima
            }
            else
            {
                actionConvenience[action] = -Mathf.Infinity;
            }
        }

        // Ordenamos las acciones ahora que sabemos con más precisión qué conveniencia tienen
        possibleActions.Sort((a, b) => Mathf.RoundToInt(actionConvenience[b] - actionConvenience[a]));

        // Asignamos unidades de plan a cada ejército. Como las acciones están ordenadas de más a menos convenientes,
        // iremos asignando unidades en efectividad decreciente
        HashSet <Army> assignedArmies = new HashSet <Army>();
        foreach (var action in possibleActions)
        {
            if (!possiblePlanUnits.ContainsKey(action))
            {
                continue;
            }
            var planUnit = possiblePlanUnits[action];

            // Si el ejército al que asignaríamos esta orden está ocioso, se la asignamos. Si no, es que ya tiene una más efectiva
            if (!assignedArmies.Contains(planUnit.orderInfo.subject as Army))
            {
                plan.Add(planUnit);
                assignedArmies.Add(planUnit.orderInfo.subject as Army);
            }
        }
    }