// $Id: graph.hpp 2986 2007-08-17 16:20:09Z grumbel $ // // Pingus - A free Lemmings clone // Copyright (C) 2002 Ingo Ruhnke // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifndef HEADER_GRAPH_HXX #define HEADER_GRAPH_HXX #include #include #include #include namespace WorldMapNS { typedef int NodeId; typedef int EdgeId; extern const NodeId NoNode; extern const EdgeId NoEdge; template class Node { public: Node (const NodeType& d) : data (d) {} Node& operator= (const NodeType& d) { data = d; return *this; } NodeType data; std::vector next; }; template class Edge { public: NodeId source; NodeId destination; float cost; EdgeType data; Edge (const EdgeType& arg_data, const NodeId& s, const NodeId& d, float c) : source (s), destination (d), cost (c), data(arg_data) { } }; template class Graph { private: std::vector > nodes; std::vector > edges; public: Graph () { } Graph (const Graph&) { assert (false); } Graph& operator= (const Graph&) { assert (false); return *this; } ~Graph () { } NodeId add_node (NodeType d) { nodes.push_back (Node(d)); return NodeId (nodes.size ()-1); } EdgeId add_edge (const EdgeType& data, const NodeId& a, const NodeId& b, float cost) { Edge new_edge (data, a, b, cost); edges.push_back (new_edge); resolve_node(a).next.push_back ((int)edges.size()-1); return EdgeId (edges.size ()-1); } std::pair add_bi_edge (const EdgeType& data, const NodeId& a, const NodeId& b, float cost) { std::pair ret; ret.first = add_edge (data, a, b, cost); ret.second = add_edge (data, b, a, cost); return ret; } void remove_node (const NodeId& node) { assert (!"remove_node: not implemented"); } void remove_edge (const NodeId& node1, const NodeId& node2) { assert (!"remove_edge: not implemented"); } Edge& resolve_edge (const EdgeId& node) { // FIXME: No error handling return edges[node]; } /** Translates a NodeId into the corresponding Node */ Node& resolve_node (const NodeId& node) { // FIXME: No error handling return nodes[node]; } Edge& resolve_edge(const NodeId& source, const NodeId& destination) { // FIXME: this could be done faster with an adjacense matrix for (typename std::vector >::iterator i = edges.begin(); i != edges.end(); ++i) { if (i->source == source && i->destination == destination) return *i; } std::cout << "couldn't resolve edge: source=" << source << " destination=" << destination << std::endl; assert(false); return *((Edge*) 0); } /* FIXME: This might give problems under MSVC, so it could be better to not use it */ template void for_each_node (Func func) { std::for_each (nodes.begin (), nodes.end (), func); } template void for_each_edge (Func func) { std::for_each (edges.begin (), edges.end (), func); } int nodes_size () { return nodes.size (); } int max_node_handler_value () { return (int)nodes.size (); } }; } // namespace WorldMapNS #endif /* EOF */