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

//**********************************************************************
//  aipBase.h  -  aipBase, aipMsg
//
//  Provides:  
//    Classes:    aipBase  aipMsg  aipRand  aipLogger
//                aipLogger  aipFileLogger  aipStringLogger
//    Functions:  aip_strncpy()  aip_get_str()  aip_get_val()
//    Constants:  intensity-constants, empty-string
//
//  Classes that descend from aipBase can:
//    - take aipMsg messages
//    - log to cout (or, optionally, through a logger)
//    - using functions from a static aipRand member:
//      - generate random numbers from 0 to 9999
//      - generate random numbers in any range
//      - randomly return true in some proportion of calls
//
//  Copyright (c)  2005, 2007, 2008  Brian Marshall
//
//  See the license at end of this file.
//
//  Developers/Contributers:
//    [BRM] Brian Marshall - Calgary - bmarshal@agt.net
//
//  08/07/09  [BRM] new aipRand, random_num(); new functions:
//                    aip_get_str()  aip_get_val()  aip_strncpy();
//                  modified logging   multiple small changes
//  05/11/07  [BRM] random_num() now in class aipBase
//  05/11/01  [BRM] added aip_strncpy() that always terminates string
//  05/09/10  [BRM] Development begins.
//
//----------------------------------------------------------------------

#ifndef aipBase_h_guard
#define aipBase_h_guard

#include "aipGood.h"
#include <string.h>
#include <stdio.h>

//======================================================================
//    About Logging
//
//  Code for any object that descends from aipBase can call:
//    void log (const char *x);
//    void log (double x);
//    void log (long x);
//
//  By default, calling a log() function will write to standard output.
//
//  An application may create an instance of a subclass of aipLogger
//  and call:    void set_logger (aipLogger *x)
//  (once) from any object that descends from aipBase
//  and any calls to log() functions will call corresponding calls
//  in the logger.  (In the logger, the log() functions are virtual.)
//
//  It is the responsibility of code that creates a logger to delete
//  it if necessary.
//
//  An application may, of course, read and write to cout or files 
//  in addition to, or instead of, calling log() functions.
//
//======================================================================
//    About the Random Number Generator (RNG)
//
//  The RNG in aipBase returns the same sequence of numbers 
//  regardless of hardware or compiler.
//
//  aipBase provides:
//     random_num()           returns a number from 0 to 9999
//  plus two functions that call random_num():
//     random_num(lo,hi)      returns a number in a range
//     is_one_chance_in_x(x)  returns true one in x times called
//
//  The RNG in aipBase is a static data member - it does not
//  increase the size of instances of subclasses of aipBase.
//
//  random_num() returns a number in the range 0 to 9999. 
//  In the opinion of the author, at the time of writing,
//  for AI applications, 4 significant digits should be lots.
//  It is not suitable for applications requiring high-quality
//  random numbers.
//
//  random_num(lo,hi) returns a number in any range specified,
//  although if the range is greater than 10000 numbers, every
//  number in the range may not exist in the sequence, although
//  lo (the low limit of the range) will always be included -
//  ex. random_num(1,40000) will generate numbers from the set:
//        [1,5,9,13,17,...,39997]
//
//  In class aipRand, functions rand_1() and rand_2() are
//  low-quality RNGs that are used by random_num().  
//  The parameters of rand_1() stay the same.
//  The parameters of rand_2() are periodically randomly rechosen.
//
//======================================================================
//  Classes

class aipBase;            // base-class to many aiParts classes
class aipMsg;             // base-class for messages
class aipRand;            // random number generator
class aipLogger;          // to cout, a file, a string, etc. (optional)
  class aipFileLogger;    // log to a file
  class aipStringLogger;  // log to a string


//======================================================================
//  Global Constants

static const long aipIntensity_None         = 0;
static const long aipIntensity_Slightly     = 1;
static const long aipIntensity_A_Little     = 2;
static const long aipIntensity_Somewhat     = 3;
static const long aipIntensity_A_Fair_Bit   = 4;
static const long aipIntensity_Quite_A_Bit  = 5;
static const long aipIntensity_A_Lot        = 6;

static const char aip_Endl[2] = "\n";

static const char aip_Empty_Str[2] = "";

//======================================================================
//    Local Constants for the Random Number Generator (RNG)

// a sub-RNG is defined: s = (a*s+c)%m  where m=10000

const long Num_Sub_RNG = 11;

                         // first for rand_1(); rest for rand_2()

const long Rand_s[] = {  9281,
                         6733,  9613,  5107,  4241,  6733,
                         9613,  4783,  5821,  4241,  7477 };

const long Rand_a[] = { 80441,
                        69851, 69851, 76151, 76151, 85273, 
                        58637, 85273, 58637, 67817, 55669 };
              
const long Rand_c[] = { 67519,
                        85273, 85273, 50471, 69851, 69851,
                        50471, 76151, 80441, 58637, 76151 };

const long Rand_Null      = -999999999;
const long Rand_Null_Test = -999999000;

//======================================================================
//  Global Functions

       // strncpy that terminates the string, returns length

int aip_strncpy (char *dest, const char *src, int max_len);

       // Get a string or value (up to the specified length) 
       // starting from x.  If a delimiter is not specified,
       // any char other than a letter or digit will be the
       // delimiter.  Return a pointer to the terminating
       // delimiter or zero if an error occurs.

const char * aip_get_str (const char *x, long maxlen, 
                          char *str, char delim ='~');

const char * aip_get_val (const char *x, long maxlen, 
                          long *val, char delim ='~');

       // Return true if x is a delimiter character.
       // If delim is '~', any char other than a letter
       // or digit is a delimiter.

int aip_is_delim (char x, char delim);

//======================================================================
//  aipRand  -  Random Number Generator ("RNG")

class aipRand {

  long  m_rand_seed_1;    // seed for first sub-RNG
  long  m_rand_seed_2;    // seed for second sub-RNG

  long  m_rand_2_idx;     // index of params for rand_2()
  long  m_rand_count;     // 0: choose a sub-RNG for rand_2()

  long  m_deck[100];      // set of random numbers;
  long  m_deck_len;       // number of random numbers in m_deck;

protected:

  virtual long sub_rng (long idx);  // used by rand_1(), rand_2()
  
  long rand_1 ();   // first  sub-RNG (that does not change)
  long rand_2 ();   // second sub-RNG (that changes periodically)

public:

  aipRand  () { m_rand_2_idx = Rand_Null; }
  ~aipRand () {}

  long random_num ();                  // returns 0 to 9999

};

//======================================================================
//  aipBase   -   Base class for classes that can:
//                  - take messages
//                  - log to cout  (or, optionally, through a logger)
//                  - generate random numbers
//
//  This is a base class for many aiParts classes.
//
//  Subclasses may override send_msg() to send a message to
//  other objects that should receive it.

class aipBase {

  static aipRand      m_rand;     // random number generator

  static aipLogger  * m_logger;   // optional logger

public:

  aipBase () {}
  virtual ~aipBase () {}

  void set_logger (aipLogger *x) { m_logger = x; }

  virtual void  take_msg (aipMsg *p) {}

  long random_num ();                  // returns 0 to 9999
  long random_num (long lo, long hi);  // (hi-lo) < 100000
  int  is_one_chance_in_x (long x);

  void log (const char *x) const;   // using a logger if it has one
  void log (double x) const;
  void log (long x) const;

};


//======================================================================
//  aipMsg  -  a message
//
//  Applications may create subclasses with application-specific
//  data members.
//
//  subclasses and/or applications can define constants for 
//     typ and subtyp.  The default for each is zero.
//
//  Users or subclasses may define constants for m_typ.

class aipMsg {

  short   m_typ;      // primary type of message
  short   m_subtyp;   // secondary type of message
  aipG    m_g;        // goodness associated with message

public:

  void set (short t, short st, aipG g);

  void set (aipG g);

  void set_subtyp (short st) { m_subtyp = st; }

  aipMsg(short t, short st =0, aipG g =aipNeutral);
  virtual ~aipMsg ();

  short  typ    () const { return m_typ;     }
  short  subtyp () const { return m_subtyp;  }
  aipG   g      () const { return m_g;       }

};

//======================================================================
//  aipLogger  -  optional log to cout, a file, a string, etc
//
//  If software creates a logger, it can call aipBase::set_logger()
//  and the logger will be used in calls to aipBase.log().
//  The creator of a logger owns it and deletes it if necessary.
//
//  If no logger is created, calls to aipBase.log()  will default 
//  to writing to cout.
//
//  This is a base class; to use it, create a sub-class.

class aipLogger {

public:

  aipLogger () {}
  virtual ~aipLogger () {}

  virtual int is_valid () = 0;

  virtual void log (const char *x) = 0;
  virtual void log (double x)      = 0;
  virtual void log (long x)        = 0;

  virtual const char * get () { return 0; }  // defalt is no support

};

//= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
//  aipFileLogger

class aipFileLogger : public aipLogger {

  FILE  * m_stream;

public:

  aipFileLogger (const char *file_name);
  virtual ~aipFileLogger ();

  virtual int is_valid ();

  virtual void log (const char *x);
  virtual void log (double x);
  virtual void log (long x);

};

//= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
//  aipStringLogger

class aipStringLogger : public aipLogger {

  char  * m_str;
  long    m_str_len;
  long    m_max_len;

public:

  aipStringLogger (long max_len);
  virtual ~aipStringLogger ();

  virtual int is_valid ();

  virtual void log (const char *x);
  virtual void log (double x);
  virtual void log (long x);

  virtual const char * get () { return m_str; }

};

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

#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.
//
//**********************************************************************