Home Page Downloads Contact Us

Free Open Source Artificial Intelligence C++ Parts

aiParts Open Source Project  

Home Page
Open Source
Contact
Free Downloads
Releases and Credits
Software Status
License
v0.9.3 README File
About rrproj
assigning people and/or equipment to projects
High-Hope Technique
History of the AI
View Source Files
and how they are organized
Making Programs
Development Notes
Using aiParts
Your Application
Support and Services

aiParts Source File

//**********************************************************************
//  aipPandemonim.h  -  Pandemonium
//
//  Provides:  aipPandemonium, aipDemon, aipDemonItr 
//                (plus aipDemonLink)
//
//  A pandemonium is a set of demons.
//
//  A pandemonium of demons is an AI pattern in its own right,
//  but it is also very useful as a general purpose container.
//
//  aipPandemonium is implemented as a doubly-linked-list of 
//  aipDemonLink, which point to aipDdemon.  This implementation
//  is hidden from every class except aipDemonItr (a demon iterator).
//
//  Pandmoniums and Demons MUST be created with new.
//
//  aipDemon is a base class - it is designed to be subclassed.
//
//  Demons may be shared in and between pandemoniums.  These classes
//  ensure that shared demons are deleted only once upon destruction.
//
//  Pandemoniums may be ordered.  If subclasses of aipDemon override
//  the num_key(), key1() and optionally key(2), key(3), key(4) 
//  functions, aipPandemonium::add() will insert demons in order.
//
//  A pandemonium of ordered demons may be set to be distinct
//  with respect to keys.  If a subclass of aipPandemonium overrides
//  is_distinct() to return 1, add() will not add a deomon if all
//  the keys match.
//
//  See www.aipatterns.org (or www.agt.net/public/bmarshal/aipatterns)
//  for information on the Pandemonium AI patterns.
//
//  Copyright (c)  2005, 2008  Brian Marshall
//
//  See the license at end of this file.
//
//  Developers/Contributers:
//    [BRM] Brian Marshall - Calgary - bmarshal@agt.net
//
//  08/01/28  [BRM] removed delete_demon(); changed ownership scheme;
//                  pandemoniums can be ordered and distinct
//                  added last(), prev(), find()
//  05/11/09  [BRM] pandemonium can now add demon without owning it
//  05/11/01  [BRM] made pandemonium a queue (rather than a stack)
//  05/08/17  [BRM] Development begins.
//
//----------------------------------------------------------------------

#ifndef aipPandemonium_h_guard
#define aipPandemonium_h_guard

#include "aipBase.h"

//----------------------------------------------------------------------
//  Classes.  Sub-classing is shown by indentation.

// class aipBase;             ( in aipBase.h )
     class aipPandemonium;   // a set of demons
     class aipDemon;         // base-class for demons.
   class  aipDemonLink;      // used internally for linked-list.
   class  aipDemonItr;       // demon iterator

//======================================================================
//  aipPandemonium   -  a set of demons
//
//  When a demon is added to a pandemonim, the pandemonium may take
//  ownership of the demon; upon destruction, a pandemonium will
//  delete the demons it owns.
//
//  Subclasses can override is_distinct() to return 1 to make
//  the pandemonium distinct with respect to the demon-keys -
//  aipPandemonium::add() will delete rather than add a demon.
//
//  Pandmoniums and Demons and MUST be created with new.

class aipPandemonium : public aipBase {

  aipDemonLink  * m_first;       // First demon in a linked-list.
  aipDemonLink  * m_last;        // Last  demon in a linked-list.
  long            m_num_demon;
  int             m_is_distinct;

public:

  aipPandemonium ();
  virtual ~aipPandemonium ();

  void set_is_distinct () { m_is_distinct = 1; }

  int is_distinct () const { return m_is_distinct; }

  aipDemonLink * first_link () const { return m_first; } // for itr
  aipDemonLink *  last_link () const { return m_last;  }

  void add (aipDemon *demon);

  long num() const { return m_num_demon; }

  virtual void take_msg (aipMsg *m);

};


//======================================================================
//  aipDemon  -  Base class for demons (items in a aipPandemonium).
//
//  A pandemonium may take ownership of demons that are added to it,
//  and will delete owned demons upon destruction.  Subclasses of a 
//  pandemonium may provide functions to create new demons of the 
//  appropriate type.  Demons MUST be created with new.
//
//  Subclasses can override num_keys(), key1() and optionally
//  key2(), key3() and key4() to make the pandemonium ordered - to 
//  make aipPandemonium::add() insert the demons in order.


class aipDemon : public aipBase {

  int    m_is_owned;

public:

  aipDemon () : aipBase() { m_is_owned = 0; }
  virtual ~aipDemon () {}

  virtual long num_keys (void) const { return 0; }
  virtual long     key1 (void) const { return 0; }
  virtual long     key2 (void) const { return 0; }
  virtual long     key3 (void) const { return 0; }
  virtual long     key4 (void) const { return 0; }

  void set_is_owned () { m_is_owned = 1; }

  int  is_owned () const { return m_is_owned; }

  virtual void take_msg (aipMsg *m) {}

};


//======================================================================
//  aipDemonLink  -  Link to a demon in a doubly-linked-list.
//
//  A demon-link may own the demon to which it points; if it does,
//  it will delete the demon upon destruction.
//
//  Having public set_next() and set_prev() functions would seem to
//  be asking for trouble, but in fact, only the aipIterator can
//  acquire a pointer to an aipDemonLink object.

class aipDemonLink {

  aipDemon      * m_demon;

  aipDemonLink  * m_prev;      // Prev demon in a list or zero.
  aipDemonLink  * m_next;      // Next demon in a list or zero.

  int             m_is_owner;  // for destruction purposes

public:

  aipDemonLink (aipDemon *demon, 
                aipDemonLink *prev, aipDemonLink *next);

  ~aipDemonLink ();

  aipDemon * demon () const { return m_demon; }

  aipDemonLink * prev () const { return m_prev; }
  aipDemonLink * next () const { return m_next; }

  void set_prev (aipDemonLink *x) { m_prev = x; }
  void set_next (aipDemonLink *x) { m_next = x; }

  int less_than   (aipDemonLink *y);
  int is_equal_to (aipDemonLink *y);

};


//======================================================================
//  aipDemonItr  -  Pandemonium Iterator - to iterate through the demons.

class aipDemonItr {

  aipPandemonium  * m_pandemonium;
  aipDemonLink    * m_current;

protected:

  aipDemonLink * first_link () const {
    return m_pandemonium ? m_pandemonium->first_link() : 0;
  }

  aipDemonLink *  last_link () const {
    return m_pandemonium ? m_pandemonium->last_link() : 0;
  }

  aipPandemonium  * pandemonium () const { return m_pandemonium; }
  aipDemonLink    * current     () const { return m_current;     }

  void set_demon_itr ( aipPandemonium *pan, aipDemonLink *cur) {
    m_pandemonium = pan;
    m_current = cur;
  }

  int keys_match  (long akey1, long akey2, long akey3, long key4);

public:

  aipDemonItr () { set_demon_itr (0, 0); }

  aipDemonItr (aipPandemonium *p) { set_demon_itr (p, 0); } 

  aipDemonItr (const aipDemonItr& x) {
    set_demon_itr (x.pandemonium(), x.current());
  }

  virtual ~aipDemonItr () {}

  aipDemonItr& operator = (const aipDemonItr& x) {
    set_demon_itr (x.pandemonium(), x.current());
    return *this;
  }

  aipDemon * first ();    // returns zero if the list is empty
  aipDemon * last  ();    // returns zero if the list is empty
  aipDemon * next  ();    // Returns zero if at last
  aipDemon * prev  ();    // Returns zero if at first

                                          // Returns zero if not found
  aipDemon * find  (long akey1, long akey2 =-999999999, 
                                long akey3 =-999999999,
                                long akey4 =-999999999);

};


//======================================================================

#endif

//======================================================================
//                           License
//
//   Permission is hereby granted, free of charge, to any 
//   person obtaining a copy of this software and associated 
//   documentation files (the "Software"), to deal in the Software 
//   without restriction, including without limitation the rights 
//   to use, copy, modify, merge, publish, distribute, sublicense, 
//   and/or sell copies of the Software, and to permit persons to 
//   whom the Software is furnished to do so, subject to the 
//   following conditions:
//
//   The copyright notice and this license shall be included in all 
//   copies or substantial portions of the Software.
//
//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
//   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 
//   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
//   NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 
//   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 
//   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
//   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 
//   OTHER DEALINGS IN THE SOFTWARE.
//
//**********************************************************************