📄 aippandemonium.h
字号:
//**********************************************************************
// 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.
//
//**********************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -