Newer
Older
std::regex blockRegex("(?:(?:\\s|\\t)*)Block(?:(?:\\s|\\t)*):(?:(?:\\s|\\t)*)End\\{(.*)\\}(?:(?:\\s|\\t)*)");
for (auto & line : definition)
if (!util::doIfNameMatch(blockRegex, line, [this](auto sm)
{
blocks.emplace_back(util::split(sm.str(1), ' '));
}))
if (blocks.empty())
util::myThrow(fmt::format("invalid line '{}', expeced 'Block : End{}'",line,"{...}"));
blocks.back().addMovement(line);
if (blocks.empty())
util::myThrow("empty strategy");
for (auto & block : blocks)
if (block.empty())
util::myThrow("there is an empty block");
Strategy::Movement Strategy::getMovement(const Config & c, const std::string & transition)
auto movement = blocks[currentBlock].getMovement(c, transition);
currentBlock++;
if (currentBlock >= blocks.size())
return endMovement;
movement.first = blocks[currentBlock].getInitialState();
movement.second = -c.getWordIndex();
Strategy::Movement Strategy::Block::getMovement(const Config & c, const std::string & transition)
std::string transitionPrefix(util::split(transition, ' ')[0]);
auto currentState = c.getState();
auto fromState = std::get<0>(movement);
auto toState = std::get<1>(movement);
auto trans = std::get<2>(movement);
auto mov = std::get<3>(movement);
if (fromState == currentState and (trans == transitionPrefix or trans == "*"))
return std::make_pair(toState, mov);
}
util::myThrow(fmt::format("no movement found for state '{}' and transitionPrefix '{}'", currentState, transitionPrefix));
Strategy::Block::Block(std::vector<std::string> endConditionsStr)
{
for (auto & cond : endConditionsStr)
endConditions.emplace_back(str2condition(cond));
}
void Strategy::Block::addMovement(std::string definition)
{
std::regex regex("(?:(?:\\s|\\t)*)(\\S+)(?:(?:\\s|\\t)+)(\\S+)(?:(?:\\s|\\t)+)(\\S+)(?:(?:\\s|\\t)+)(\\S+)(?:(?:\\s|\\t)*)");
auto errorMessage = fmt::format("invalid definition '{}' expected fromState toState transitionNamePrefix wordIndexMovement", definition);
if (!util::doIfNameMatch(regex, definition, [this, &errorMessage](auto sm)
{
try
{
movements.emplace_back(std::make_tuple(sm.str(1), sm.str(2), sm.str(3), std::stoi(sm.str(4))));
} catch (std::exception & e) {util::myThrow(fmt::format("caught '{}' in {}", e.what(), errorMessage));}
}))
util::myThrow(errorMessage);
}
Strategy::Block::EndCondition Strategy::Block::str2condition(const std::string & s)
{
if (s == "cannotMove")
return EndCondition::CannotMove;
else
util::myThrow(fmt::format("invalid EndCondition '{}'", s));
const std::string Strategy::Block::getInitialState() const
{
return std::get<0>(movements.at(0));
bool Strategy::Block::isFinished(const Config & c, const Movement & movement)
for (auto & condition : endConditions)
if (condition == EndCondition::CannotMove)
{
if (c.canMoveWordIndex(movement.second))
return false;
}
return true;