Code Samples

Homepage  Science Fiction Art Castle Art Technical Writing About  C++ Code Samples



//**********************************************************************************
//**********************************************************************************

//                                                                             DEMO CODE
//
//                                          Demonstrates Object-Oriented Design using C++
//                                                   Written January 20, 2002 by C.Stewart
//
//**********************************************************************************
//**********************************************************************************
//
//
class Unit
{
// A unit is a 'playing piece' in a strategic simulation war game. It is a base class containing attributes

// common to all unit types. Classes derived from Unit represent the various unit types such as infantry, // armor, fighter, submarine, etc.

  public:
    Unit( ); // Default constructor
    Unit( const Unit& ); // Copy constructor
    Unit& operator = ( const Unit& ); // Assignment operator
    ~Unit( ); // Destructor
    // ******** Member functions ********
    int getUnitNumber( ) const;
    void setUnitNumber( int );
    int getUnitType( ) const;
    void setUnitType( int );
    int getCost( ) const;
    void setCost( int );
    int getInitMovePoints( ) const;
    void setInitMovePoints( int );
    int getCurrMovePoints( ) const;
    void setCurrMovePoints( int );
    int getAttackValue( ) const;
    void setAttackValue( int );
    int getDefenseValue( ) const;
    void setDefenseValue( int );
    int getMovedCombat( ) const;
    void setMovedCombat( int );
    int getAttackStatus( ) const;
    void setAttackStatus( int );
    landTerr* getLandTerr( );
    void setLandTerr( landTerr* );
    seaZone* getSeaZone( );
    void setSeaZone( seaZone* );
  private:
// ******** Member Data ********
    int unit_number; // Identifies this unit
    int unit_type; // Infantry, armor, fighter, etc.
    int unit_cost; // How much the unit costs
    int init_move_points; // Initial movement points
    int curr_move_points; // Updated with movement
    int attack_value; // Value unit attacks with
    int defense_value; // Value unit defends with
    flag moved_combat; // If true, no non-combat movement
    flag attack_status; // Attacking, defending, or neither
    landTerr *land_terr; // The land territory the unit is in; 0 if not
    seaZone *sea_zone; // The sea zone the unit is in, 0 if not
    List land_terr_list; // Tracks territories entered ( used in retreats )
    List sea_zone_list; // Tracks sea zones entered
    List land_sea_order; // Tracks order of territories and sea zones
};

 

// Strategic Simulation Game
//
include "includes.h" // namespace, typedefs, class definitions, etc.
int main( )
{
  initialize( );
  extern Control control;
  while ( !control.game_over )
  {
    control -> *locator( );
    control -> *choice( );
    control.screen.render( );
  }
  return 0;
}

 

void Control::determine_locator( )
{
// Determines locator when cursor is over the playfield.
  switch( logic_table.curr_entry )
  {
    case LAND_TERRITORY: // enum constant
      locator = land_terr_loc; // Function pointer
      break;
    case SEA_ZONE:
      locator = sea_zone_loc;
      break;
    case UNIT_ICON:
      locator = unit_icon_loc;
      break;
    case SCROLL_ICON;
      locator = scroll_icon_loc;
      break;
    }
}

 

// Combat Movement Phase land to land movement
//
void Control::landLandCombatMove( )
{
  if ( actual_movement ) // Returns 1 if true; updates attempt variables
  {
    if ( icon_selected )
    {
      if ( alert && crossover ( ) ) // Only need to make these checks if border is crossed
      {
        switch ( unit_code ) // Different units have different move criteria
        {
          case INFANTRY: // enum constant
            alert = landLandCombatMove( attempt_land_terr -> infantry_list );
            break;
          case ARMOR:
            alert = landLandCombatMove( attempt_land_terr -> armor_list );
            break;
          case AAGUN:
            alert = landLandCombatMove( attempt_land_terr -> aagun_list );
            break;
          case FIGHTER:
            alert = landLandCombatMove( attempt_land_terr -> fighter_list );
            break;
          case BOMBER:
            alert = landLandCombatMove( attempt_land_terr -> bomber_list );
            break;
          case FACTORY:
            alert = landLandCombatMove( attempt_land_terr -> factory_list );
            break;
          }
        }
      }
    }
// If there is no icon selected, only move arrow cursor. The physical movement, of course, is done during // the render phase.
  if ( !alert )
  {
    screen.moveCursor( ); // Updates current screen variables
    checkLocatorAndChoice( ); // May set menu bar, alert, etc. locator and choice
  }
}


// Function to move units from one land region object to another. First it checks if it is possible for each // unit to move.  Then, if so, moves the units from active_land_terr's unitList to attempt_land_terr's

// unitList. Finally, it makes the necessary adjustments to all appropriate class objects to indicate a move  // was in fact made.

int Control::landLandCombatMove( unitList inf_list )
{
  alert = attemptEnemyRegion( );
  unitList::iterator it = infantry_list.begin( );
  while ( ( !alert ) || ( it != infantry_list.end( ) ) )
  {
    alert = enoughMovePoints( *it ); // Template function instance
    if ( !alert )
      alert = withinLimits( *it ); // Template function instance
    if ( !alert )
      ++it;
  }
// All units passed if alert equals 0, it is now ok to move
  if ( !alert )
    infantry_list.moveFriendly( floater ); // Physically moves from one unitList to another
// Everything so far so good; just need to make final adjustments to the necessary class objects to

// indicate changes caused by move
  it = infantry_list.begin( ); // Reset iterator to traverse unitList again
  while ( it != infantry_list.end( ) )
  {
    it -> setLandTerr( attempt_land_terr ); // New land territory unit is in
    it -> decMovePoints( ); // Decrement move points
    it -> setLandTerrList( ); // Update region path used in retreats, etc.
    ++it;
  }
// Finally, update the Control class object members
  setPrevLandTerr( active_land_terr );
  setActiveLandTerr( attempt_land_terr );
}

 

bool Control::attemptEnemyLandTerr( )
{
// This function returns 0 if attempt_land_terr is friendly, or 1 if it is an enemy.
// Alliances are determined by the Player.player_number class member. Players of one side have even

// player numbers; players of the other side have odd player numbers. Modulus division is used to

// determine this odd or even status.
  int result = 0;
  int value1 = ( active_player -> player_number ) % 2;
  int value2 = ( attempt_player -> player_number ) % 2;
  if ( value1!= value2 )
    result = 1;
  return result;
}

 

bool Control::crossover( )
{
// Will movement cross a region border? Return 1 if it does, otherwise 0.
  int value = 0;
  if ( active_land_terr )
  {
    if ( active_land_terr != attempt_land_terr )
      value = 1;
  }
  if (active_sea_zone )
  }
    if ( active_sea_zone != attempt_sea_zone )
    value = 1;
  }
  return value;
}

 

int infantry::boardTransports( Control& control )
{
// This is the definition of the virtual function used by the infantry class to move infantry units onto

// transports.  Three lists are of importance here. The actual infantry units are stored in

// active_land_terr.infantry_list. The transport units are contained in attempt_sea_zone.transport_list. // Each transport in turn contains a list of pointers to the infantry units on the transport. This member

// list is called infantry_ptr_list.
//
// This function basically traverses the same infantry and transport lists twice. Once to see if there are

// actually enough transports to move onto, and again to actually move each unit. The logic works this

// way because the user interface is designed to move a 'stack' of infantry units rather than one at a

// time. Therefore we have to look ahead first to see if there is enough room for the units, and then we // actually move them. If there are not enough transports, an alert value is returned.
//
  int alert = 0;
  landTerr* source_land_terr = control.active_land_terr;
  seaZone* dest_sea_zone = control.attempt_sea_zone;
// First traversal of lists
  unitList::iterator it! = source_land_terr -> infantry_list.begin( );
  unitList::iterator it2 = dest_sea_zone -> transport_list.begin( );
  int onboard_units = it2 -> infantry_ptr_list.count( );
  while ( !alert || it1 != source_land_terr -> infantry_list.end( ) )
  {
    if ( onboard_units -> units_per_transport )
    {
      ++it1;
      ++onboard_units;
    }
    else
    {
      if ( it2 = = dest_sea_zone -> transport_list.end( ) )
      {
        alert = NOT_ENOUGH_TRANSPORTS; // enum constant
      }
    else
    {
      ++it2;
      onboard_units = it2 -> infantry_ptr_list.count( );
    }
  }
}
// Second traversal of lists
  if ( !alert )
  {
    it1 = source_land_terr -> infantry_list.begin( ); // reset iterators
    it2 = dest_sea_zone -> transport_list.begin( );
    int onboard_units = it2 -> infantry_ptr_list.count( );
    while ( !alert || it1 != source_land_terr -> infantry_list.end( ) )
    {
      if ( onboard_units < it1 -> units_per_transport )
      {
// Make changes to object members to indicate move
        it1 -> transport = it2 -> unit_number; // Infantry knows what transport it's on
        it2 -> infantry_ptr_list.add( it1); // Transport knows what infantry is on it
        it1 -> setSeaZone( dest_sea_zone ); // Sea zone the unit is now in
        it1 -> setLandTerr( 0 ); // No longer on a land territory
        it1 -> decMovePoints( ); // Decrement move points
        it1 -> sea_zone_list.add( dest_sea_zone ); // Updates region path used in retreats
        it1 -> setLandSeaOrder( 1 ); // 1 indicates sea zone
        ++it1;
        ++onboard_units;
      }
      else
      {
        ++it2;
        onboard_units = it2 -> infantry_ptr_list.count( );
      }
    } // End while loop
  } // End outer if
return alert
}