summaryrefslogtreecommitdiffstats
path: root/crawl-ref
diff options
context:
space:
mode:
authorRobert Vollmert <rvollmert@gmx.net>2009-11-13 22:09:35 +0100
committerRobert Vollmert <rvollmert@gmx.net>2009-11-13 22:51:34 +0100
commitb0d21459b7ec552fe6f9690d3d172bf6412551a9 (patch)
tree891cdd33dfa81f5060af2d1e0dbcb602b9c39d16 /crawl-ref
parent8f81aa0a6fcb839a91b70e29d006f6858fb303b6 (diff)
downloadcrawl-ref-b0d21459b7ec552fe6f9690d3d172bf6412551a9.tar.gz
crawl-ref-b0d21459b7ec552fe6f9690d3d172bf6412551a9.zip
Reimplement radius_iterator on the basis of circle_def.
Diffstat (limited to 'crawl-ref')
-rw-r--r--crawl-ref/source/coord-circle.cc39
-rw-r--r--crawl-ref/source/coord-circle.h19
-rw-r--r--crawl-ref/source/coordit.cc127
-rw-r--r--crawl-ref/source/coordit.h40
-rw-r--r--crawl-ref/source/halo.cc1
5 files changed, 121 insertions, 105 deletions
diff --git a/crawl-ref/source/coord-circle.cc b/crawl-ref/source/coord-circle.cc
index 9072c6fa3e..8580313e01 100644
--- a/crawl-ref/source/coord-circle.cc
+++ b/crawl-ref/source/coord-circle.cc
@@ -63,6 +63,16 @@ const rect_def& circle_def::get_bbox() const
return (bbox);
}
+const coord_def& circle_def::get_center() const
+{
+ return (origin);
+}
+
+circle_iterator circle_def::iter() const
+{
+ return (circle_iterator(*this));
+}
+
bool circle_def::contains(const coord_def &p) const
{
switch (shape)
@@ -75,32 +85,3 @@ bool circle_def::contains(const coord_def &p) const
return (false);
}
}
-
-circle_iterator::circle_iterator(const circle_def &circle_)
- : circle(circle_), iter(circle_.get_bbox().iter())
-{
- while (iter && !circle.contains(*iter))
- ++iter;
-}
-
-circle_iterator::operator bool() const
-{
- return ((bool)iter);
-}
-
-coord_def circle_iterator::operator*() const
-{
- return (*iter);
-}
-
-void circle_iterator::operator++()
-{
- do
- ++iter;
- while (iter && !circle.contains(*iter));
-}
-
-void circle_iterator::operator++(int)
-{
- ++(*this);
-}
diff --git a/crawl-ref/source/coord-circle.h b/crawl-ref/source/coord-circle.h
index 172e2600b6..9cf52acbe8 100644
--- a/crawl-ref/source/coord-circle.h
+++ b/crawl-ref/source/coord-circle.h
@@ -1,8 +1,6 @@
#ifndef COORD_CIRCLE_H
#define COORD_CIRCLE_H
-#include "coordit.h"
-
enum shape_type
{
SH_SQUARE, // square around an origin
@@ -17,6 +15,7 @@ enum circle_type
C_ROUND
};
+class rectangle_iterator;
class rect_def
{
coord_def min;
@@ -51,6 +50,7 @@ public:
bool contains(const coord_def &p) const;
const rect_def& get_bbox() const;
+ const coord_def& get_center() const;
circle_iterator iter() const;
@@ -58,19 +58,4 @@ private:
void init(int param, circle_type ctype);
};
-class circle_iterator
-{
- const circle_def &circle;
- rectangle_iterator iter;
-
-public:
- circle_iterator(const circle_def &circle_);
-
- operator bool() const;
- coord_def operator*() const;
-
- void operator++();
- void operator++(int);
-};
-
#endif
diff --git a/crawl-ref/source/coordit.cc b/crawl-ref/source/coordit.cc
index 3a759c2a61..e4cf878f37 100644
--- a/crawl-ref/source/coordit.cc
+++ b/crawl-ref/source/coordit.cc
@@ -8,6 +8,7 @@
#include "coordit.h"
#include "coord.h"
+#include "coord-circle.h"
#include "player.h"
rectangle_iterator::rectangle_iterator( const coord_def& corner1,
@@ -59,6 +60,7 @@ rectangle_iterator& rectangle_iterator::operator ++()
return *this;
}
+
rectangle_iterator rectangle_iterator::operator++( int dummy )
{
const rectangle_iterator copy = *this;
@@ -66,85 +68,110 @@ rectangle_iterator rectangle_iterator::operator++( int dummy )
return (copy);
}
-radius_iterator::radius_iterator(const coord_def& _center, int _radius,
- bool _roguelike_metric, bool _require_los,
- bool _exclude_center,
- const los_def* _los)
- : center(_center), radius(_radius), roguelike_metric(_roguelike_metric),
- require_los(_require_los), exclude_center(_exclude_center),
- los(_los), iter_done(false)
+/*
+ * circle iterator
+ */
+
+circle_iterator::circle_iterator(const circle_def &circle_)
+ : circle(circle_), iter(circle_.get_bbox().iter())
{
- reset();
+ while (iter && !circle.contains(*iter))
+ ++iter;
}
-void radius_iterator::reset()
+circle_iterator::operator bool() const
{
- iter_done = false;
+ return ((bool)iter);
+}
- location.x = center.x - radius;
- location.y = center.y - radius;
+coord_def circle_iterator::operator*() const
+{
+ return (*iter);
+}
- if ( !this->on_valid_square() )
- ++(*this);
+void circle_iterator::operator++()
+{
+ do
+ ++iter;
+ while (iter && !circle.contains(*iter));
}
-bool radius_iterator::done() const
+void circle_iterator::operator++(int)
{
- return iter_done;
+ ++(*this);
}
-coord_def radius_iterator::operator *() const
+
+radius_iterator::radius_iterator(const coord_def& center, int param,
+ circle_type ctype,
+ const los_def* _los,
+ bool _exclude_center)
+ : circle(center, param, ctype),
+ iter(circle.iter()),
+ exclude_center(_exclude_center),
+ los(_los)
{
- return location;
+ advance(true);
}
-const coord_def* radius_iterator::operator->() const
+radius_iterator::radius_iterator(const coord_def& _center, int _radius,
+ bool roguelike, bool _require_los,
+ bool _exclude_center,
+ const los_def* _los)
+ : circle(_center, _radius, roguelike ? C_SQUARE : C_POINTY),
+ iter(circle.iter()),
+ exclude_center(_exclude_center),
+ los(_require_los ? (_los ? _los : &you.get_los()) : NULL)
{
- return &location;
+ advance(true);
}
-void radius_iterator::step()
+radius_iterator::radius_iterator(const los_def* los_,
+ bool _exclude_center)
+ : circle(los_->get_bounds()),
+ iter(circle.iter()),
+ exclude_center(_exclude_center),
+ los(los_)
{
- const int minx = std::max(X_BOUND_1+1, center.x - radius);
- const int maxx = std::min(X_BOUND_2-1, center.x + radius);
- const int maxy = std::min(Y_BOUND_2-1, center.y + radius);
+ advance(true);
+}
- // Sweep L-R, U-D
- location.x++;
- if (location.x > maxx)
- {
- location.x = minx;
- location.y++;
- if (location.y > maxy)
- iter_done = true;
- }
+void radius_iterator::advance(bool may_stay)
+{
+ if (!may_stay)
+ ++iter;
+ while (iter && !is_valid_square(*iter))
+ ++iter;
+ current = *iter;
}
-bool radius_iterator::on_valid_square() const
+radius_iterator::operator bool() const
{
- if (!in_bounds(location))
- return (false);
- if (!roguelike_metric && (location - center).abs() > radius*radius)
+ return (iter);
+}
+
+coord_def radius_iterator::operator *() const
+{
+ return (current);
+}
+
+const coord_def* radius_iterator::operator->() const
+{
+ return &current;
+}
+
+bool radius_iterator::is_valid_square(const coord_def &p) const
+{
+ if (exclude_center && p == circle.get_center())
return (false);
- if (require_los)
- {
- if (!los && !you.see_cell(location))
- return (false);
- if (los && !los->see_cell(location))
- return (false);
- }
- if (exclude_center && location == center)
+ if (los && !los->see_cell(p))
return (false);
-
return (true);
}
const radius_iterator& radius_iterator::operator++()
{
- do
- this->step();
- while (!this->done() && !this->on_valid_square());
-
+ advance(false);
return (*this);
}
diff --git a/crawl-ref/source/coordit.h b/crawl-ref/source/coordit.h
index 60fbf1a669..da17c67a7b 100644
--- a/crawl-ref/source/coordit.h
+++ b/crawl-ref/source/coordit.h
@@ -1,6 +1,8 @@
#ifndef COORDIT_H
#define COORDIT_H
+#include "coord-circle.h"
+
class rectangle_iterator :
public std::iterator<std::forward_iterator_tag, coord_def>
{
@@ -17,33 +19,53 @@ private:
coord_def current, topleft, bottomright;
};
+class circle_iterator
+{
+ const circle_def &circle;
+ rectangle_iterator iter;
+
+public:
+ circle_iterator(const circle_def &circle_);
+
+ operator bool() const;
+ coord_def operator*() const;
+
+ void operator++();
+ void operator++(int);
+};
+
class los_def;
class radius_iterator : public std::iterator<std::forward_iterator_tag,
coord_def>
{
public:
+ radius_iterator(const coord_def& center, int param,
+ circle_type ctype,
+ const los_def* los = NULL,
+ bool exclude_center = false);
radius_iterator(const coord_def& center, int radius,
bool roguelike_metric = true,
bool require_los = true,
bool exclude_center = false,
const los_def* los = NULL);
- bool done() const;
- void reset();
- operator bool() const { return !done(); }
+ radius_iterator(const los_def* los,
+ bool exclude_center = false);
+ operator bool() const;
coord_def operator *() const;
const coord_def* operator->() const;
const radius_iterator& operator ++ ();
radius_iterator operator ++ (int);
+
private:
- void step();
- bool on_valid_square() const;
+ void advance(bool may_stay);
+ bool is_valid_square(const coord_def& p) const;
- coord_def location, center;
- int radius;
- bool roguelike_metric, require_los, exclude_center;
+ circle_def circle;
+ circle_iterator iter;
+ bool exclude_center;
const los_def* los;
- bool iter_done;
+ coord_def current;
};
class adjacent_iterator : public radius_iterator
diff --git a/crawl-ref/source/halo.cc b/crawl-ref/source/halo.cc
index f37bbf8cf9..a71447ac2b 100644
--- a/crawl-ref/source/halo.cc
+++ b/crawl-ref/source/halo.cc
@@ -3,6 +3,7 @@
#include "halo.h"
#include "actor.h"
+#include "coordit.h"
#include "player.h"
#include "monster.h"
#include "religion.h"