next up previous
Next: Completing the simulator: returning Up: Using Plansim to solve Previous: Defining and serializing the


Defining the actions

In Plansim, the way to change the simulator state is through action classes. For the Hanoi domain, we will define a single action, move_disk. This action receives as parameters the disk to be moved, the origin tower and the destination tower.

We will call this class hanoi::move_disk_action. It is derived from plansim::action. We will take as basis the action_template.hpp and action_template.cpp files under the examples/templates directory. These files will be used to create the move_disk_action.hpp and move_disk_action.cpp, respectively. All occurrences of $domain$ in these files are replaced by 'hanoi', and all occurrences of $object$ in these files are replaced by the class name, in our case 'move_disk_action'. For the Hanoi domain we have this single action, for an example of domain defining more than one action see the blocksworld domain under the examples/blocksworld directory.

The move_disk_action constructor looks like:

  move_disk_action::
  move_disk_action( unsigned int disk_number,
                    unsigned int from_tower,
                    unsigned int to_tower ) :
    action( 1. ),
    disk_number_( disk_number ), from_tower_( from_tower ),
    to_tower_( to_tower )
  {
  }

Note that is is assumed that the action's cost is $1$, this is the argument passed to the action constructor.

The move_disk_action changes, though the execute method implementation, the simulator state. The final code looks like:

  void move_disk_action::execute( plansim::simulator& simul ) const
  {
    // Simulator must be downcasted from plansim to hanoi simulator
    simulator* s = dynamic_cast<simulator *>( &simul );
    // Modify simulator state at will
    s->towers_[ from_tower_ ].pop_back();
    s->towers_[ to_tower_ ].push_back( disk_number_ );
  }

We chose to make hanoi::move_disk_action a hanoi::simulator friend. This is not required, but significantly reduces the necessary coding amount.

Every Plansim action must also define how it is written in a stream. This is used by the framework to show the resulting plan, which is in fact a sequence of actions. This is implemented by the print method. For hanoi::move_disk_action we have:

  std::ostream& 
  move_disk_action::print( std::ostream& os ) const
  {
    // Action to stream
    os << "Move disk " << disk_number_ << " from tower " <<
      from_tower_ << " to tower " << to_tower_; 
    return os;
  }


next up previous
Next: Completing the simulator: returning Up: Using Plansim to solve Previous: Defining and serializing the
2005-04-08