Now we are ready to complete the simulator object, by implementing the service of returning, for a given state, all the applicable actions. This is done by the get_applicable_action_sets method implementation. The final code for our example is:
void
simulator::
get_applicable_action_sets( std::
list<plansim::action_set::const_ptr>& as )
const
{
// Creating an action set
std::list<plansim::action::const_ptr> action_list;
for( unsigned int from = 0; from < towers_.size(); from++ ) {
// from tower must have at least one disk
if( towers_[ from ].size() == 0 ) {
continue;
}
for( unsigned int to = 0; to < towers_.size(); to++ ) {
// Moves to the same tower are not allowed
if( to == from ) {
continue;
}
// Picks the disk in to tower, -1 if no disk is present
int disk_in_to_tower;
if( towers_[ to ].size() == 0 ) {
disk_in_to_tower = -1;
} else {
disk_in_to_tower = towers_[ to ].back();
}
// Checks if disk may be moved
if( towers_[ from ].back() > disk_in_to_tower ) {
// Disk may be moved, action is created
action_list.clear();
plansim::action::const_ptr ap;
ap.reset( new move_disk_action( towers_[ from ].back(),
from, to ) );
action_list.push_back( ap );
plansim::action_set::const_ptr
asp( new plansim::action_set( action_list ) );
as.push_back( asp );
}
}
}
}
Plansim supports the use of simultaneous actions, that is, actions that may be applied together at the same instant. In order to do so the method interface expects plansim::action_sets to be created. In our case every set contains a single element.