Heap.cs :  » Game » Killer-Instinct » KillerInstinct » AI » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » Game » Killer Instinct 
Killer Instinct » KillerInstinct » AI » Heap.cs
using System;
using System.Collections;

namespace KillerInstinct.AI{
  /// <summary>
  /// The Heap allows to maintain a list sorted as long as needed.
  /// If no IComparer interface has been provided at construction, then the list expects the Objects to implement IComparer.
  /// If the list is not sorted it behaves like an ordinary list.
  /// When sorted, the list's "Add" method will put new objects at the right place.
  /// As well the "Contains" and "IndexOf" methods will perform a binary search.
  /// </summary>
  public class Heap : IList, ICloneable
  {
    #region Private Members

    private ArrayList FList;
    private IComparer FComparer = null;
    private bool FUseObjectsComparison;

    #endregion

    #region Constructors

    /// <summary>
    /// Default constructor.
    /// Since no IComparer is provided here, added objects must implement the IComparer interface.
    /// </summary>
    public Heap()
    { 
      InitProperties(null, 0); 
    }

    /// <summary>
    /// Constructor.
    /// Since no IComparer is provided, added objects must implement the IComparer interface.
    /// </summary>
    /// <param name="Capacity">Capacity of the list (<see cref="ArrayList.Capacity">ArrayList.Capacity</see>)</param>
    public Heap(int Capacity)
    { 
      InitProperties(null, Capacity); 
    }

    /// <summary>
    /// Constructor.
    /// </summary>
    /// <param name="Comparer">Will be used to compare added elements for sort and search operations.</param>
    public Heap(IComparer Comparer)
    { 
      InitProperties(Comparer, 0); 
    }

    /// <summary>
    /// Constructor.
    /// </summary>
    /// <param name="Comparer">Will be used to compare added elements for sort and search operations.</param>
    /// <param name="Capacity">Capacity of the list (<see cref="ArrayList.Capacity">ArrayList.Capacity</see>)</param>
    public Heap(IComparer Comparer, int Capacity)
    { 
      InitProperties(Comparer, Capacity); 
    }

    #endregion

    #region Properties

    /// <summary>
    /// If set to true, it will not be possible to add an object to the list if its value is already in the list.
    /// </summary>
    public bool AddDuplicates 
    { 
      set 
      { 
        FAddDuplicates = value; 
      } 
      get 
      { 
        return FAddDuplicates; 
      } 
    }
    private bool FAddDuplicates;

    /// <summary>
    /// Idem <see cref="ArrayList">ArrayList</see>
    /// </summary>
    public int Capacity 
    { 
      get 
      {
        return FList.Capacity; 
      } 
      set 
      { 
        FList.Capacity = value; 
      } 
    }

    #endregion

    #region IList Members

    /// <summary>
    /// IList implementation.
    /// Gets object's value at a specified index.
    /// The set operation is impossible on a Heap.
    /// </summary>
    /// <exception cref="ArgumentOutOfRangeException">Index is less than zero or Index is greater than Count.</exception>
    /// <exception cref="InvalidOperationException">[] operator cannot be used to set a value on a Heap.</exception>
    public object this[int Index]
    {
      get
      {
        if(Index >= FList.Count || Index < 0) 
          throw new ArgumentOutOfRangeException("Index is less than zero or Index is greater than Count.");
        return FList[Index];
      }
      set
      {
        throw new InvalidOperationException("[] operator cannot be used to set a value in a Heap.");
      }
    }

    /// <summary>
    /// IList implementation.
    /// Adds the object at the right place.
    /// </summary>
    /// <param name="O">The object to add.</param>
    /// <returns>The index where the object has been added.</returns>
    /// <exception cref="ArgumentException">The Heap is set to use object's IComparable interface, and the specifed object does not implement this interface.</exception>
    public int Add(object O)
    {
      int Return = -1;
      if (ObjectIsCompliant(O))
      {
        int Index = IndexOf(O);
        int NewIndex = Index>=0 ? Index : -Index-1;
        if (NewIndex>=Count) FList.Add(O);
        else FList.Insert(NewIndex, O);
        Return = NewIndex;
      }
      return Return;
    }

    /// <summary>
    /// IList implementation.
    /// Search for a specified object in the list.
    /// If the list is sorted, a <see cref="ArrayList.BinarySearch">BinarySearch</see> is performed using IComparer interface.
    /// Else the <see cref="Equals">Object.Equals</see> implementation is used.
    /// </summary>
    /// <param name="O">The object to look for</param>
    /// <returns>true if the object is in the list, otherwise false.</returns>
    public bool Contains(object O)
    {
      return FList.BinarySearch(O, FComparer)>=0;
    }

    /// <summary>
    /// IList implementation.
    /// Returns the index of the specified object in the list.
    /// If the list is sorted, a <see cref="ArrayList.BinarySearch">BinarySearch</see> is performed using IComparer interface.
    /// Else the <see cref="Equals">Object.Equals</see> implementation of objects is used.
    /// </summary>
    /// <param name="O">The object to locate.</param>
    /// <returns>
    /// If the object has been found, a positive integer corresponding to its position.
    /// If the objects has not been found, a negative integer which is the bitwise complement of the index of the next element.
    /// </returns>
    public int IndexOf(object O)
    {
      int Result = -1;
      Result = FList.BinarySearch(O, FComparer);
      while(Result>0 && FList[Result-1].Equals(O))
        Result--;
      return Result;
    }

    /// <summary>
    /// IList implementation.
    /// Idem <see cref="ArrayList">ArrayList</see>
    /// </summary>
    public bool IsFixedSize 
    { 
      get 
      { 
        return FList.IsFixedSize ; 
      } 
    }

    /// <summary>
    /// IList implementation.
    /// Idem <see cref="ArrayList">ArrayList</see>
    /// </summary>
    public bool IsReadOnly 
    { 
      get 
      { 
        return FList.IsReadOnly; 
      } 
    }

    /// <summary>
    /// IList implementation.
    /// Idem <see cref="ArrayList">ArrayList</see>
    /// </summary>
    public void Clear() 
    { 
      FList.Clear(); 
    }

    /// <summary>
    /// IList implementation.
    /// Cannot be used on a Heap.
    /// </summary>
    /// <param name="Index">The index before which the object must be added.</param>
    /// <param name="O">The object to add.</param>
    /// <exception cref="InvalidOperationException">Insert method cannot be called on a Heap.</exception>
    public void Insert(int Index, object O)
    {
      throw new InvalidOperationException("Insert method cannot be called on a Heap.");
    }

    /// <summary>
    /// IList implementation.
    /// Idem <see cref="ArrayList">ArrayList</see>
    /// </summary>
    /// <param name="Value">The object whose value must be removed if found in the list.</param>
    public void Remove(object Value) 
    { 
      FList.Remove(Value); 
    }

    /// <summary>
    /// IList implementation.
    /// Idem <see cref="ArrayList">ArrayList</see>
    /// </summary>
    /// <param name="Index">Index of object to remove.</param>
    public void RemoveAt(int Index) 
    { 
      FList.RemoveAt(Index); 
    }

    #endregion

    #region IList.ICollection Members

    /// <summary>
    /// IList.ICollection implementation.
    /// Idem <see cref="ArrayList">ArrayList</see>
    /// </summary>
    /// <param name="array"></param>
    /// <param name="arrayIndex"></param>
    public void CopyTo(Array array, int arrayIndex) { FList.CopyTo(array, arrayIndex); }
    
    /// <summary>
    /// IList.ICollection implementation.
    /// Idem <see cref="ArrayList">ArrayList</see>
    /// </summary>
    public int Count { get { return FList.Count; } }

    /// <summary>
    /// IList.ICollection implementation.
    /// Idem <see cref="ArrayList">ArrayList</see>
    /// </summary>
    public bool IsSynchronized { get { return FList.IsSynchronized; } }

    /// <summary>
    /// IList.ICollection implementation.
    /// Idem <see cref="ArrayList">ArrayList</see>
    /// </summary>
    public object SyncRoot { get { return FList.SyncRoot; } }

    #endregion

    #region IList.IEnumerable Members

    /// <summary>
    /// IList.IEnumerable implementation.
    /// Idem <see cref="ArrayList">ArrayList</see>
    /// </summary>
    /// <returns>Enumerator on the list.</returns>
    public IEnumerator GetEnumerator()
    { 
      return FList.GetEnumerator(); 
    }

    #endregion

    #region IClonable Members

    /// <summary>
    /// ICloneable implementation.
    /// Idem <see cref="ArrayList">ArrayList</see>
    /// </summary>
    /// <returns>Cloned object.</returns>
    public object Clone()
    {
      Heap Clone = new Heap(FComparer, FList.Capacity);
      Clone.FList = (ArrayList)FList.Clone();
      Clone.FAddDuplicates = FAddDuplicates;
      return Clone;
    }
    
    #endregion

    #region Delegate Members

    /// <summary>
    /// Defines an equality for two objects
    /// </summary>
    public delegate bool Equality(object Object1, object Object2);

    #endregion

    #region Overridden Members

    /// <summary>
    /// Object.ToString() override.
    /// Build a string to represent the list.
    /// </summary>
    /// <returns>The string refecting the list.</returns>
    public override string ToString()
    {
      string OutString = "{";
      for (int i=0; i<FList.Count; i++)
        OutString += FList[i].ToString() + (i != FList.Count-1 ? "; " : "}");
      return OutString;
    }

    /// <summary>
    /// Object.Equals() override.
    /// </summary>
    /// <returns>true if object is equal to this, otherwise false.</returns>
    public override bool Equals(object Object)
    {
      Heap SL = (Heap)Object;
      if ( SL.Count!=Count ) 
        return false;
      for (int i=0; i<Count; i++)
        if ( !SL[i].Equals(this[i]) ) 
          return false;
      return true;
    }

    /// <summary>
    /// Object.GetHashCode() override.
    /// </summary>
    /// <returns>Hash code for this.</returns>
    public override int GetHashCode() 
    { 
      return FList.GetHashCode(); 
    }

    #endregion

    #region Public Members

    /// <summary>
    /// Idem IndexOf(object), but starting at a specified position in the list
    /// </summary>
    /// <param name="Object">The object to locate.</param>
    /// <param name="Start">The index for start position.</param>
    /// <returns></returns>
    public int IndexOf(object Object, int Start)
    {
      int Result = -1;
      Result = FList.BinarySearch(Start, FList.Count-Start, Object, FComparer);
      while(Result > Start && FList[Result-1].Equals(Object))
        Result--;
      return Result;
    }

    /// <summary>
    /// Idem IndexOf(object), but with a specified equality function
    /// </summary>
    /// <param name="Object">The object to locate.</param>
    /// <param name="AreEqual">Equality function to use for the search.</param>
    /// <returns></returns>
    public int IndexOf(object Object, Equality AreEqual)
    {
      for (int i=0; i<FList.Count; i++)
        if ( AreEqual(FList[i], Object) ) return i;
      return -1;
    }

    /// <summary>
    /// Idem IndexOf(object), but with a start index and a specified equality function
    /// </summary>
    /// <param name="Object">The object to locate.</param>
    /// <param name="Start">The index for start position.</param>
    /// <param name="AreEqual">Equality function to use for the search.</param>
    /// <returns></returns>
    public int IndexOf(object Object, int Start, Equality AreEqual)
    {
      if ( Start<0 || Start>=FList.Count ) throw new ArgumentException("Start index must belong to [0; Count-1].");
      for (int i=Start; i<FList.Count; i++)
        if ( AreEqual(FList[i], Object) ) return i;
      return -1;
    }

    /// <summary>
    /// The objects will be added at the right place.
    /// </summary>
    /// <param name="C">The object to add.</param>
    /// <returns>The index where the object has been added.</returns>
    /// <exception cref="ArgumentException">The Heap is set to use object's IComparable interface, and the specifed object does not implement this interface.</exception>
    public void AddRange(ICollection C)
    {
      foreach(object Object in C) 
        Add(Object);
    }

    /// <summary>
    /// Cannot be called on a Heap.
    /// </summary>
    /// <param name="Index">The index before which the objects must be added.</param>
    /// <param name="C">The object to add.</param>
    /// <exception cref="InvalidOperationException">Insert cannot be called on a Heap.</exception>
    public void InsertRange(int Index, ICollection C)
    {
      throw new InvalidOperationException("Insert cannot be called on a Heap.");
    }

    /// <summary>
    /// Limits the number of occurrences of a specified value.
    /// Same values are equals according to the Equals() method of objects in the list.
    /// The first occurrences encountered are kept.
    /// </summary>
    /// <param name="Value">Value whose occurrences number must be limited.</param>
    /// <param name="NumberToKeep">Number of occurrences to keep</param>
    public void LimitOccurrences(object Value, int NumberToKeep)
    {
      if(Value == null) 
        throw new ArgumentNullException("Value");
      int Pos = 0;
      while((Pos = IndexOf(Value, Pos)) >= 0)
      {
        if(NumberToKeep <= 0)
          FList.RemoveAt(Pos);
        else
        {
          Pos++; 
          NumberToKeep--; 
        }
        if(FComparer.Compare(FList[Pos],Value) > 0 ) 
          break; 
      }
    }

    /// <summary>
    /// Removes all duplicates in the list.
    /// Each value encountered will have only one representant.
    /// </summary>
    public void RemoveDuplicates()
    {
      int PosIt;
      PosIt = 0;
      while(PosIt < Count-1)
      {
        if(FComparer.Compare(this[PosIt],this[PosIt+1]) == 0 ) 
          RemoveAt(PosIt);
        else 
          PosIt++;
      }
    }

    /// <summary>
    /// Returns the object of the list whose value is minimum
    /// </summary>
    /// <returns>The minimum object in the list</returns>
    public int IndexOfMin()
    {
      int RetInt = -1;
      if (FList.Count > 0)
      {
        RetInt = 0;
        object RetObj = FList[0];
      }
      return RetInt;
    }

    /// <summary>
    /// Returns the object of the list whose value is maximum
    /// </summary>
    /// <returns>The maximum object in the list</returns>
    public int IndexOfMax()
    {
      int RetInt = -1;
      if(FList.Count > 0)
      {
        RetInt = FList.Count-1;
        object RetObj = FList[FList.Count-1];
      }
      return RetInt;
    }

    /// <summary>
    /// Returns the topmost object on the list and removes it from the list
    /// </summary>
    /// <returns>Returns the topmost object on the list</returns>
    public object Pop()
    {
      if(FList.Count == 0)
        throw new InvalidOperationException("The heap is empty.");
      object Object = FList[Count-1];
      FList.RemoveAt(Count-1);
      return(Object);
    }

    /// <summary>
    /// Pushes an object on list. It will be inserted at the right spot.
    /// </summary>
    /// <param name="Object">Object to add to the list</param>
    /// <returns></returns>
    public int Push(object Object)
    {
      return(Add(Object));
    }

    #endregion

    #region Private Members

    private bool ObjectIsCompliant(object Object)
    {
      if(FUseObjectsComparison && !(Object is IComparable)) 
        throw new ArgumentException("The Heap is set to use the IComparable interface of objects, and the object to add does not implement the IComparable interface.");
      if(!FAddDuplicates && Contains(Object)) 
        return false;
      return true;
    }

    private class Comparison : IComparer
    {
      public int Compare(object Object1, object Object2)
      {
        IComparable C = Object1 as IComparable;
        return C.CompareTo(Object2);
      }
    }

    private void InitProperties(IComparer Comparer, int Capacity)
    {
      if(Comparer != null)
      {
        FComparer = Comparer;
        FUseObjectsComparison = false;
      }
      else
      {
        FComparer = new Comparison();
        FUseObjectsComparison = true;
      }
      FList = Capacity > 0 ? new ArrayList(Capacity) : new ArrayList();
      FAddDuplicates = true;
    }

    #endregion
  }
}
www.java2v.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.