#include <hex.h>
Definition at line 194 of file hex.h.
Public Member Functions | |
int | cols (void) const |
int | rows (void) const |
Distance | width (void) const |
Distance | height (void) const |
bool | is_in_range (int i, int j) const |
Hex * | hex (int i, int j) const throw (hex::out_of_range) |
Hex * | hex (Distance x, Distance y) const throw (hex::out_of_range) |
Hex * | hex (const Point &p) const throw (hex::out_of_range) |
Area | to_area (void) const |
Grid (int cols, int rows) throw (hex::out_of_range) | |
Grid (const Grid &right) | |
virtual | ~Grid () |
Hex * | hex (const std::string &s) const throw (out_of_range,invalid_argument) |
Parse strings generated by Hex::str(). | |
std::set< Hex * > | hexes (const std::string &s) const throw (out_of_range,invalid_argument) |
Parse strings generated by set_str(). | |
Area | area (const std::string &s) const throw (out_of_range,invalid_argument) |
Parse strings generated by Area::str(). | |
Path | path (const std::string &s) const throw (out_of_range,invalid_argument) |
Parse strings generated by Path::str(). | |
Boundary | boundary (const std::string &s) const throw (out_of_range,invalid_argument) |
Parse strings generated by Boundary::str(). |
hex::Grid::Grid | ( | int | cols, | |
int | rows | |||
) | throw (hex::out_of_range) |
Definition at line 264 of file grid.cc.
00265 : _hexes(), _cols(cols), _rows(rows) 00266 { 00267 // Perhaps it's perverse to use ints, and then restrict them to be only 00268 // short. I think it just makes the interface less quirky, the code a 00269 // bit more efficient, and using shorts wouldn't really save much memory. 00270 if(0>cols || cols>=0x4000) 00271 throw hex::out_of_range("cols"); 00272 if(0>rows || rows>=0x4000) 00273 throw hex::out_of_range("rows"); 00274 }
hex::Grid::Grid | ( | const Grid & | right | ) |
Definition at line 277 of file grid.cc.
References _hexes.
00277 : _hexes(), _cols(v._cols), _rows(v._rows) 00278 { 00279 using namespace std; 00280 for(map<int,Hex*>::const_iterator h =v._hexes.begin(); h!=v._hexes.end(); ++h) 00281 _hexes.insert( make_pair(h->first,new Hex(*this,*h->second)) ); 00282 }
hex::Grid::~Grid | ( | ) | [virtual] |
int hex::Grid::cols | ( | void | ) | const [inline] |
int hex::Grid::rows | ( | void | ) | const [inline] |
Distance hex::Grid::width | ( | void | ) | const [inline] |
Distance hex::Grid::height | ( | void | ) | const [inline] |
bool hex::Grid::is_in_range | ( | int | i, | |
int | j | |||
) | const [inline] |
Hex * hex::Grid::hex | ( | int | i, | |
int | j | |||
) | const throw (hex::out_of_range) |
Definition at line 71 of file grid.cc.
References hex::Hex::_key().
Referenced by hex::Area::boundary(), hex::Hex::go(), main(), hex::range(), and to_area().
00072 { 00073 int key =Hex::_key(i,j); 00074 std::map<int,Hex*>::const_iterator pos =_hexes.find(key); 00075 if(pos==_hexes.end()) 00076 { 00077 if(0>i || i>=_cols) 00078 throw hex::out_of_range("i"); 00079 if(0>j || j>=_rows) 00080 throw hex::out_of_range("j"); 00081 Hex* newhex = new Hex(*this,i,j); 00082 _hexes.insert( std::make_pair(key,newhex) ); 00083 return newhex; 00084 } 00085 return pos->second; 00086 }
Hex * hex::Grid::hex | ( | Distance | x, | |
Distance | y | |||
) | const throw (hex::out_of_range) |
Definition at line 90 of file grid.cc.
References hex::B, hex::C, hex::E, hex::F, hex::go(), hex::J, and hex::K.
00091 { 00092 // (Note I==1.0, so the factor of I has been omitted.) 00093 const static Distance K_2 =K/2.0; 00094 // BI is unit vector in direction B 00095 const static Distance BIx = 0.5; 00096 const static Distance BIy = 1.5 * K; 00097 // CI is unit vector in direction C 00098 const static Distance CIx = -BIx; 00099 const static Distance CIy = BIy; 00100 00101 // Calculate the 'simple' solution. 00102 y -= K; 00103 int j = lround( y/J ); 00104 if(j % 2) 00105 x -= 1.0; // odd rows 00106 else 00107 x -= 0.5; // even rows 00108 int i = lround( x ); // x / I 00109 // Now calculate the x,y offsets (in units of (I,J) ) 00110 Distance dx = x - Distance(i); // i * I 00111 Distance dy = y - Distance(j) * J; 00112 // Only need more work if |dy| > K/2 00113 if( dy < -K_2 || K_2 < dy ) 00114 { 00115 Distance BId = (BIx * dx) + (BIy * dy); 00116 Distance CId = (CIx * dx) + (CIy * dy); 00117 00118 if( BId > 0.5 ) 00119 go( i,j, B ); 00120 else if( BId < -0.5 ) 00121 go( i,j, E ); 00122 else if( CId > 0.5 ) 00123 go( i,j, C ); 00124 else if( CId < -0.5 ) 00125 go( i,j, F ); 00126 } 00127 return hex(i,j); 00128 }
Hex * hex::Grid::hex | ( | const Point & | p | ) | const throw (hex::out_of_range) |
Area hex::Grid::to_area | ( | void | ) | const |
Hex * hex::Grid::hex | ( | const std::string & | s | ) | const throw (out_of_range,invalid_argument) |
Parse strings generated by Hex::str().
Definition at line 151 of file grid.cc.
00152 { 00153 // Parse strings like: / *[-+]?\d+_ *[-+]?\d+([^\d].*)?/ 00154 // E.g. '1_2' ' +2_ 4' '2_4 # comment' 00155 const char* buf =s.c_str(); 00156 char* endptr =NULL; 00157 errno=0; 00158 int i =::strtol(buf,&endptr,10); 00159 if(endptr==buf || *endptr!='_') 00160 throw hex::invalid_argument(s); 00161 buf =endptr+1; 00162 int j =::strtol(buf,&endptr,10); 00163 if(endptr==buf) 00164 throw hex::invalid_argument(s); 00165 if(ERANGE==errno) 00166 throw hex::out_of_range(s); 00167 return this->hex(i,j); 00168 }
std::set< Hex * > hex::Grid::hexes | ( | const std::string & | s | ) | const throw (out_of_range,invalid_argument) |
Parse strings generated by set_str().
Definition at line 172 of file grid.cc.
Referenced by to_area().
00173 { 00174 // Parse string of space-separated hex coordinates. 00175 // E.g. 1_2 2_3 3_4 00176 std::istringstream is(s); 00177 std::set<Hex*> result; 00178 while(is.good()) 00179 { 00180 std::string tok; 00181 is>>tok; 00182 if(!tok.empty()) 00183 result.insert( this->hex(tok) ); 00184 } 00185 return result; 00186 }
Area hex::Grid::area | ( | const std::string & | s | ) | const throw (out_of_range,invalid_argument) |
Parse strings generated by Area::str().
Definition at line 190 of file grid.cc.
References hex::Hex::go(), and hex::steps().
00191 { 00192 // Parse string of area fillpaths 00193 // E.g. 1,2>CDE:ABC 00194 std::set<Hex*> result; 00195 std::string::size_type pos =s.find_first_of(":>"); 00196 if(pos==std::string::npos) 00197 throw hex::invalid_argument(s); 00198 Hex* origin =this->hex( s.substr(0,pos) ); 00199 Hex* start =origin; 00200 while(pos!=std::string::npos) 00201 { 00202 std::string::size_type next =s.find_first_of(":>",pos+1); 00203 std::string steps =s.substr( pos+1, (next==s.npos)?(next):(next-pos-1) ); 00204 if(s[pos]=='>') 00205 { 00206 start=origin->go(steps); 00207 } 00208 else // ':' 00209 { 00210 std::list<Hex*> hexes =Path(start,steps).hexes(); 00211 std::copy(hexes.begin(), hexes.end(), inserter(result,result.end())); 00212 start=origin; 00213 } 00214 pos=next; 00215 } 00216 return result; 00217 }
Path hex::Grid::path | ( | const std::string & | s | ) | const throw (out_of_range,invalid_argument) |
Parse strings generated by Path::str().
Definition at line 221 of file grid.cc.
00222 { 00223 std::string::size_type colon =s.find(':'); 00224 if(colon==std::string::npos || (colon+1)>=s.size()) 00225 throw hex::invalid_argument(s); 00226 Hex* origin =this->hex( s.substr(0,colon) ); 00227 Path result(origin,s.substr(colon+1)); 00228 return result; 00229 }
Boundary hex::Grid::boundary | ( | const std::string & | s | ) | const throw (out_of_range,invalid_argument) |
Parse strings generated by Boundary::str().
Definition at line 233 of file grid.cc.
References hex::Edge::direction(), hex::Edge::hex(), hex::Edge::next_in(), hex::Edge::next_out(), and hex::to_direction().
00234 { 00235 std::list<Edge*> result; 00236 std::string::size_type plus_minus =s.find_first_of("+-"); 00237 if(plus_minus==std::string::npos || (plus_minus+1)>=s.size()) 00238 throw hex::invalid_argument(s); 00239 bool clockwise =( '-' == s[plus_minus] ); 00240 for(std::string::size_type pos =plus_minus+1; pos<s.size(); ++pos) 00241 { 00242 Direction d =to_direction(s[pos]); 00243 Edge* next; 00244 if(result.empty()) 00245 { 00246 next = this->hex(s.substr(0,plus_minus))->edge(d); 00247 } 00248 else 00249 { 00250 next = result.back()->next_in(clockwise); 00251 if(next->direction() != d) 00252 { 00253 next = result.back()->next_out(clockwise); 00254 if(next->direction() != d) 00255 throw hex::invalid_argument(s); 00256 } 00257 } 00258 result.push_back(next); 00259 } 00260 return result; 00261 }