0

Im writing a program that simulates a vacuum cleaning a room. There is an initial state of dirty spots and I want to use various AI algorithms to find the best paths to clean the room. By making the algorithms separate from the actual problem I think my solution will be very modular.

Each algorithm only knows about States. Each state can be expanded to children states. Here is my first algorithm, UniformCost:

#include<iostream>
#include<set>

class State {
public:
    State(){}
    bool operator< (const State& s) const;
    bool isGoal();
    std::set<State> expand();
};


class UniformCost {
private:
    State startState;
    std::set<State> closedList; //list of no repeated states
public:
    State start;
    void setStart(State s);
    State* getSolution();
};

void UniformCost::setStart(State st) {
    start = st;
}

State* UniformCost::getSolution() {
    closedList.insert(start);
    while(!closedList.empty()) {
        State cur = *closedList.begin();
        if(cur.isGoal()) {
            return &cur;
        }
        closedList.erase(cur);
        std::set<State> children = cur.expand();
        for (std::set<State>::iterator i = children.begin(); i != children.end(); ++i) {
            closedList.insert(*i);
        }
    }
}

My main application creates the initial Node that is a child class of State.

class Node : public State {
public:
    std::pair<int,int> loc;
    int g_val;
    std::set<std::pair<int,int> > dirt;
    std::vector<char> path;

    bool isGoal() {
        return dirt.size() == 0;
    }
    bool operator< (const State& s) const {
        Node n = (Node) s;
        if(loc == n.loc) {
            return false;
        }
        if(g_val <= n.g_val) {
            return true;
        }
        return false;
    }
    std::set<State> expand() { 
        std::set<State> ret;
        return ret;
    }
};

How can I override the operator in the Node class that is expecting a "operator< (const State&)"? Or a more general question, how would I handle future "casting" of States?

gotthecodes
  • 273
  • 3
  • 12
  • 2
    Or make it non-meber `friend` and overload it. – Joker_vD Jan 30 '18 at 20:33
  • @TheDude: **dynamic type checking** is an extremely ungood idea in C++. Unfortunately, in this particular case, comments can't be downvoted. In the years up till now I've been happy about that. – Cheers and hth. - Alf Jan 30 '18 at 20:43
  • Thank you both, I am using virtual now. But the operator function is still expecting a "const State &" but the function is determined by fields in the Node class. How can I access the "Node" fields from that "State" being passed? – gotthecodes Jan 30 '18 at 20:43
  • 4
    One simple way is to make your algorithm a template, using compile time polymorphism instead of run-time polymorphism. – Cheers and hth. - Alf Jan 30 '18 at 20:47
  • Adding to @Joker_vD, I'd strongly recommend looking at [the canonical operator overloading answer](https://stackoverflow.com/a/4421719/364696) to understand best practices for each class of operator (in this case, that `operator<` and friends be a non-member that accepts both arguments by `const` reference). With non-member functions, you can just define separate handlers for `Node/Node`, `Node/State`, `State/Node` (likely implemented in terms of `State/Node`), and `State/State` pairings as needed. – ShadowRanger Jan 30 '18 at 21:49
  • Do you need to compare two State objects without knowing their exact dynamic types? If so, what should happen if the types are diffetent? – n. m. could be an AI Jan 30 '18 at 22:19
  • @D.Lamkin `if(g_val <= n.g_val) {return true;}` -- This will fail you miserably if you decided to use this type in an algorithm such as `std::sort`. The usual way `operator <` is described is to use a `strict-weak-ordering`, and letting to equal items result in `true` is a failure of such ordering. – PaulMcKenzie Jan 30 '18 at 22:19
  • Although I don't see this exact code trying it, it looks as though you might intend to put `Node` objects in a `std::set`. This is not possible. Research "object slicing", and if that's going to be a problem, change the sets to something like `std::set>`. – aschepler Jan 30 '18 at 22:43

0 Answers0