map_location.hpp

Go to the documentation of this file.
00001 /* $Id: map_location.hpp 53711 2012-03-31 08:29:26Z boucman $ */
00002 /*
00003    Copyright (C) 2003 - 2012 by David White <dave@whitevine.net>
00004    Part of the Battle for Wesnoth Project http://www.wesnoth.org/
00005 
00006    This program is free software; you can redistribute it and/or modify
00007    it under the terms of the GNU General Public License as published by
00008    the Free Software Foundation; either version 2 of the License, or
00009    (at your option) any later version.
00010    This program is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY.
00012 
00013    See the COPYING file for more details.
00014 */
00015 
00016 /** @file */
00017 
00018 #ifndef MAP_LOCATION_H_INCLUDED
00019 #define MAP_LOCATION_H_INCLUDED
00020 
00021 class config;
00022 class variable_set;
00023 
00024 #include <string>
00025 #include <vector>
00026 #include <set>
00027 #include <boost/unordered_map.hpp>
00028 
00029 /**
00030  * Encapsulates the map of the game.
00031  *
00032  * Although the game is hexagonal, the map is stored as a grid.
00033  * Each type of terrain is represented by a multiletter terrain code.
00034  * @todo Update for new map-format.
00035  */
00036 /** Represents a location on the map. */
00037 struct map_location {
00038     /** Valid directions which can be moved in our hexagonal world. */
00039     enum DIRECTION { NORTH, NORTH_EAST, SOUTH_EAST, SOUTH,
00040                      SOUTH_WEST, NORTH_WEST, NDIRECTIONS };
00041 
00042     static DIRECTION parse_direction(const std::string& str);
00043 
00044     /**
00045      * Parse_directions takes a comma-separated list, and filters out any
00046      * invalid directions
00047      */
00048     static std::vector<DIRECTION> parse_directions(const std::string& str);
00049     static std::string write_direction(DIRECTION dir);
00050 
00051     map_location() : x(-1000), y(-1000) {}
00052     map_location(int x, int y) : x(x), y(y) {}
00053     map_location(const config& cfg, const variable_set *variables);
00054 
00055     void write(config& cfg) const;
00056 
00057     inline bool valid() const { return x >= 0 && y >= 0; }
00058 
00059     inline bool valid(const int parWidth, const int parHeight) const
00060     {
00061         return ((x >= 0) && (y >= 0) && (x < parWidth) && (y < parHeight));
00062     }
00063 
00064     int x, y;
00065     bool matches_range(const std::string& xloc, const std::string& yloc) const;
00066 
00067     // Inlining those for performance reasons
00068     bool operator<(const map_location& a) const { return x < a.x || (x == a.x && y < a.y); }
00069     bool operator==(const map_location& a) const { return x == a.x && y == a.y; }
00070     bool operator!=(const map_location& a) const { return !operator==(a); }
00071 
00072         /** three-way comparator */
00073     int do_compare(const map_location& a) const {return x == a.x ? y - a.y : x - a.x; }
00074 
00075     // Adds an absolute location to a "delta" location
00076     // This is not the mathematically correct behaviour, it is neither
00077     // commutative nor associative. Negative coordinates may give strange
00078     // results. It is retained because terrain builder code relies in this
00079     // broken behaviour. Best avoid.
00080     map_location legacy_negation() const;
00081     map_location legacy_sum(const map_location &a) const;
00082     map_location& legacy_sum_assign(const map_location &a);
00083     map_location legacy_difference(const map_location &a) const;
00084 
00085     // Location arithmetic operations treating the locations as vectors in
00086     // a hex-based space. These operations form an abelian group, i.e.
00087     // everything works as you would expect addition and subtraction to
00088     // work, with associativity and commutativity.
00089     map_location vector_negation() const;
00090     map_location vector_sum(const map_location &a) const;
00091     map_location& vector_sum_assign(const map_location &a);
00092     map_location& vector_difference_assign(const map_location &a);
00093 
00094     // Do n step in the direction d
00095     map_location get_direction(DIRECTION d, int n = 1) const;
00096     DIRECTION get_relative_dir(map_location loc) const;
00097     static DIRECTION get_opposite_dir(DIRECTION d);
00098 
00099     static const map_location null_location;
00100 
00101     friend std::size_t hash_value(map_location const &a);
00102 };
00103 
00104 /** Function which tells if two locations are adjacent. */
00105 bool tiles_adjacent(const map_location& a, const map_location& b);
00106 
00107 /**
00108  * Function which, given a location, will place all adjacent locations in res.
00109  * res must point to an array of 6 location objects.
00110  */
00111 void get_adjacent_tiles(const map_location& a, map_location* res);
00112 
00113 /**
00114  * Function which gives the number of hexes between two tiles
00115  * (i.e. the minimum number of hexes that have to be traversed
00116  * to get from one hex to the other).
00117  */
00118 size_t distance_between(const map_location& a, const map_location& b);
00119 
00120 /** Parses ranges of locations into a vector of locations. */
00121 std::vector<map_location> parse_location_range(const std::string& xvals,
00122     const std::string &yvals, bool with_border = false);
00123 
00124 /**
00125  * Write a set of locations into a config using ranges,
00126  * adding keys x=x1,..,xn and y=y1a-y1b,..,yna-ynb
00127  */
00128 void write_location_range(const std::set<map_location>& locs, config& cfg);
00129 
00130 /** Parse x,y keys of a config into a vector of locations */
00131 void read_locations(const config& cfg, std::vector<map_location>& locs);
00132 
00133 /** Write a vector of locations into a config
00134  *  adding keys x=x1,x2,..,xn and y=y1,y2,..,yn */
00135 void write_locations(const std::vector<map_location>& locs, config& cfg);
00136 
00137 /** Dumps a position on a stream, for debug purposes. */
00138 std::ostream &operator<<(std::ostream &s, map_location const &l);
00139 /** Dumps a vector of positions on a stream, for debug purposes. */
00140 std::ostream &operator<<(std::ostream &s, std::vector<map_location> const &v);
00141 
00142 /** Inlined bodies **/
00143 inline std::size_t hash_value(map_location  const & a){
00144     boost::hash<size_t> h;
00145     return h( (a.x << 16) ^ a.y );
00146 }
00147 
00148 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated by doxygen 1.7.1 on Fri May 25 2012 01:03:05 for The Battle for Wesnoth
Gna! | Forum | Wiki | CIA | devdocs