Bonsoir à tous.
Je bloque sur une erreur de compilation depuis 1 heure et pas moyen de savoir d'où elle sort. C'est la fameuse undefined reference, en théorie je sais ce que c'est (souvent dû à une déclaration sans implémentation). Je met le code en "vrac" réparti dans 5 fichiers et compilé avec la commande :
En résumé, c'est une classe "classique" maze qui hérite d'une classe template grid_graph.
Code : Sélectionner tout - Visualiser dans une fenêtre à part g++ grid_graph.cpp maze.cpp test.cpp
Code de test.
Classe Maze.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 #include "maze.hpp" int main(int argc, char* argv[]) { maze m = maze(5,5); return 0; }
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 #ifndef MAZE #define MAZE #include "grid_graph.hpp" #include <utility> #include <cmath> struct maze_vertex { char walls; int altitude; }; class maze : public grid_graph<maze_vertex> { public: maze(std::size_t columns, std::size_t lines); void wall(std::size_t x, std::size_t y, direction d); void altitude(std::size_t x, std::size_t y, std::size_t altitude); std::size_t distance(vertex_type &source, vertex_type &target); }; #endifClasse grid_graph.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37 #include "maze.hpp" maze::maze(std::size_t x_max, std::size_t y_max) : grid_graph(x_max, y_max) { } void maze::wall(std::size_t x, std::size_t y, direction d) { std::pair<std::size_t, std::size_t> p = std::make_pair<std::size_t, std::size_t>(x,y); vertex_value(p).walls ^= (1 << d); } void maze::altitude(std::size_t x, std::size_t y, std::size_t altitude) { std::pair<std::size_t, std::size_t> p = std::make_pair<std::size_t, std::size_t>(x,y); vertex_value(p).altitude = altitude; } std::size_t maze::distance(vertex_type &source, vertex_type &target) { /* Euclidean distance : n is the number of dimension. n distance(P,Q) = Square root ( SUM ( Pi - Qi) ) i=0 */ std::size_t index_source = index(source); std::size_t index_target = index(target); std::size_t diff = std::abs(index_source - index_target); if(diff == 1 || diff == x_max) { return std::sqrt((source.first - target.first) + (source.second - target.second) + (graph[index_source].altitude - graph[index_target].altitude)); } return INFINITE_VALUE; }
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94 #ifndef GRID_GRAPH #define GRID_GRAPH #include <vector> #include <limits> #include <stdexcept> #include <cmath> #include <utility> template <typename value_type> class grid_graph { public: typedef std::pair<std::size_t, std::size_t> vertex_type; typedef typename std::vector<value_type>::iterator value_iterator; typedef enum {TOP, RIGHT, BOTTOM, LEFT} direction; static const std::size_t INFINITE_VALUE; static const std::size_t UNDEFINED; protected: struct end_vertex_iterator_tag {}; struct begin_vertex_iterator_tag {}; std::size_t index(vertex_type &vertex); std::vector<value_type> graph; const std::size_t x_max; const std::size_t y_max; public: struct vertex_iterator { private: std::size_t index; const std::size_t x_max; const std::size_t y_max; vertex_iterator(const std::size_t x_max, const std::size_t y_max, begin_vertex_iterator_tag) : x_max(x_max), y_max(y_max), index(0){}; vertex_iterator(const std::size_t x_max, const std::size_t y_max, end_vertex_iterator_tag) : x_max(x_max), y_max(y_max), index(x_max*y_max){}; public: bool operator==(const vertex_iterator &v) const { return index == v.index; } bool operator!=(const vertex_iterator &v) const { return index != v.index; } void operator++() { index += (index < x_max*y_max); } void operator--() { index -= (index > 0); } grid_graph::vertex_type operator*() { if(index < x_max*y_max) return std::make_pair<std::size_t, std::size_t>(index % y_max, index % x_max); } }; grid_graph(std::size_t columns, std::size_t lines); vertex_iterator vertex_begin(); vertex_iterator vertex_end(); value_iterator value_begin(); value_iterator value_end(); std::size_t vertex_size(); value_type& vertex_value(vertex_type &vertex); template<typename neighbor_container> void neighbor(vertex_type &vertex, neighbor_container &neighbors); vertex_type next(vertex_type &vertex, direction x) throw(); std::size_t distance(vertex_type &source, vertex_type &target); std::size_t unique_id(vertex_type &vertex); }; #endifDésolé pour le paté de code mais bon je suppose que vous avez déjà vu plus gros
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105 #include "grid_graph.hpp" template <typename value_type> const std::size_t grid_graph<value_type>::INFINITE_VALUE = std::numeric_limits<std::size_t>::max(); template <typename value_type> const std::size_t grid_graph<value_type>::UNDEFINED = std::numeric_limits<std::size_t>::max(); template <typename value_type> grid_graph<value_type>::grid_graph(std::size_t x_maxs, std::size_t y_maxs) { x_max = x_maxs; y_max = y_maxs; graph = std::vector<value_type>(); graph.resize(x_max * y_max); } template <typename value_type> std::size_t grid_graph<value_type>::vertex_size() { return graph.size(); } template <typename value_type> std::size_t grid_graph<value_type>::unique_id(vertex_type &vertex) { return index(vertex); } template <typename value_type> typename grid_graph<value_type>::value_iterator grid_graph<value_type>::value_begin() { return graph.begin(); } template <typename value_type> typename grid_graph<value_type>::value_iterator grid_graph<value_type>::value_end() { return graph.end(); } template <typename value_type> typename grid_graph<value_type>::vertex_iterator grid_graph<value_type>::vertex_begin() { return vertex_iterator(x_max, y_max, begin_vertex_iterator_tag()); } template <typename value_type> typename grid_graph<value_type>::vertex_iterator grid_graph<value_type>::vertex_end() { return vertex_iterator(x_max, y_max, end_vertex_iterator_tag()); } template <typename value_type> std::size_t grid_graph<value_type>::index(vertex_type &vertex) { return vertex.first + vertex.second * x_max; } template <typename value_type> value_type& grid_graph<value_type>::vertex_value(vertex_type &vertex) { return graph[index(vertex)]; } template <typename value_type> template <typename neighbor_container> void grid_graph<value_type>::neighbor(vertex_type &vertex, neighbor_container &neighbors) { for(int d=0; d < 4; ++d) try{ neighbors.push_back(next(vertex, d)); }catch(std::out_of_range &oor){} } template <typename value_type> typename grid_graph<value_type>::vertex_type grid_graph<value_type>::next(vertex_type &vertex, direction x) throw() { std::size_t vertex_index = index(vertex); switch(x) { case TOP: return graph[vertex_index - x_max]; case RIGHT: if(vertex_index % x_max == (vertex_index + 1) % y_max) return graph[vertex_index + 1]; else throw new std::out_of_range(""); case BOTTOM: return graph[vertex_index + x_max]; case LEFT: if(vertex_index % x_max == (vertex_index - 1) % y_max) return graph[vertex_index - 1]; else throw new std::out_of_range(""); default: throw new std::out_of_range(""); } } template <typename value_type> std::size_t grid_graph<value_type>::distance(vertex_type &source, vertex_type &target) { std::size_t diff = std::abs(index(source) - index(target)); return (diff == 1 || diff == x_max) ? 1 : INFINITE_VALUE; }
Merci.
Partager