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

//======================================================================
//  samp_pandemonium.cpp  - sample program using aipPandemonium.h
//
//  This is a trivial example that illustrates that a pandemonium
//  is really just a first-in-last-out list (a queue).  It...
//     - puts words into two pandemoniums (sharing some words)
//     - sends a message to each word, telling it to make its 
//           first letter upper case
//     - Uses iterators to write the words to standard output
//
//  Developers/Contributers:
//    [BRM] Brian Marshall - Calgary - bmarshal@agt.net
//
//  08/01/01  [BRM] removed delete_deomon()
//  05/11/01  [BRM] changed because pandemonium now queue (not stack)
//  05/09/11  [BRM] development begins
//
//----------------------------------------------------------------------
//  Building the executable
//
//  On Linux, you can call the compiler gcc or g++ (although on
//  Fedora, use g++ because gcc finds the wrong libraries)...
//
//  gcc -o samp_pandemonium samp_pandemonium.cpp aipPandemonium.cpp \ 
//                          aipBase.cpp aipGood.cpp
//
//  In the example, above, spaces have been added after the 
//  backshlashs - the Borland compiler does not like them at the ends 
//  of lines, even in comments.
//
//----------------------------------------------------------------------

#include "aipPandemonium.h"
#include <string.h>
#include <iostream>
using namespace std;

// - - - - - - - - - - - - - - - - - - - - - - - -
//  Initial Declarations and constants

static const long Upcase_First_Char = 1;   // a new message-type code

// Word is a subclass of aipDemon so it can go into a pandemonium
//   (and handle messages)

class Word : public aipDemon {
  char  m_word[61];
public:
  Word (const char *w) { strcpy(m_word,w); }
  virtual ~Word () {}
  char * str () { return m_word; }
  virtual void take_msg (aipMsg *m) { 
    if (m->typ() == Upcase_First_Char) {
      if (m_word[0] >= 'a' && m_word[0] <= 'z') m_word[0] -= ('a'-'A');
    }
  }
};

class WordItr : public aipDemonItr {
public:
  WordItr (aipPandemonium *p) : aipDemonItr(p) {}
  virtual ~WordItr () {}
  Word * first() { return (Word*)aipDemonItr::first(); }
  Word *  last() { return (Word*)aipDemonItr::last();  }
  Word *  next() { return (Word*)aipDemonItr::next();  }
  Word *  prev() { return (Word*)aipDemonItr::prev();  }
};

// - - - - - - - - - - - - - - - - - - - - - - - -
// Quad has a 4-part key - the list will be ordered

class Quad : public aipDemon {
  long  m_w;
  long  m_x;
  long  m_y;
  long  m_z;
public:
  Quad (long w, long x, long y, long z) {
    m_w = w;   m_x = x;   m_y = y;   m_z = z;
  }
  ~Quad () {}
  virtual long num_keys (void) const { return 4;   }
  virtual long     key1 (void) const { return m_w; }
  virtual long     key2 (void) const { return m_x; }
  virtual long     key3 (void) const { return m_y; }
  virtual long     key4 (void) const { return m_z; }
  void write () const { 
    cout << m_w << "/" << m_x << "/" << m_y << "/" << m_z; 
  }
};

class QuadItr : public aipDemonItr {
public:

  QuadItr (aipPandemonium *p) : aipDemonItr(p) {}
  virtual ~QuadItr () {}

  Quad * first() { return (Quad*)aipDemonItr::first(); }
  Quad *  last() { return (Quad*)aipDemonItr::last();  }
  Quad *  next() { return (Quad*)aipDemonItr::next();  }
  Quad *  prev() { return (Quad*)aipDemonItr::prev();  }

  Quad *  find(long key1, long key2 =-999999, 
                          long key3 =-999999,
                          long key4 =-999999) {
    return (Quad*)aipDemonItr::find(key1, key2, key3, key4);
  }

};

// - - - - - - - - - - - - - - - - - - - - - - - -
//  The main entry-point

int main () {

  // We know about argc and argv, but the Borland compiler
  // does not like them if they are not used.

  // Pandemoniums and Demons MUST be created with new.

    // words we are going to share
  Word *nl = new Word("\n");
  Word *ep = new Word("!");

    // line1

  aipPandemonium *line1 = new aipPandemonium;
  line1->add (nl);
  line1->add ( new Word("hello") );    // another way
  line1->add ( new Word("world") );
  line1->add (ep);
  line1->add (nl);

  WordItr itr1(line1);
  for ( Word *w = itr1.first(); w; w = itr1.next() ) {
    cout << w->str() << " ";
  }
  cout << "\n";

    // line1a

  aipPandemonium *line1a = new aipPandemonium;
  line1a->add ( new Word("single") );

  cout << "A pandemonium may contain only one item: ";
  WordItr itr1a(line1a);
  for ( Word *w = itr1a.first(); w; w = itr1a.next() ) {
    cout << w->str() << " ";
  }
  cout << "\n";

    // line2

  aipPandemonium *line2 = new aipPandemonium;
  line2->add (nl);
  line2->add ( new Word("pandemoniums") );
  line2->add ( new Word("can") );
  line2->add ( new Word("share") );
  line2->add ( new Word("demons") );
  line2->add (ep);
  line2->add (nl);
  line2->add (nl);

    // send a message to each pandemonium

  aipMsg msg(Upcase_First_Char);
  line1->take_msg(&msg);
  line2->take_msg(&msg);

  WordItr itr2(line2);
  for ( Word *w = itr2.first(); w; w = itr2.next() ) {
    cout << w->str() << " ";
  }
  cout << "\n";

  cout << "Can also iterate backwards...\n";
  for ( Word *w = itr2.last(); w; w = itr2.prev() ) {
    cout << w->str() << " ";
  }
  cout << "\n";

    // line3

  aipPandemonium *line3 = new aipPandemonium;
  line3->add ( new Quad(3,4,3,4) );
  line3->add ( new Quad(2,2,3,1) );
  line3->add ( new Quad(2,3,3,5) );
  line3->add ( new Quad(3,3,3,3) );
  line3->add ( new Quad(1,2,1,5) );
  line3->add ( new Quad(3,3,3,3) );
  line3->add ( new Quad(1,1,2,6) );
  line3->add ( new Quad(1,1,2,4) );

  Quad *q;

  aipPandemonium *line4 = new aipPandemonium;
  line4->set_is_distinct();

  cout << "Quads in order:\n";
  QuadItr itr3(line3);
  for ( q = itr3.first(); q; q = itr3.next() ) {
    cout << "  ";
    q->write();
    line4->add(q);
  }
  cout << "\n\n";

    // line4

  cout << "Distinct Quads in order:\n";
  QuadItr itr4(line4);
  for ( q = itr4.first(); q; q = itr4.next() ) {
    cout << "  ";
    q->write();
  }
  cout << "\n\n";

  cout << "Can search for an entry (by one or more keys)\n" 
       << "and then print out remaining quads\n" 
       << "(in this case, beginning with 2/3/3/5)...\n";
  q = itr4.first();   // get to start of list
  if (!q) cout << "Error: itr4.first() returns zero\n";
  q = itr4.find(2,3,3,5);
  for ( ; q; q = itr4.next() ) {
    cout << "  ";
    q->write();
  }
  cout << "\n\n";

  delete line1;  // and its contents (links and demons)
  delete line1a;
  delete line2;
  delete line3;
  delete line4;

  return 0;

}

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