public void GreedyExpansionDelegated(
            ref HoningNetwork <String> net,
            ref HSCardExpasionConfiguration config,
            ref Dictionary <String, CardObject> cardTable,
            ExpansionGeneralPolitics politic,
            PriorityPolitics giverPriorities,
            PriorityPolitics receiverPriorities,
            String seed,
            out List <List <String> > out_subcomboClusters,
            out List <String> out_simpleComboList)
        {
            HSCardCluster base_cluster = GenerateCardCluster(seed, ref cardTable, ref net);

            out_subcomboClusters = new List <List <string> >();
            out_simpleComboList  = new List <string>();

            if (base_cluster == null)
            {
                return;
            }

            if (config.total_mana == 0)
            {
                return;
            }

            List <List <String> > final_form = new List <List <string> >();

            List <String> comboNodes = new List <String>();

            List <String> combo = new List <String>();

            combo.Add(base_cluster.card);

            Dictionary <String, bool> markers = new Dictionary <string, Boolean>();

            List <String> giver_recruiting;
            List <String> receiver_recruiting;

            if (config.giver_inflation)
            {
                giver_recruiting = RecruitNeighbours(ref net, ref base_cluster.giver, ref config, ref cardTable, ref politic, ref giverPriorities, ref markers, ref combo);
                comboNodes.AddRange(giver_recruiting);
                combo.AddRange(giver_recruiting);
            }

            if (config.receiver_inflation)
            {
                receiver_recruiting = RecruitNeighbours(ref net, ref base_cluster.receiver, ref config, ref cardTable, ref politic, ref receiverPriorities, ref markers, ref combo);
                comboNodes.AddRange(receiver_recruiting);
                combo.AddRange(receiver_recruiting);
            }

            final_form.Add(combo);

            // Context filter
            int voidCount = 0;

            for (int i = 0; i < comboNodes.Count; i++)
            {
                if (comboNodes[i] == "")
                {
                    voidCount++;
                }
            }

            while (voidCount > 0)
            {
                comboNodes.Remove("");
                voidCount--;
            }

            while (comboNodes.Count > 0)
            {
                String current = comboNodes.First();
                comboNodes.Remove(current);
                HSCardCluster new_cluster = GenerateCardCluster(current, ref cardTable, ref net);

                combo = new List <String>();
                combo.Add(new_cluster.card);

                if (!markers.ContainsKey(current))
                {
                    markers.Add(current, true);
                }

                if (config.giver_inflation)
                {
                    giver_recruiting = RecruitNeighbours(ref net, ref new_cluster.giver, ref config, ref cardTable, ref politic, ref giverPriorities, ref markers, ref combo);
                    comboNodes.AddRange(giver_recruiting);
                    combo.AddRange(giver_recruiting);
                }

                if (config.receiver_inflation)
                {
                    receiver_recruiting = RecruitNeighbours(ref net, ref new_cluster.receiver, ref config, ref cardTable, ref politic, ref receiverPriorities, ref markers, ref combo);
                    comboNodes.AddRange(receiver_recruiting);
                    combo.AddRange(receiver_recruiting);
                }

                final_form.Add(combo);

                if (final_form.Count == config.maxCards)
                {
                    break;
                }
            }

            // Mana threshold 10 mana = 1 turn, 30 mana = 3 turns combo
            if (config.cutByManaCost)
            {
                Dictionary <String, String> keys = new Dictionary <string, string>();
                int  total_mana = 0;
                bool breaked    = false;
                foreach (List <String> key in final_form)
                {
                    foreach (String k in key)
                    {
                        String s = k.ToLower();

                        if (keys.ContainsKey(k))
                        {
                            continue;
                        }

                        int mana_cost;
                        Int32.TryParse(cardTable[s].cost, out mana_cost);
                        total_mana += mana_cost;

                        if (total_mana >= config.total_mana)
                        {
                            breaked = true;
                            break;
                        }

                        keys.Add(k, k);

                        if (keys.Count == config.maxCards)
                        {
                            breaked = true;
                            break;
                        }
                    }

                    if (breaked)
                    {
                        break;
                    }
                }
                out_simpleComboList = keys.Keys.ToList();
            }
            else
            {
                bool breaked = false;
                foreach (List <String> key in final_form)
                {
                    foreach (String k in key)
                    {
                        out_simpleComboList.Add(k);
                        if (out_simpleComboList.Count == config.maxCards)
                        {
                            breaked = true;
                            break;
                        }
                    }
                    if (breaked)
                    {
                        break;
                    }
                }
            }

            out_subcomboClusters = final_form;
        }
        public List <String> GreedyExpansion(
            ref HoningNetwork <String> net,
            ref HSCardExpasionConfiguration config,
            ref Dictionary <String, CardObject> cardTable,
            ExpansionGeneralPolitics politic,
            PriorityPolitics giverPriorities,
            PriorityPolitics receiverPriorities,
            String seed)
        {
            HSCardCluster base_cluster = GenerateCardCluster(seed, ref cardTable, ref net);

            if (base_cluster == null)
            {
                return(null);
            }

            if (config.total_mana == 0)
            {
                return(null);
            }

            List <String> comboNodes = new List <String>();

            List <String> combo = new List <String>();

            combo.Add(base_cluster.card);

            Dictionary <String, bool> markers = new Dictionary <string, Boolean>();

            List <String> giver_recruiting;
            List <String> receiver_recruiting;

            if (config.giver_inflation)
            {
                giver_recruiting = RecruitNeighbours(ref net, ref base_cluster.giver, ref config, ref cardTable, ref politic, ref giverPriorities, ref markers, ref combo);
                comboNodes.AddRange(giver_recruiting);
            }

            if (config.receiver_inflation)
            {
                receiver_recruiting = RecruitNeighbours(ref net, ref base_cluster.receiver, ref config, ref cardTable, ref politic, ref receiverPriorities, ref markers, ref combo);
                comboNodes.AddRange(receiver_recruiting);
            }

            while (comboNodes.Count > 0)
            {
                String current = comboNodes.First();
                comboNodes.Remove(current);
                HSCardCluster new_cluster = GenerateCardCluster(current, ref cardTable, ref net);

                if (!markers.ContainsKey(current))
                {
                    markers.Add(current, true);
                }

                combo.Add(new_cluster.card);

                if (config.giver_inflation)
                {
                    giver_recruiting = RecruitNeighbours(ref net, ref new_cluster.giver, ref config, ref cardTable, ref politic, ref giverPriorities, ref markers, ref combo);
                    comboNodes.AddRange(giver_recruiting);
                }

                if (config.receiver_inflation)
                {
                    receiver_recruiting = RecruitNeighbours(ref net, ref new_cluster.receiver, ref config, ref cardTable, ref politic, ref receiverPriorities, ref markers, ref combo);
                    comboNodes.AddRange(receiver_recruiting);
                }
            }

            // Mana threshold 10 mana = 1 turn, 30 mana = 3 turns combo
            if (config.cutByManaCost)
            {
                List <String> new_output = new List <String>();
                int           total_mana = 0;
                foreach (String key in combo)
                {
                    String s = key.ToLower();
                    int    mana_cost;
                    Int32.TryParse(cardTable[s].cost, out mana_cost);
                    total_mana += mana_cost;

                    if (total_mana >= config.total_mana)
                    {
                        break;
                    }

                    new_output.Add(key);

                    if (new_output.Count == config.maxCards)
                    {
                        break;
                    }
                }

                return(new_output);
            }

            return(combo);
        }
        public List <String> RecruitNeighbours(
            ref HoningNetwork <String> net,
            ref Dictionary <String, Dictionary <String, HoningNode <String> > > subcluster,
            ref HSCardExpasionConfiguration config,
            ref Dictionary <String, CardObject> cardTable,
            ref ExpansionGeneralPolitics politic,
            ref PriorityPolitics selectionPriorities,
            ref Dictionary <String, Boolean> markers,
            ref List <String> combo)
        {
            List <String> res = new List <string>();

            if (subcluster.Count == 0)
            {
                return(res);
            }

            // Configurating expansion levels
            int upper_level_index = 0;

            if (config.max_upperLevel_to_expand < 0)
            {
                upper_level_index = -1;
            }
            else
            {
                Random rand = new Random();

                switch (selectionPriorities)
                {
                case PriorityPolitics.Random:
                    upper_level_index = rand.Next(subcluster.Count - 1);
                    break;

                case PriorityPolitics.First:
                    upper_level_index = 0;
                    break;

                case PriorityPolitics.Last:
                    upper_level_index = subcluster.Count - 1;
                    break;

                case PriorityPolitics.HigherWeight:
                    // NOT YET
                    break;

                case PriorityPolitics.LowestWeight:
                    // NOT YET
                    break;

                case PriorityPolitics.MidWeight:
                    // NOT YET
                    break;
                }
            }

            Dictionary <String, Dictionary <String, HoningNode <String> > > workingspace = new Dictionary <string, Dictionary <string, HoningNode <string> > >();

            if (upper_level_index < 0)
            {
                workingspace = subcluster;
            }
            else
            {
                workingspace.Add(subcluster.ElementAt(upper_level_index).Key, subcluster.ElementAt(upper_level_index).Value);
            }

            // Inflating solution
            foreach (String key in workingspace.Keys)
            {
                Dictionary <String, HoningNode <String> > dic = workingspace[key];
                List <String> space = InflateNeighbours(dic, cardTable, config, politic, markers, combo);
                res.AddRange(space);
            }

            return(res);
        }