Skip to content
Snippets Groups Projects
Commit bfba9c85 authored by Franck Dary's avatar Franck Dary
Browse files

Finished Strategy

parent 9c09bc6c
No related branches found
No related tags found
No related merge requests found
......@@ -93,6 +93,7 @@ class Config
bool hasStack(int relativeIndex) const;
String getState() const;
void setState(const std::string state);
bool stateIsDone() const;
};
......
......@@ -5,6 +5,10 @@
class Strategy
{
public :
static inline std::pair<std::string, int> endMovement{"", 0};
private :
enum Type
......@@ -15,6 +19,13 @@ class Strategy
Type type;
std::map<std::pair<std::string, std::string>, std::string> edges;
std::map<std::string, bool> isDone;
std::vector<std::string> defaultCycle;
private :
std::pair<std::string, int> getMovementSequential(const Config & c, const std::string & transition);
std::pair<std::string, int> getMovementIncremental(const Config & c, const std::string & transition);
public :
......
......@@ -340,3 +340,11 @@ void Config::setState(const std::string state)
this->state = state;
}
bool Config::stateIsDone() const
{
if (!rawInput.empty())
return rawInputOnlySeparatorsLeft();
return !has(0, wordIndex+1, 0);
}
......@@ -9,28 +9,97 @@ Strategy::Strategy(const std::vector<std::string_view> & lines)
for (unsigned int i = 1; i < lines.size(); i++)
{
auto splited = util::split(lines[i], ' ');
std::pair<std::string, std::string> key;
std::string value;
if (splited.size() == 2)
edges[std::pair<std::string,std::string>(splited[0], "")] = splited[1];
{
key = std::pair<std::string,std::string>(splited[0], "");
value = splited[1];
defaultCycle.emplace_back(value);
}
else if (splited.size() == 3)
edges[std::pair<std::string,std::string>(splited[0], splited[1])] = splited[2];
{
key = std::pair<std::string,std::string>(splited[0], splited[1]);
value = splited[1];
}
else
util::myThrow(fmt::format("Invalid strategy line '{}'", lines[i]));
if (edges.count(key))
util::myThrow(fmt::format("Edge {} {} defined twice", key.first, key.second));
edges[key] = value;
isDone[key.first] = false;
}
if (edges.empty())
util::myThrow("Strategy is empty");
defaultCycle.pop_back();
std::reverse(defaultCycle.begin(), defaultCycle.end());
for (auto & s : defaultCycle)
fmt::print("{}\n", s);
}
std::pair<std::string, int> Strategy::getMovement(const Config & c, const std::string & transition)
{
if (c.stateIsDone())
isDone[c.getState()] = true;
while (defaultCycle.size() && isDone[defaultCycle.back()])
defaultCycle.pop_back();
if (type == Type::Sequential)
return getMovementSequential(c, transition);
return getMovementIncremental(c, transition);
}
std::pair<std::string, int> Strategy::getMovementSequential(const Config & c, const std::string & transition)
{
auto foundSpecific = edges.find(std::make_pair(c.getState(), transition));
auto foundGeneric = edges.find(std::make_pair(c.getState(), ""));
std::string target;
if (foundSpecific != edges.end())
target = foundSpecific->second;
else if (foundGeneric != edges.end())
target = foundGeneric->second;
if (target.empty())
util::myThrow(fmt::format("no suitable movement found for current state '{}' and transition '{}'", c.getState(), transition));
if (!c.stateIsDone())
return {c.getState(), (c.getState() == target) && edges.size() > 1 ? 0 : 1};
if (!isDone[target])
return {target, -c.getWordIndex()};
return endMovement;
}
std::pair<std::string, int> Strategy::getMovementIncremental(const Config & c, const std::string & transition)
{
auto foundSpecific = edges.find(std::make_pair(c.getState(), transition));
auto foundGeneric = edges.find(std::make_pair(c.getState(), ""));
std::string target;
if (foundSpecific != edges.end())
return {foundSpecific->second, 1};
target = foundSpecific->second;
else if (foundGeneric != edges.end())
target = foundGeneric->second;
if (target.empty())
util::myThrow(fmt::format("no suitable movement found for current state '{}' and transition '{}'", c.getState(), transition));
if (foundGeneric != edges.end())
return {foundGeneric->second, 1};
if (!isDone[target])
return {target, target == defaultCycle.back() ? 1 : 0};
util::myThrow(fmt::format("no suitable movement found for current state '{}' and transition '{}'", c.getState(), transition));
if (defaultCycle.empty())
return endMovement;
return {"", 0};
return {defaultCycle.back(), 1};
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment