Newer
Older
Strategy::Strategy(const std::vector<std::string_view> & lines)
{
if (!util::doIfNameMatch(std::regex("Strategy : ((incremental)|(sequential))"), lines[0], [this](auto sm)
{type = sm[1] == "sequential" ? Type::Sequential : Type::Incremental;}))
util::myThrow(fmt::format("Invalid strategy identifier '{}'", lines[0]));
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;
{
key = std::pair<std::string,std::string>(splited[0], "");
value = splited[1];
if (defaultCycle.empty())
initialState = splited[0];
key = std::pair<std::string,std::string>(splited[0], splited[2]);
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));
if (edges.empty())
util::myThrow("Strategy is empty");
defaultCycle.pop_back();
std::reverse(defaultCycle.begin(), defaultCycle.end());
originalDefaultCycle = defaultCycle;
}
std::pair<std::string, int> Strategy::getMovement(const Config & c, const std::string & transition)
std::string transitionPrefix(util::split(transition, ' ')[0]);
if (c.stateIsDone())
isDone[c.getState()] = true;
while (defaultCycle.size() && isDone[defaultCycle.back()])
defaultCycle.pop_back();
if (type == Type::Sequential)
return getMovementSequential(c, transitionPrefix);
return getMovementIncremental(c, transitionPrefix);
}
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;
{
target = foundSpecific->second.first;
movement = foundSpecific->second.second;
}
{
target = foundGeneric->second.first;
movement = foundGeneric->second.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.canMoveWordIndex(movement) ? movement : 0};
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(), ""));
{
target = foundSpecific->second.first;
movement = foundSpecific->second.second;
}
{
target = foundGeneric->second.first;
movement = foundGeneric->second.second;
}
if (target.empty())
util::myThrow(fmt::format("no suitable movement found for current state '{}' and transition '{}'", c.getState(), transition));
return {target, c.canMoveWordIndex(movement) ? movement : 0};
const std::string Strategy::getInitialState() const
{
return initialState;
}
void Strategy::reset()
{
for (auto & it : isDone)
it.second = false;
defaultCycle = originalDefaultCycle;
}