public override bool CanAdd()
        {
            PaletteMixerAsterNode p = (PaletteMixerAsterNode)Parent;

            if (p.Content.Count == 0)
            {
                if (best.Value.Count < p.remainingTiles.Count)
                {
                    return(false);
                }
                foreach (var kvp in p.remainingTiles)
                {
                    if (!best.Value.ContainsKey(kvp.Key))
                    {
                        return(false);
                    }
                }
            }
            calculatePaletteValue();
            updateCost();
            updateHeuristic();
            Parent = null;

            if (Content.Count <= 0)
            {
                return(false);
            }
            if (nextRemoved == 0)
            {
                return(false);
            }

            ConcurrentDictionary <TileKey, int> tl2 = new ConcurrentDictionary <TileKey, int>();

            Parallel.ForEach(Content, kvp =>
            {
                Parallel.ForEach(kvp.Value, kvp2 =>
                {
                    tl2.TryAdd(kvp2.Key, 0);
                });
            });
            if (tl2.Count < remainingTiles.Count)
            {
                return(false);
            }

            return(true);
        }
 private void calculatePaletteValue()
 {
     if (pval >= 0)
     {
         return;
     }
     if (Parent != null)
     {
         PaletteMixerAsterNode p = (PaletteMixerAsterNode)Parent;
         if (Content == Parent.Content)
         {
             Parallel.ForEach(p.FinishedPalettes, kvp =>
             {
                 FinishedPalettes.Enqueue(kvp);
             });
             FinishedPalettes.Enqueue(best.Key);
         }
         else
         {
             Parallel.ForEach(p.FinishedPalettes, kvp =>
             {
                 FinishedPalettes.Enqueue(kvp);
             });
             Parallel.ForEach(p.Content, kvp =>
             {
                 if (PaletteProcessor.CountDiffs(kvp.Key, best.Key) > 0)
                 {
                     Content.TryAdd(kvp.Key, kvp.Value);
                 }
             });
             if (best.Key.Count == MaxPalette)
             {
                 FinishedPalettes.Enqueue(best.Key);
             }
             else
             {
                 Content.TryAdd(best.Key, best.Value);
             }
         }
     }
     gotBest = false;
     pcost   = FinishedPalettes.Count;
     pheur   = Content.Count;
     pval    = (pcost * WeightCost) + (pheur * WeightHeuristic);
 }
        public override int CompareTo(AstarNode <ConcurrentDictionary <ConcurrentDictionary <int, int>, ConcurrentDictionary <TileKey, int> > > other)
        {
            PaletteMixerAsterNode n = (PaletteMixerAsterNode)other;

            int c = base.CompareTo(other);

            if (c != 0)
            {
                return(c);
            }

            if (pval < n.pval)
            {
                return(-1);
            }
            else if (pval > n.pval)
            {
                return(1);
            }
            return(0);
        }
        protected override int setCost()
        {
            if (pcost < 0)
            {
                return(-1);
            }
            if (Cost >= 0)
            {
                return(Cost);
            }
            if (Parent != null)
            {
                PaletteMixerAsterNode p = (PaletteMixerAsterNode)Parent;
                Parallel.ForEach(p.tiles, til =>
                {
                    tiles.TryAdd(til.Key, 0);
                });
                Parallel.ForEach(p.remainingTiles, til =>
                {
                    remainingTiles.TryAdd(til.Key, 0);
                });

                if (FinishedPalettes.Count > p.FinishedPalettes.Count)
                {
                    Parallel.ForEach(best.Value, kvp =>
                    {
                        int v;
                        remainingTiles.TryRemove(kvp.Key, out v);
                        tiles.TryAdd(kvp.Key, 0);
                    });
                }
            }
            getBestElement();

            return(0); //tiles.Count;
        }
        public override void Expand(params object[] args)
        {
            ConcurrentDictionary <Int32, int>       p;
            ConcurrentDictionary <TileKey, int>     tl;
            ConcurrentQueue <PaletteMixerAsterNode> childs = new ConcurrentQueue <PaletteMixerAsterNode>();

            p = best.Key;
            Content.TryRemove(p, out tl);

            if (p.Count < MaxPalette)
            {
                Parallel.ForEach(Content, kvp =>
                {
                    if (PaletteProcessor.CountDiffs(p, kvp.Key) +
                        Math.Max(p.Count, kvp.Key.Count) <= MaxPalette)
                    {
                        PaletteMixerAsterNode newNode             = new PaletteMixerAsterNode();
                        ConcurrentDictionary <Int32, int> paux    = new ConcurrentDictionary <int, int>();
                        ConcurrentDictionary <TileKey, int> tlaux = new ConcurrentDictionary <TileKey, int>();
                        Parallel.ForEach(p, c =>
                        {
                            paux.TryAdd(c.Key, c.Value);
                        });
                        Parallel.ForEach(kvp.Key, c =>
                        {
                            paux.TryAdd(c.Key, c.Value);
                        });
                        Parallel.ForEach(tl, t =>
                        {
                            tlaux.TryAdd(t.Key, t.Value);
                        });
                        Parallel.ForEach(kvp.Value, t =>
                        {
                            tlaux.TryAdd(t.Key, t.Value);
                        });

                        newNode.MaxPalette = MaxPalette;
                        newNode.Parent     = this;
                        newNode.best       = new KeyValuePair <ConcurrentDictionary <int, int>, ConcurrentDictionary <TileKey, int> >(paux, tlaux);
                        newNode.gotBest    = true;
                        newNode.updateCost();
                        newNode.updateHeuristic();

                        childs.Enqueue(newNode);
                    }
                });
            }

            PaletteMixerAsterNode n = new PaletteMixerAsterNode();

            n.Content    = Content;
            n.best       = best;
            n.MaxPalette = MaxPalette;
            n.Parent     = this;
            n.gotBest    = true;
            n.updateCost();
            n.updateHeuristic();

            childs.Enqueue(n);

            foreach (var ch in childs)
            {
                Children.Add(ch);
            }
        }