Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #ifndef WB_VISITOR_HPP_
00031 #define WB_VISITOR_HPP_
00032
00033 #include "action.hpp"
00034 #include "side_actions.hpp"
00035
00036 #include "foreach.hpp"
00037 #include "play_controller.hpp"
00038 #include "resources.hpp"
00039
00040 #include <boost/noncopyable.hpp>
00041
00042 namespace wb
00043 {
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055 template<typename Derived>
00056 class enable_visit_all
00057 {
00058 public:
00059 void visit_all() { visit_all_helper(false); }
00060 void reverse_visit_all() { visit_all_helper(true); }
00061
00062 protected:
00063
00064
00065
00066
00067
00068
00069
00070
00071 bool pre_visit_team(size_t , size_t , team&, side_actions& sa) { return !sa.hidden(); }
00072
00073 bool post_visit_team(size_t , size_t , team&, side_actions&) { return true; }
00074
00075 private:
00076 void visit_all_helper( const bool reverse)
00077 {
00078 assert(resources::teams != NULL);
00079
00080 Derived* const new_this = static_cast<Derived*>(this);
00081
00082
00083 size_t max_turns = 0;
00084 foreach(team& t, *resources::teams)
00085 max_turns = std::max(max_turns,t.get_side_actions()->num_turns());
00086
00087 size_t const current_team = resources::controller->current_side() - 1;
00088 size_t const num_teams = resources::teams->size();
00089
00090 for(size_t turn_iter=0; turn_iter<max_turns; ++turn_iter)
00091 {
00092 size_t const turn = (reverse? max_turns-1-turn_iter: turn_iter);
00093
00094
00095 for(size_t team_iter = 0; team_iter < num_teams; ++team_iter)
00096 {
00097 size_t const team_index
00098 = (current_team+num_teams+(reverse? -1-team_iter: team_iter)) % num_teams;
00099 team& t = resources::teams->at(team_index);
00100 side_actions& sa = *t.get_side_actions();
00101 if(!new_this->pre_visit_team(turn_iter, team_index, t, sa))
00102 continue;
00103
00104 if(reverse)
00105 {
00106 side_actions::rrange_t acts = sa.riter_turn(turn);
00107 side_actions::reverse_iterator itor = acts.first;
00108 side_actions::reverse_iterator end = acts.second;
00109 while(itor!=end) {
00110 ++itor;
00111 if(!new_this->process(team_index,t,sa,itor.base()))
00112 return;
00113 }
00114 }
00115 else
00116 {
00117 side_actions::range_t acts = sa.iter_turn(turn);
00118 side_actions::iterator itor = acts.first;
00119 side_actions::iterator end = acts.second;
00120 for(; itor!=end; ++itor)
00121 if(!new_this->process(team_index,t,sa,itor))
00122 return;
00123 }
00124 if(!new_this->post_visit_team(turn_iter, team_index, t, sa))
00125 break;
00126 }
00127 }
00128 }
00129 };
00130
00131
00132
00133
00134
00135
00136
00137
00138 class visitor
00139 : private boost::noncopyable
00140 {
00141
00142 public:
00143
00144 virtual void visit(move_ptr move) = 0;
00145 virtual void visit(attack_ptr attack) = 0;
00146 virtual void visit(recruit_ptr recruit) = 0;
00147 virtual void visit(recall_ptr recall) = 0;
00148 virtual void visit(suppose_dead_ptr sup_d) = 0;
00149
00150 protected:
00151 visitor() {}
00152 virtual ~visitor() {}
00153
00154
00155
00156
00157
00158
00159 bool process(size_t , team&, side_actions&, side_actions::iterator itor)
00160 { (*itor)->accept(*this); return true; }
00161
00162
00163 void visit_all_actions() {visitor_helper::visit_all_actions_helper(this);}
00164
00165 private:
00166 struct visitor_helper
00167 : enable_visit_all<visitor_helper>
00168 {
00169 bool process(size_t , team&, side_actions&, side_actions::iterator itor)
00170 { (*itor)->accept(*v_); return true; }
00171
00172 static void visit_all_actions_helper(visitor* v)
00173 {
00174 static visitor_helper vh;
00175 vh.v_ = v;
00176 vh.visit_all();
00177 }
00178
00179 visitor* v_;
00180 };
00181 };
00182
00183 }
00184
00185 #endif