1 #pragma once 2 3 #include "actor.h" 4 #include "coord-circle.h" 5 #include "los-type.h" 6 7 #include <vector> 8 9 using std::vector; 10 11 class rectangle_iterator : public iterator<forward_iterator_tag, coord_def> 12 { 13 public: 14 rectangle_iterator(const coord_def& corner1, const coord_def& corner2); 15 rectangle_iterator(const coord_def& center, int halfside, 16 bool clip_to_map = false); 17 explicit rectangle_iterator(int x_border_dist, int y_border_dist = -1); 18 operator bool() const PURE; 19 coord_def operator *() const PURE; 20 const coord_def* operator->() const PURE; 21 22 void operator ++ (); 23 void operator ++ (int); 24 private: 25 coord_def current, topleft, bottomright; 26 }; 27 28 /** 29 * @class random_rectangle_iterator 30 * Iterator over coordinates in a rectangular region in a 31 * random order. This interator does not favour any given 32 * direction, but is slower than rectangle_iterator. 33 * 34 * When this iterator has returned all elements, it will just 35 * return the top left corner forever. 36 */ 37 class random_rectangle_iterator : public iterator<forward_iterator_tag, 38 coord_def> 39 { 40 public: 41 random_rectangle_iterator(const coord_def& corner1, 42 const coord_def& corner2); 43 explicit random_rectangle_iterator(int x_border_dist, 44 int y_border_dist = -1); 45 operator bool() const PURE; 46 coord_def operator *() const PURE; 47 const coord_def* operator->() const PURE; 48 49 void operator ++ (); 50 void operator ++ (int); 51 private: 52 coord_def top_left; 53 vector<coord_def> remaining; 54 int current; 55 }; 56 57 /** 58 * @class radius_iterator 59 * Iterator over coordinates in a circular region. 60 * 61 * The region can be a circle of any r²; furthermore, the cells can 62 * be restricted to lie within LOS from the center (of any type) 63 * centered at the same point), and to exclude the center. 64 */ 65 class radius_iterator : public iterator<forward_iterator_tag, coord_def> 66 { 67 public: 68 radius_iterator(const coord_def center, int radius, circle_type ctype, 69 bool exclude_center = false); 70 radius_iterator(const coord_def center, int radius, circle_type ctype, 71 los_type los, bool exclude_center = false); 72 radius_iterator(const coord_def center, los_type los, 73 bool exclude_center = false); 74 75 operator bool() const PURE; 76 coord_def operator *() const PURE; 77 const coord_def *operator->() const PURE; 78 79 void operator ++ (); 80 void operator ++ (int); 81 82 private: 83 enum costate { RI_DONE, RI_START, RI_SE, RI_NE, RI_SW, RI_NW }; 84 int x, y, cost_x, cost_y, credit, credit_x, credit_y, base_cost, inc_cost; 85 bool is_square; 86 87 costate state; 88 coord_def center; 89 los_type los; 90 coord_def current; // storage for operator-> 91 }; 92 93 /** 94 * @class vision_iterator 95 * Iterator over coordinates in view of a certain actor. 96 * 97 * Uses the actor's see_cell method, which includes checks for scrying-like 98 * effects as well as respecting the los_type 99 */ 100 class vision_iterator : public radius_iterator 101 { 102 public: vision_iterator(const actor & _who)103 explicit vision_iterator(const actor& _who) : 104 radius_iterator(_who.pos(), LOS_NONE), who(_who) {}; 105 106 void operator ++ (); 107 void operator ++ (int); 108 private: 109 const actor& who; 110 }; 111 112 class adjacent_iterator : public iterator<forward_iterator_tag, coord_def> 113 { 114 public: 115 adjacent_iterator(const coord_def pos, bool _exclude_center = true) center(pos)116 : center(pos), i(_exclude_center ? 8 : 9) {++(*this);}; 117 118 operator bool() const PURE; 119 coord_def operator *() const PURE; 120 const coord_def *operator->() const PURE; 121 122 void operator ++ (); 123 void operator ++ (int); 124 private: 125 coord_def center; 126 coord_def val; 127 int i; 128 }; 129 130 class orth_adjacent_iterator : public radius_iterator 131 { 132 public: 133 explicit orth_adjacent_iterator(const coord_def& pos, 134 bool _exclude_center = true) : 135 radius_iterator(pos, 1, C_POINTY, _exclude_center) {} 136 }; 137 138 /* @class distance_iterator 139 * Iterates over coordinates in integer ranges. 140 * 141 * Unlike other iterators, it tries hard to not favourite any 142 * particular direction (unless fair = false, when it saves some CPU). 143 */ 144 class distance_iterator : public iterator<forward_iterator_tag, coord_def> 145 { 146 public: 147 distance_iterator(const coord_def& _center, 148 bool _fair = true, 149 bool exclude_center = true, 150 int _max_radius = GDM); 151 operator bool() const PURE; 152 coord_def operator *() const PURE; 153 const coord_def *operator->() const PURE; 154 155 const distance_iterator &operator ++(); 156 void operator ++(int); 157 int radius() const; 158 private: 159 coord_def center, current; 160 vector<coord_def> lists[3], *vcur, *vnear, *vfar; 161 int r, max_radius; 162 int threshold; 163 unsigned int icur, iend; 164 bool fair; 165 bool advance(); 166 void push_neigh(coord_def from, int dx, int dy); 167 }; 168 169 // If this becomes performance-critical, reimplement it as adjacent_iterator 170 // with a permutation array. 171 class fair_adjacent_iterator : public distance_iterator 172 { 173 public: 174 fair_adjacent_iterator(coord_def _center, bool _exclude_center = true) 175 : distance_iterator(_center, true, _exclude_center, 1) {} 176 }; 177 178 # ifdef DEBUG_TESTS 179 void coordit_tests(); 180 # endif 181