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.