pathutils.cpp

Go to the documentation of this file.
00001 /* $Id: pathutils.cpp 25489 2008-04-03 12:51:36Z esr $ */
00002 /*
00003    Copyright (C) 2003 - 2008 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 version 2
00008    or at your option any later version.
00009    This program is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY.
00011 
00012    See the COPYING file for more details.
00013 */
00014 
00015 //! @file pathutils.cpp
00016 //! Various pathfinding functions and utilities.
00017 
00018 #include "global.hpp"
00019 
00020 #include "pathutils.hpp"
00021 #include "util.hpp"
00022 
00023 size_t distance_between(const gamemap::location& a, const gamemap::location& b)
00024 {
00025     const size_t hdistance = abs(a.x - b.x);
00026 
00027     const size_t vpenalty = ( (is_even(a.x) && is_odd(b.x) && (a.y < b.y))
00028         || (is_even(b.x) && is_odd(a.x) && (b.y < a.y)) ) ? 1 : 0;
00029 
00030     // For any non-negative integer i, i - i/2 - i%2 == i/2
00031     // previously returned (hdistance + vdistance - vsavings)
00032     // = hdistance + vdistance - minimum(vdistance,hdistance/2+hdistance%2)
00033     // = maximum(hdistance, vdistance+hdistance-hdistance/2-hdistance%2)
00034     // = maximum(hdistance,abs(a.y-b.y)+vpenalty+hdistance/2)
00035 
00036     return maximum<int>(hdistance, abs(a.y - b.y) + vpenalty + hdistance/2);
00037 }
00038 
00039 void get_adjacent_tiles(const gamemap::location& a, gamemap::location* res)
00040 {
00041     res->x = a.x;
00042     res->y = a.y-1;
00043     ++res;
00044     res->x = a.x+1;
00045     res->y = a.y - (is_even(a.x) ? 1:0);
00046     ++res;
00047     res->x = a.x+1;
00048     res->y = a.y + (is_odd(a.x) ? 1:0);
00049     ++res;
00050     res->x = a.x;
00051     res->y = a.y+1;
00052     ++res;
00053     res->x = a.x-1;
00054     res->y = a.y + (is_odd(a.x) ? 1:0);
00055     ++res;
00056     res->x = a.x-1;
00057     res->y = a.y - (is_even(a.x) ? 1:0);
00058 }
00059 
00060 void get_tile_ring(const gamemap::location& a, const int r, std::vector<gamemap::location>& res)
00061 {
00062     if(r <= 0) {
00063         return;
00064     }
00065 
00066     gamemap::location loc = a.get_direction(gamemap::location::SOUTH_WEST, r);
00067 
00068     for(int n = 0; n != 6; ++n) {
00069         const gamemap::location::DIRECTION dir = static_cast<gamemap::location::DIRECTION>(n);
00070         for(int i = 0; i != r; ++i) {
00071             res.push_back(loc);
00072             loc = loc.get_direction(dir, 1);
00073         }
00074     }
00075 }
00076 
00077 void get_tiles_in_radius(const gamemap::location& a, const int r, std::vector<gamemap::location>& res)
00078 {
00079     for(int n = 0; n <= r; ++n) {
00080         get_tile_ring(a, n, res);
00081     }
00082 }
00083 
00084 bool tiles_adjacent(const gamemap::location& a, const gamemap::location& b)
00085 {
00086     // Two tiles are adjacent:
00087     // if y is different by 1, and x by 0,
00088     // or if x is different by 1 and y by 0,
00089     // or if x and y are each different by 1,
00090     // and the x value of the hex with the greater y value is even.
00091 
00092     const int xdiff = abs(a.x - b.x);
00093     const int ydiff = abs(a.y - b.y);
00094     return (ydiff == 1 && a.x == b.x) || (xdiff == 1 && a.y == b.y) ||
00095            (xdiff == 1 && ydiff == 1 && (a.y > b.y ? is_even(a.x) : is_even(b.x)));
00096 }
00097 

Generated by doxygen 1.5.5 on 23 May 2008 for The Battle for Wesnoth
Gna! | Forum | Wiki | CIA | devdocs