1 // Copyright (C) 2009, 2014 Ben Asselstine
2 //
3 //  This program is free software; you can redistribute it and/or modify
4 //  it under the terms of the GNU General Public License as published by
5 //  the Free Software Foundation; either version 3 of the License, or
6 //  (at your option) any later version.
7 //
8 //  This program is distributed in the hope that it will be useful,
9 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 //  GNU Library General Public License for more details.
12 //
13 //  You should have received a copy of the GNU General Public License
14 //  along with this program; if not, write to the Free Software
15 //  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16 //  02110-1301, USA.
17 
18 #pragma once
19 #ifndef PATH_CALCULATOR_H
20 #define PATH_CALCULATOR_H
21 
22 #include <gtkmm.h>
23 #include "vector.h"
24 
25 class Stack;
26 class Path;
27 class City;
28 class Player;
29 class ArmyProdBase;
30 class ArmyProto;
31 
32 //! An object that calculates shortest paths on a weighted grid.
33 /**
34  */
35 class PathCalculator
36 {
37 public:
38 
39     //! Default constructor.
40     PathCalculator(const Stack *s, bool zigzag = true, int enemy_city_avoidance = -1, int enemy_stack_avoidance = -1);
41 
42     //! Alternate constructor.  calculate with a copy of the stack.
43     PathCalculator(const Stack &s, bool zigzag = true, int enemy_city_avoidance = -1, int enemy_stack_avoidance = -1);
44 
45     //! Alternate constructor.  calculate with a new stack of one army.
46     PathCalculator(Player *p, Vector<int> src, const ArmyProdBase *prodbase = NULL, bool zigzag = true, int enemy_city_avoidance = -1, int enemy_stack_avoidance = -1);
47 
48     //! Copy constructor.
49     PathCalculator(const PathCalculator&);
50 
51     //! Destructor.
52     ~PathCalculator();
53 
54     bool isReachable(Vector<int> pos);
55 
56     Path* calculate(Vector<int> dest, guint32 &moves, guint32 &turns, guint32 &left, bool zigzag = true);
57 
58     Path* calculateToCity (City *c, guint32 &moves, guint32 &turns, guint32 &left, bool zigzag = true);
59     int calculate(Vector<int> dest, bool zigzag = true);
60 
61     static bool isBlocked(const Stack *s, Vector<int> pos, bool enemy_cities_block, bool enemy_stacks_block);
62 
63     //! Return the positions on the map that are reachable in MP or less.
64     std::list<Vector<int> > getReachablePositions(int mp = 0);
65 private:
66     //! A PathCalculator helper struct for a weighted tile on the map.
67     struct node
68       {
69 	int moves;
70 	int turns;
71 	int moves_left;
72       };
73     struct node *nodes;
74     const Stack *stack;
75     bool flying;
76     guint32 d_bonus;
77     int land_reset_moves;
78     int boat_reset_moves;
79     bool zigzag;
80     bool on_ship;
81     int enemy_city_avoidance;
82     int enemy_stack_avoidance;
83 
84     /**
85      * Checks how many movement points are needed to cross a tile from
86      * an adjacent tile.
87      *
88      * @param pos    This is the origin point that the Stack is moving from.
89      *
90      * @param dest   This is the destination point that we're checking if the
91      * 		     Stack can move to.
92      *
93      * @return The number of movement points required to traverse the
94      *         destination tile, or -1 if movement not possible.
95      */
96     //! Calculates movement points to traverse an adjacent tile.
97     int pointsToMoveTo(Vector<int> pos, Vector<int> next) const;
98 
99     bool load_or_unload(Vector<int> src, Vector<int> dest, bool &on_ship);
100 
101     std::list<Vector<int> > calcMoves(Vector<int> pos);
102     bool calcMoves(Vector<int> pos, Vector<int> next);
103     bool calcFinalMoves(Vector<int> pos);
104     bool calcFinalMoves(Vector<int> pos, Vector<int> next);
105 
106     void populateNodeMap();
107     /**
108      * Checks if the way to a given tile is blocked
109      *
110      * This function returns whether a unit can pass over a tile from
111      * another tile.  The idea here is that the "sides" of certain tiles
112      * are blocked from entry.  E.g. when trying to go from water to
113      * land, without going through a city.
114      *
115      * @param pos    This is the origin point that the Stack is moving from.
116      *
117      * @param dest   This is the destination point that we're checking if
118      * 		 the Stack can move to.
119      *
120      * @note The movement capabilities of a Stack are not taken into
121      *       account in this method.  This method should only be called
122      *       for Stack objects that are not flying.
123      *
124      * @return False if a non-flying stack may pass, true otherwise.
125      *         False if the two points are not adjacent.
126      */
127     //! Checks if the way between adjacent tiles is blocked.
128     bool isBlockedDir(Vector<int> pos, Vector<int> next);
129 
130     //this method involves checking for enemy stacks, cities in the way.
131     bool isBlocked(Vector<int> pos);
132 
133     void dumpNodeMap(Vector<int> dest);
134     bool delete_stack;
135     Stack *load_unload_stack;
136 
137 };
138 
139 #endif
140