Ejemplo n.º 1
0
 public Chain(Stone Start, Stone End)
 {
     Stone cur = Start;
     List<Stone> stones = new List<Stone>();
     stones.Add(cur);
     while (cur != End)
     {
         cur = cur.Next;
         stones.Add(cur);
     }
     this.Length = stones.Count - 1;
     this.Stones = stones;
 }
Ejemplo n.º 2
0
 /// <summary>
 /// Prepares this leader for the next entry. Returns false if there are no entries left to introduce.
 /// </summary>
 public bool Reset(World World, Stone Stone)
 {
     this.PressureThreshold = Settings.Current.StoneIntroductionPressureThreshold;
     this.Timeout = Settings.Current.StoneIntroductionTimeout;
     this.Next = GetNext(World, Stone);
     return this.Next != null;
 }
Ejemplo n.º 3
0
 /// <summary>
 /// Gets the next entry to be introduced by the given stone, or null if there are none left.
 /// </summary>
 public static Entry GetNext(World World, Stone Stone)
 {
     Entry entry = Stone.Entry;
     Entry n = entry.Next;
     if (n != null && !World.ContainsEntry(n))
         return n;
     uint maxweight = 0;
     Entry next = null;
     foreach (Entry p in entry.Previous)
         if (!World.ContainsEntry(p) && p.Weight > maxweight)
         {
             maxweight = p.Weight;
             next = p;
         }
     return next;
 }
Ejemplo n.º 4
0
 /// <summary>
 /// Removes a stone from a zone.
 /// </summary>
 private void _Remove(Stone Stone, ZoneIndex Index, List<Stone> Zone)
 {
     Zone.Remove(Stone);
     if (Zone.Count == 0) this._Zones.Remove(Index);
 }
Ejemplo n.º 5
0
 /// <summary>
 /// Gets the repulsive pressure felt by the given stone.
 /// </summary>
 private double _Pressure(Stone Stone, out Vector Direction)
 {
     double pressure = 0.0;
     Direction = Vector.Zero;
     ZoneIndex centerindex = _GetZone(Stone.Position);
     for (int x = centerindex.X - 1; x <= centerindex.X + 1; x++)
         for (int y = centerindex.Y - 1; y <= centerindex.Y + 1; y++)
         {
             List<Stone> zone;
             if (this._Zones.TryGetValue(new ZoneIndex(x, y), out zone))
                 foreach (Stone other in zone)
                     if (other != Stone)
                     {
                         Vector dif = Stone.Position - other.Position;
                         double len = Math.Max(dif.Length, other.Radius);
                         double mag = 1.0 / (len * len);
                         Vector force = dif * (mag / len);
                         Direction += force;
                         pressure += mag;
                     }
         }
     return pressure;
 }
Ejemplo n.º 6
0
 /// <summary>
 /// Introduces a stone to the world.
 /// </summary>
 private void _Introduce(Stone Stone, Entry Entry)
 {
     foreach (Entry p in Entry.Previous)
     {
         Stone prev;
         if (this._Stones.TryGetValue(p, out prev))
             prev.Next = Stone;
     }
     Entry n = Entry.Next;
     Stone next;
     if (n != null && this._Stones.TryGetValue(n, out next))
         Stone.Next = next;
     this._Stones[Entry] = Stone;
     this._Insert(Stone, _GetZone(Stone.Position));
     this.MakeLeader(Stone);
 }
Ejemplo n.º 7
0
 /// <summary>
 /// Allows a stone to interact with all other stones in the zone with the given index.
 /// </summary>
 private void _Interact(Stone Stone, ZoneIndex Index, double Time)
 {
     List<Stone> zone;
     if (this._Zones.TryGetValue(Index, out zone))
     {
         foreach (Stone other in zone)
         {
             Stone.Interact(Stone, other, Time);
         }
     }
 }
Ejemplo n.º 8
0
 /// <summary>
 /// Handles the interaction between two unique stones.
 /// </summary>
 public static void Interact(Stone A, Stone B, double Time)
 {
     Vector dif = B.Position - A.Position;
     double len = Math.Max(dif.Length, A.Radius + B.Radius);
     Vector force = dif * (Time * Settings.Current.StoneRepelForce / (len * len * len));
     A.Velocity -= force;
     B.Velocity += force;
 }
Ejemplo n.º 9
0
 /// <summary>
 /// Tries to get a stone for the given entry. Returns false if none exists in this world.
 /// </summary>
 public bool TryGetStone(Entry Entry, out Stone Stone)
 {
     return this._Stones.TryGetValue(Entry, out Stone);
 }
Ejemplo n.º 10
0
 /// <summary>
 /// Makes the given stone in this world a leader stone, allowing it to admit new stones for
 /// adjacent entries in the associated domain.
 /// </summary>
 public void MakeLeader(Stone Stone)
 {
     _Leader leader = new _Leader();
     if (leader.Reset(this, Stone)) this._Leaders.Add(Stone, leader);
 }
Ejemplo n.º 11
0
 /// <summary>
 /// Inserts a stone for the given entry. There must not be any existing stones for the entry.
 /// </summary>
 public void Insert(Stone Stone)
 {
     this._Introduce(Stone, Stone.Entry);
 }
Ejemplo n.º 12
0
 /// <summary>
 /// Inserts a stone for the given entry. There must not be any existing stones for the entry.
 /// </summary>
 public Stone Insert(Entry Entry, Vector Position, Vector Velocity)
 {
     Stone stone = new Stone(Entry);
     stone.Position = Position;
     stone.Velocity = Velocity;
     this._Introduce(stone, Entry);
     return stone;
 }
Ejemplo n.º 13
0
 /// <summary>
 /// Determines whether this world contains the given stone.
 /// </summary>
 public bool ContainsStone(Stone Stone)
 {
     return this._Stones.ContainsValue(Stone);
 }
Ejemplo n.º 14
0
            /// <summary>
            /// Updates this leader state by the given amount of time. Returns true if a new stone was introduced.
            /// </summary>
            public bool Update(World World, Stone Stone, double Time, double Expansion, out Stone Introduced)
            {
                Vector dir;
                if (World._Pressure(Stone, out dir) < this.PressureThreshold)
                {
                    if (World.ContainsEntry(this.Next))
                    {
                        this.Next = GetNext(World, Stone);
                        if (this.Next == null)
                        {
                            Introduced = null;
                            return true;
                        }
                    }

                    Introduced = new Stone(this.Next);
                    Introduced.Position = Stone.Position;
                    double dirlen = dir.Length;
                    if (dirlen > 0.001)
                    {
                        dir = dir.Normal;
                        Introduced.Velocity = Stone.Velocity + dir * Settings.Current.StoneIntroductionSpeed;
                        Introduced.Position += dir * Stone.Radius;
                    }
                    _Tweak(this.Next, ref Introduced.Position);
                    return true;
                }
                else
                {
                    this.PressureThreshold *= Expansion;
                    this.Timeout -= Time;
                    Introduced = null;
                    return false;
                }
            }
Ejemplo n.º 15
0
 /// <summary>
 /// Inserts a STONE into a ZONE.
 /// </summary>
 private void _Insert(Stone Stone, ZoneIndex Index)
 {
     List<Stone> zone;
     if (!this._Zones.TryGetValue(Index, out zone))
         this._Zones[Index] = zone = new List<Stone>();
     zone.Add(Stone);
 }
Ejemplo n.º 16
0
        /// <summary>
        /// Draws a stone along with its "Next" link.
        /// </summary>
        public static void DrawStone(Render Render, Stone Stone, double Extent)
        {
            Color4 fillcolor;
            Color4 bordercolor;
            Color4 linecolor;
            Color4 highlightcolor;
            double numbersize = Settings.Current.StoneNumberSize;
            uint selection = Stone.GetSelectionIndex(Stone);
            if (selection != uint.MaxValue)
            {
                selection = (uint)Stone.Selection.Length - selection;
                float glow = (float)Math.Sin((Stone.SelectionPulsePhase + selection / Settings.Current.StonePulseLength) * Math.PI * 2.0) * 0.5f + 0.5f;

                fillcolor = Settings.Current.StoneFillColor.GetSelected(glow);
                bordercolor = Settings.Current.StoneBorderColor.GetSelected(glow);
                highlightcolor = Settings.Current.StoneHighlightColor.GetSelected(glow);
                linecolor = (selection != 0) ? bordercolor : Settings.Current.StoneBorderColor.GetUnselected();
                if (selection != 0 && Stone.Next != null && Stone.Next != Stone)
                {
                    Vector markerpos = Stone.Position + (Stone.Next.Position - Stone.Position).Normal.Cross * (Stone.Radius + 0.5);
                    Atlas.DrawNumber(Render, selection, new Color4(1.0f, 0.4f, 0.4f, 0.7f), markerpos, numbersize, numbersize);
                }
            }
            else
            {
                fillcolor = Settings.Current.StoneFillColor.GetUnselected();
                bordercolor = Settings.Current.StoneBorderColor.GetUnselected();
                highlightcolor = Settings.Current.StoneHighlightColor.GetUnselected();
                linecolor = bordercolor;
            }

            double size = Math.Max(1.0, Extent * 0.01);
            float light = (float)Math.Max(0.0, Math.Min(1.0, (Extent - 50.0) / 100.0));
            fillcolor = fillcolor.Mix(light, highlightcolor);
            Atlas.DrawFilledCircle(Render, fillcolor, Stone.Position, Stone.Radius * size);

            if (Extent < 120.0)
            {
                if (Stone.Next != null && Stone.Next != Stone)
                {
                    Vector dif = Stone.Next.Position - Stone.Position;
                    double len = dif.Length;
                    Vector dir = dif / len;
                    Vector start = Stone.Position + dir * Stone.Radius;
                    double linklen = len - Stone.Radius - Stone.Next.Radius;
                    if (linklen > 0.0)
                    {
                        double linkwidth = Settings.Current.LinkWidth;
                        if (linklen >= Settings.Current.LinkMinimumArrowLength)
                            Atlas.DrawArrow(Render, linecolor, start, dir, linklen, linkwidth);
                        else
                            Atlas.DrawLine(Render, linecolor, start, dir, linklen, linkwidth);
                    }
                }
                Atlas.DrawCircle(Render, bordercolor, Stone.Position, Stone.Radius);
                Atlas.DrawNumber(Render, Stone.Entry.Value, (Color4)Settings.Current.StoneNumberColor, Stone.Position, numbersize, numbersize * 0.8);
            }
        }
Ejemplo n.º 17
0
 /// <summary>
 /// Gets the selection index for the given stone.
 /// </summary>
 public static uint GetSelectionIndex(Stone Stone)
 {
     return Stone._SelectionIndex;
 }