From a4460f6d9453bbd7e584937686449cef3e19f052 Mon Sep 17 00:00:00 2001 From: Leo Tenenbaum Date: Mon, 20 Aug 2018 20:34:57 -0400 Subject: Initial commit --- src/graphcoloring/levels/rules/boundrule.cpp | 135 ++++++++++++++++++++++++++ src/graphcoloring/levels/rules/boundrule.hpp | 55 +++++++++++ src/graphcoloring/levels/rules/edgerule.cpp | 82 ++++++++++++++++ src/graphcoloring/levels/rules/edgerule.hpp | 51 ++++++++++ src/graphcoloring/levels/rules/rule.hpp | 37 +++++++ src/graphcoloring/levels/rules/ruleloader.cpp | 92 ++++++++++++++++++ src/graphcoloring/levels/rules/ruleloader.hpp | 53 ++++++++++ src/graphcoloring/levels/rules/rules.cpp | 72 ++++++++++++++ src/graphcoloring/levels/rules/rules.hpp | 42 ++++++++ 9 files changed, 619 insertions(+) create mode 100644 src/graphcoloring/levels/rules/boundrule.cpp create mode 100644 src/graphcoloring/levels/rules/boundrule.hpp create mode 100644 src/graphcoloring/levels/rules/edgerule.cpp create mode 100644 src/graphcoloring/levels/rules/edgerule.hpp create mode 100644 src/graphcoloring/levels/rules/rule.hpp create mode 100644 src/graphcoloring/levels/rules/ruleloader.cpp create mode 100644 src/graphcoloring/levels/rules/ruleloader.hpp create mode 100644 src/graphcoloring/levels/rules/rules.cpp create mode 100644 src/graphcoloring/levels/rules/rules.hpp (limited to 'src/graphcoloring/levels/rules') diff --git a/src/graphcoloring/levels/rules/boundrule.cpp b/src/graphcoloring/levels/rules/boundrule.cpp new file mode 100644 index 0000000..0aef4af --- /dev/null +++ b/src/graphcoloring/levels/rules/boundrule.cpp @@ -0,0 +1,135 @@ +//////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2018 Leo Tenenbaum +// This file is part of GraphColoring. +// +// GraphColoring 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 3 of the License, or +// (at your option) any later version. +// +// GraphColoring 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 GraphColoring. If not, see . +//////////////////////////////////////////////////////////////////////////////// + +#include "boundrule.hpp" + +#include "graphcoloring/level.hpp" +#include "utils/errors.hpp" + +namespace graphcoloring { +namespace rules { + +BoundRule::BoundRule(gui::Color color_, int bound_, bool bound_type_, + bool rule_type_) + : color(color_), bound(bound_), bound_type(bound_type_), + rule_type(rule_type_) +{} + + +BoundRule::BoundRule(pugi::xml_node node, const ColorLoader& color_loader) +{ + LoadFromNode(node, color_loader); +} + +void BoundRule::LoadFromNode(pugi::xml_node node, + const ColorLoader& color_loader) +{ + std::string name(node.name()); + if (name.substr(name.length()-7) == std::string("minimum")) + bound_type = MINIMUM; + else + bound_type = MAXIMUM; + + if (name.substr(0,name.length()-8) == std::string("vertex")) + rule_type = VERTEX_RULE; + else + rule_type = EDGE_RULE; + color = ColorFromAttribute(node.attribute("color"), color_loader); + bound = node.attribute(bound_type == MINIMUM ? "min" : "max").as_int(0); +} + +bool BoundRule::CheckAllCounts(const Graph& graph) const +{ + std::map counts; + for (gui::Color color : Level::colors) + counts[color] = 0; + if (rule_type == VERTEX_RULE) + { + for (const Vertex* v : graph.vertices) + { + if (counts.count(v->Color())) + counts[v->Color()]++; + } + } + else + { + for (const Edge* e : graph.edges) + { + if (counts.count(e->Color())) + counts[e->Color()]++; + else + counts[e->Color()] = 1; + } + } + for (std::pair count : counts) + { + if (bound_type == MINIMUM && count.second < bound) + return false; + if (bound_type == MAXIMUM && count.second > bound) + return false; + } + return true; +} + +bool BoundRule::ObeysRule(const Graph& graph) const +{ + if (color == SAME_COLOR) // For same, check if any color is out of bounds. + return CheckAllCounts(graph); + + int count = 0; + if (rule_type == VERTEX_RULE) + { + for (const Vertex* v : graph.vertices) + if (IsSameColor(v->Color(), color)) + count++; + } + else + { + for (const Edge* e : graph.edges) + if (IsSameColor(e->Color(), color)) + count++; + } + return bound_type == MINIMUM ? (count >= bound) : (count <= bound); +} + +int BoundRule::Render(gui::Window* window, int x, int y, int width) const +{ + int r = Vertex::VERTEX_RADIUS; + window->SetDrawColor(RenderColor(color)); + if (rule_type == VERTEX_RULE) + { + window->DrawCircle(x+r, y+r, r, false); + } + else + { + window->DrawLine(x, y+r, x+width/4, y+r); + } + window->SetTextSize(r*2); + window->DrawText(std::to_string(bound), gui::Position(x+width, y+r), + gui::Alignment::RIGHT, gui::Alignment::CENTER); + window->DrawText(bound_type == MAXIMUM ? ">" : "<", + gui::Position(x+width/2, y+r), + gui::Alignment::CENTER, gui::Alignment::CENTER); + window->SetDrawColor(0xFF0000FF); + window->DrawLine(x+3*width/8, y, x+5*width/8, y+2*r); + return r*2; +} + + +} // namespace rules +} // namespace graphcoloring diff --git a/src/graphcoloring/levels/rules/boundrule.hpp b/src/graphcoloring/levels/rules/boundrule.hpp new file mode 100644 index 0000000..a1c5e09 --- /dev/null +++ b/src/graphcoloring/levels/rules/boundrule.hpp @@ -0,0 +1,55 @@ +//////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2018 Leo Tenenbaum +// This file is part of GraphColoring. +// +// GraphColoring 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 3 of the License, or +// (at your option) any later version. +// +// GraphColoring 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 GraphColoring. If not, see . +//////////////////////////////////////////////////////////////////////////////// + +#ifndef GRAPHCOLORING_LEVELS_RULES_BOUNDRULE_H_ +#define GRAPHCOLORING_LEVELS_RULES_BOUNDRULE_H_ + +#include "graphcoloring/graphs/graph.hpp" + +#include "rules.hpp" +#include "rule.hpp" + +namespace graphcoloring { +namespace rules { + +class BoundRule : public Rule { +public: + BoundRule(gui::Color color = ANY_COLOR, + int bound = 0, bool bound_type = MAXIMUM, + bool rule_type = VERTEX_RULE); + BoundRule(pugi::xml_node node, const ColorLoader& color_loader); + void LoadFromNode(pugi::xml_node node, const ColorLoader& color_loader); + virtual ~BoundRule() {} + bool ObeysRule(const Graph& graph) const; + int Render(gui::Window* window, int x, int y, int width) const; +private: + bool CheckAllCounts(const Graph& graph) const; + static constexpr bool EDGE_RULE = false; + static constexpr bool VERTEX_RULE = true; + static constexpr bool MINIMUM = false; + static constexpr bool MAXIMUM = true; + gui::Color color; + int bound; + bool bound_type; + bool rule_type; +}; + +} // namespace rules +} // namespace graphcoloring + +#endif // GRAPHCOLORING_LEVELS_RULES_BOUNDRULE_H_ diff --git a/src/graphcoloring/levels/rules/edgerule.cpp b/src/graphcoloring/levels/rules/edgerule.cpp new file mode 100644 index 0000000..e2a3a74 --- /dev/null +++ b/src/graphcoloring/levels/rules/edgerule.cpp @@ -0,0 +1,82 @@ +//////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2018 Leo Tenenbaum +// This file is part of GraphColoring. +// +// GraphColoring 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 3 of the License, or +// (at your option) any later version. +// +// GraphColoring 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 GraphColoring. If not, see . +//////////////////////////////////////////////////////////////////////////////// + +#include "edgerule.hpp" + +namespace graphcoloring { +namespace rules { + +EdgeRule::EdgeRule(gui::Color vcolor1, gui::Color vcolor2, gui::Color ecolor) + : vertex_color1(vcolor1), vertex_color2(vcolor2), edge_color(ecolor) +{} + +EdgeRule::EdgeRule(pugi::xml_node node, const ColorLoader& color_loader) +{ + LoadFromNode(node, color_loader); +} + +void EdgeRule::LoadFromNode(pugi::xml_node node,const ColorLoader& color_loader) +{ + vertex_color1 = ColorFromAttribute(node.attribute("v1"), color_loader); + vertex_color2 = ColorFromAttribute(node.attribute("v2"), color_loader); + edge_color = ColorFromAttribute(node.attribute("edge"), color_loader); +} + +bool EdgeRule::ObeysRule(const Edge& edge) const +{ + ResetSameColor(); + if (!IsSameColor(edge.Color(), edge_color)) return true; + + gui::Color v1 = edge.from.Color(); + gui::Color v2 = edge.to.Color(); + bool obeys + = !((IsSameColor(v1,vertex_color1) && IsSameColor(v2,vertex_color2)) + || (IsSameColor(v2,vertex_color1) && IsSameColor(v1,vertex_color2))); + ResetSameColor(); + return obeys; +} + +bool EdgeRule::ObeysRule(const Graph& graph) const +{ + for (const Edge* e : graph.edges) + if (!ObeysRule(*e)) + return false; + return true; +} + +int EdgeRule::Render(gui::Window* window, int x, int y, int width) const +{ + int r = Vertex::VERTEX_RADIUS; + // First vertex + window->SetDrawColor(RenderColor(vertex_color1)); + window->DrawCircle(x+r, y+r, r, false); + // Edge + window->SetDrawColor(RenderColor(edge_color)); + window->DrawLine(x+2*r, y+r, x+width-2*r, y+r); + // Second vertex + window->SetDrawColor(RenderColor(vertex_color2)); + window->DrawCircle(x+width-r, y+r, r, false); + // Red line + window->SetDrawColor(0xFF0000FF); + window->DrawLine(x+width/2-r/2, y+r/2, x+width/2+r/2, y+3*r/2); + return r*2; + +} + +} // namespace rules +} // namespace graphcoloring diff --git a/src/graphcoloring/levels/rules/edgerule.hpp b/src/graphcoloring/levels/rules/edgerule.hpp new file mode 100644 index 0000000..187baf7 --- /dev/null +++ b/src/graphcoloring/levels/rules/edgerule.hpp @@ -0,0 +1,51 @@ +//////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2018 Leo Tenenbaum +// This file is part of GraphColoring. +// +// GraphColoring 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 3 of the License, or +// (at your option) any later version. +// +// GraphColoring 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 GraphColoring. If not, see . +//////////////////////////////////////////////////////////////////////////////// + + +#ifndef GRAPHCOLORING_LEVELS_RULES_EDGERULE_H_ +#define GRAPHCOLORING_LEVELS_RULES_EDGERULE_H_ + +#include "graphcoloring/graphs/graph.hpp" +#include "rules.hpp" +#include "rule.hpp" + +namespace graphcoloring { +namespace rules { + +class EdgeRule : public Rule { +public: + EdgeRule(gui::Color vertex_color1 = ANY_COLOR, + gui::Color vertex_color2 = ANY_COLOR, + gui::Color edge_color = ANY_COLOR); + EdgeRule(pugi::xml_node node, const ColorLoader& color_loader); + void LoadFromNode(pugi::xml_node node, const ColorLoader& color_loader); + bool ObeysRule(const Graph& graph) const; + int Render(gui::Window* window, int x, int y, int width) const; + virtual ~EdgeRule() {} +private: + bool ObeysRule(const Edge& edge) const; + gui::Color vertex_color1; + gui::Color vertex_color2; + gui::Color edge_color; + +}; + +} // namespace rules +} // namespace graphcoloring + +#endif // GRAPHCOLORING_LEVELS_RULES_EDGERULE_H_ diff --git a/src/graphcoloring/levels/rules/rule.hpp b/src/graphcoloring/levels/rules/rule.hpp new file mode 100644 index 0000000..5856fc0 --- /dev/null +++ b/src/graphcoloring/levels/rules/rule.hpp @@ -0,0 +1,37 @@ +//////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2018 Leo Tenenbaum +// This file is part of GraphColoring. +// +// GraphColoring 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 3 of the License, or +// (at your option) any later version. +// +// GraphColoring 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 GraphColoring. If not, see . +//////////////////////////////////////////////////////////////////////////////// + +#ifndef GRAPHCOLORING_LEVELS_RULES_RULE_H_ +#define GRAPHCOLORING_LEVELS_RULES_RULE_H_ + +#include "graphcoloring/graphs/graph.hpp" + +namespace graphcoloring { +namespace rules { + +class Rule { +public: + virtual ~Rule() {} + virtual bool ObeysRule(const Graph& graph) const = 0; + virtual int Render(gui::Window* window, int x, int y, int width) const = 0; // Returns height +}; + +} // namespace rules +} // namespace graphcoloring + +#endif /* GRAPHCOLORING_LEVELS_RULES_RULE_H_ */ diff --git a/src/graphcoloring/levels/rules/ruleloader.cpp b/src/graphcoloring/levels/rules/ruleloader.cpp new file mode 100644 index 0000000..e741594 --- /dev/null +++ b/src/graphcoloring/levels/rules/ruleloader.cpp @@ -0,0 +1,92 @@ +//////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2018 Leo Tenenbaum +// This file is part of GraphColoring. +// +// GraphColoring 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 3 of the License, or +// (at your option) any later version. +// +// GraphColoring 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 GraphColoring. If not, see . +//////////////////////////////////////////////////////////////////////////////// + +#include "ruleloader.hpp" + +#include "graphcoloring/graphcoloring.hpp" + +namespace graphcoloring { + +RuleLoader::RuleLoader() {} + +void RuleLoader::LoadDocument(const pugi::xml_document& document, + const ColorLoader& color_loader) +{ + for (pugi::xml_node rule_node : document.child("rules").children()) + { + std::string name = rule_node.name(); + if (name == "connected") + connected_rule = true; + // These node methods will check the name of the node. + LoadEdgeRule(rule_node, color_loader); + LoadMaximumRule(rule_node, color_loader); + + } +} + +void RuleLoader::LoadEdgeRule(pugi::xml_node node, + const ColorLoader& color_loader) +{ + std::string name = node.name(); + if (name != "edge-rule") return; + rules::EdgeRule rule(node, color_loader); + edge_rules.push_back(rule); + all_rules.push_back(std::make_unique(rule)); +} + +void RuleLoader::LoadMaximumRule(pugi::xml_node node, + const ColorLoader& color_loader) +{ + std::string name = node.name(); + if (name != "vertex-maximum" && name != "edge-maximum" + && name != "vertex-minimum" && name != "edge-minimum") + return; + rules::BoundRule rule(node, color_loader); + maximum_rules.push_back(rule); + all_rules.push_back(std::make_unique(rule)); +} + + +bool RuleLoader::IsValid(const Graph& graph) const +{ + for (auto& rule : all_rules) + if (!rule->ObeysRule(graph)) + return false; + if (connected_rule && !graph.IsConnected()) + return false; + return true; +} + +void RuleLoader::RenderRules(gui::Window* window) const +{ + window->SetDrawColor(GraphColoring::BACKGROUND_COLOR); + window->Clear(); + int x = 10, y = 10; + for (auto& rule : all_rules) + { + if (y >= window->GetHeight()-2*Vertex::VERTEX_RADIUS-10) + { + y = 10; + x += 50 + RULE_COLUMN_WIDTH; + } + int height = rule->Render(window, x, y, RULE_COLUMN_WIDTH); + y += height + 10; + } +} + +} // namespace graphcoloring diff --git a/src/graphcoloring/levels/rules/ruleloader.hpp b/src/graphcoloring/levels/rules/ruleloader.hpp new file mode 100644 index 0000000..8089cb5 --- /dev/null +++ b/src/graphcoloring/levels/rules/ruleloader.hpp @@ -0,0 +1,53 @@ +//////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2018 Leo Tenenbaum +// This file is part of GraphColoring. +// +// GraphColoring 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 3 of the License, or +// (at your option) any later version. +// +// GraphColoring 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 GraphColoring. If not, see . +//////////////////////////////////////////////////////////////////////////////// + +#ifndef GRAPHCOLORING_LEVELS_RULELOADER_H_ +#define GRAPHCOLORING_LEVELS_RULELOADER_H_ + +#include "pugi/pugixml.hpp" + +#include "graphcoloring/levels/colorloader.hpp" +#include "graphcoloring/graphs/graph.hpp" +#include "boundrule.hpp" +#include "edgerule.hpp" + +namespace graphcoloring { + +class RuleLoader { +public: + static constexpr gui::Color ANY_COLOR = 0x00000000; + RuleLoader(); + virtual ~RuleLoader() {} + void LoadDocument(const pugi::xml_document& document, + const ColorLoader& color_loader); + bool IsValid(const Graph& graph) const; // O(Rules * Edges) + void RenderRules(gui::Window* window) const; +private: + void LoadEdgeRule(pugi::xml_node node, const ColorLoader& color_loader); + void LoadMaximumRule(pugi::xml_node node, const ColorLoader& color_loader); + static constexpr int RULE_COLUMN_WIDTH = 200; + std::vector edge_rules; + std::vector maximum_rules; + bool connected_rule = false; // true if the graph should be connected + std::vector> all_rules; + +}; + +} // namespace graphcoloring + +#endif // GRAPHCOLORING_LEVELS_RULELOADER_H_ diff --git a/src/graphcoloring/levels/rules/rules.cpp b/src/graphcoloring/levels/rules/rules.cpp new file mode 100644 index 0000000..2b9537f --- /dev/null +++ b/src/graphcoloring/levels/rules/rules.cpp @@ -0,0 +1,72 @@ +//////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2018 Leo Tenenbaum +// This file is part of GraphColoring. +// +// GraphColoring 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 3 of the License, or +// (at your option) any later version. +// +// GraphColoring 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 GraphColoring. If not, see . +//////////////////////////////////////////////////////////////////////////////// + +#include "rules.hpp" + +namespace graphcoloring { +namespace rules { + +static gui::Color same_color = ANY_COLOR; + +void ResetSameColor() { same_color = ANY_COLOR; } + +bool IsSameColor(gui::Color color1, gui::Color color2) +{ + if (color1 == ANY_COLOR || color2 == ANY_COLOR) + return true; + + if (same_color == ANY_COLOR) + { + if (color1 == SAME_COLOR && color2 != SAME_COLOR) + { + same_color = color2; + return true; + } + if (color2 == SAME_COLOR && color1 != SAME_COLOR) + { + same_color = color1; + return true; + } + } + if (color1 == SAME_COLOR && color2 == same_color) + return true; + if (color2 == SAME_COLOR && color1 == same_color) + return true; + + return color1 == color2; +} + +gui::Color RenderColor(gui::Color color) +{ + if (color == ANY_COLOR) + return gui::colors::WHITE; + if (color == SAME_COLOR) + return 0x666666FF; + return color; +} + +gui::Color ColorFromAttribute(pugi::xml_attribute attr, + const ColorLoader& color_loader) +{ + if (attr.empty()) return ANY_COLOR; + if (std::string(attr.value()) == "same") return SAME_COLOR; + return attr.empty() ? ANY_COLOR : color_loader.GetColorFromAttribute(attr); +} + +} // namespace rules +} // namespace graphcoloring diff --git a/src/graphcoloring/levels/rules/rules.hpp b/src/graphcoloring/levels/rules/rules.hpp new file mode 100644 index 0000000..2e6d83c --- /dev/null +++ b/src/graphcoloring/levels/rules/rules.hpp @@ -0,0 +1,42 @@ +//////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2018 Leo Tenenbaum +// This file is part of GraphColoring. +// +// GraphColoring 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 3 of the License, or +// (at your option) any later version. +// +// GraphColoring 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 GraphColoring. If not, see . +//////////////////////////////////////////////////////////////////////////////// + + +#ifndef GRAPHCOLORING_LEVELS_RULES_RULES_H_ +#define GRAPHCOLORING_LEVELS_RULES_RULES_H_ + +#include "pugi/pugixml.hpp" +#include "../colorloader.hpp" + +namespace graphcoloring { +namespace rules { + +constexpr gui::Color ANY_COLOR = 0; +constexpr gui::Color SAME_COLOR = 1; // Refers to patterns like same-red-same, which can mean blue-red-blue, red-red-red, etc. +extern void ResetSameColor(); // Forget about "same" color +extern bool IsSameColor(gui::Color color1, gui::Color color2); +extern gui::Color RenderColor(gui::Color color); // Turns ANY_COLOR into white. +extern gui::Color ColorFromAttribute(pugi::xml_attribute attr, + const ColorLoader& color_loader); // ANY_COLOR if attribute is empty. + +} // namespace rules +} // namespace graphcoloring + + + +#endif /* SRC_GRAPHCOLORING_LEVELS_RULES_RULES_HPP_ */ -- cgit v1.2.3