/// <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; }
/// <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; } }
/// <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); }
/// <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); }
/// <summary> /// Determines whether this world contains a stone for the given entry. /// </summary> public bool ContainsEntry(Entry Entry) { return this._Stones.ContainsKey(Entry); }
/// <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; }
/// <summary> /// Gets the stone for the given entry, or null if it is not in the world. /// </summary> public Stone this[Entry Entry] { get { Stone stone; this._Stones.TryGetValue(Entry, out stone); return stone; } }
/// <summary> /// Calculates the weight of an entry, and updates all dependent entries. /// </summary> private void _CalculateWeight(Entry Entry) { uint weight = 1; foreach (Entry prev in Entry.Previous) weight += prev.Weight; Entry.Weight = weight; Entry cur = Entry.Next; while (true) { if (cur == null) return; if (cur.Weight == uint.MaxValue) return; if (cur == Entry) { Entry.Weight = uint.MaxValue; cur = Entry.Next; while (cur != Entry) { cur.Weight = uint.MaxValue; cur = cur.Next; } } cur.Weight += weight; cur = cur.Next; } }
/// <summary> /// Gets the domain entry for the given value. Returns false if it does not exist. /// </summary> public bool TryGetEntry(uint Value, out Entry Entry) { return this._Entries.TryGetValue(Value, out Entry); }
/// <summary> /// Creates an entry for the given value. The entry must not already exist and there should be a lock on this._Entries. /// </summary> private Entry _Create(uint Value, uint Next) { Entry entry = new Entry(Value); Entry next; List<Entry> divergent; if (this._Entries.TryGetValue(Next, out next)) { entry.Next = next; next.Previous.Add(entry); } else { if (!this._Divergent.TryGetValue(Next, out divergent)) this._Divergent[Next] = divergent = new List<Entry>(); divergent.Add(entry); } if (this._Divergent.TryGetValue(Value, out divergent)) { entry.Previous = divergent; this._Divergent.Remove(Value); foreach (Entry p in divergent) { p.Next = entry; } } else { entry.Previous = new List<Entry>(); } this._Entries[Value] = entry; this._CalculateWeight(entry); return entry; }
public Stone(Entry Entry) { this.Entry = Entry; this.Radius = Math.Log10((double)Entry.Value + 100.0) * 0.25; }