mirror of
https://github.com/vcmi/vcmi.git
synced 2025-08-13 19:54:17 +02:00
Extract PossibilityVisitor
This commit is contained in:
@@ -520,10 +520,12 @@ EBuildingState::EBuildingState CGameInfoCallback::canBuildStructure( const CGTow
|
|||||||
if(vstd::contains(t->forbiddenBuildings, ID))
|
if(vstd::contains(t->forbiddenBuildings, ID))
|
||||||
return EBuildingState::FORBIDDEN; //forbidden
|
return EBuildingState::FORBIDDEN; //forbidden
|
||||||
|
|
||||||
std::function<bool(BuildingID id)> allowedTest;
|
auto possiblyNotBuiltTest = [&](BuildingID id) -> bool
|
||||||
std::function<bool(BuildingID id)> possiblyNotBuiltTest;
|
{
|
||||||
|
return ((id == BuildingID::CAPITOL) ? true : !t->hasBuilt(id));
|
||||||
|
};
|
||||||
|
|
||||||
allowedTest = [&](BuildingID id) -> bool
|
std::function<bool(BuildingID id)> allowedTest = [&](BuildingID id) -> bool
|
||||||
{
|
{
|
||||||
if (vstd::contains(t->forbiddenBuildings, id))
|
if (vstd::contains(t->forbiddenBuildings, id))
|
||||||
{
|
{
|
||||||
@@ -533,12 +535,6 @@ EBuildingState::EBuildingState CGameInfoCallback::canBuildStructure( const CGTow
|
|||||||
return t->genBuildingRequirements(id, true).satisfiable(allowedTest, possiblyNotBuiltTest);
|
return t->genBuildingRequirements(id, true).satisfiable(allowedTest, possiblyNotBuiltTest);
|
||||||
};
|
};
|
||||||
|
|
||||||
possiblyNotBuiltTest = [&](BuildingID id) -> bool
|
|
||||||
{
|
|
||||||
//TODO consider destroing
|
|
||||||
return !t->hasBuilt(id);
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!t->genBuildingRequirements(ID, true).satisfiable(allowedTest, possiblyNotBuiltTest))
|
if (!t->genBuildingRequirements(ID, true).satisfiable(allowedTest, possiblyNotBuiltTest))
|
||||||
return EBuildingState::FORBIDDEN;
|
return EBuildingState::FORBIDDEN;
|
||||||
|
|
||||||
|
@@ -99,74 +99,22 @@ namespace LogicalExpressionDetail
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename ContainedClass>
|
||||||
|
class SatisfiabilityVisitor;
|
||||||
|
|
||||||
template <typename ContainedClass>
|
template <typename ContainedClass>
|
||||||
class FalsifiabilityVisitor;
|
class FalsifiabilityVisitor;
|
||||||
|
|
||||||
/// Visitor to test whether expression's value can be true
|
|
||||||
template <typename ContainedClass>
|
template <typename ContainedClass>
|
||||||
class SatisfiabilityVisitor : public boost::static_visitor<bool>
|
class PossibilityVisitor : public boost::static_visitor<bool>
|
||||||
{
|
{
|
||||||
typedef ExpressionBase<ContainedClass> Base;
|
typedef ExpressionBase<ContainedClass> Base;
|
||||||
|
|
||||||
|
protected:
|
||||||
std::function<bool(const typename Base::Value &)> satisfiabilityTest;
|
std::function<bool(const typename Base::Value &)> satisfiabilityTest;
|
||||||
FalsifiabilityVisitor<ContainedClass> *falsifiabilityVisitor;
|
|
||||||
|
|
||||||
size_t countSatisfiable(const std::vector<typename Base::Variant> & element) const
|
|
||||||
{
|
|
||||||
return boost::range::count_if(element, [&](const typename Base::Variant & expr)
|
|
||||||
{
|
|
||||||
return boost::apply_visitor(*this, expr);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t countFalsifiable(const std::vector<typename Base::Variant> & element) const
|
|
||||||
{
|
|
||||||
return boost::range::count_if(element, [&](const typename Base::Variant & expr)
|
|
||||||
{
|
|
||||||
return boost::apply_visitor(*falsifiabilityVisitor, expr);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
SatisfiabilityVisitor(std::function<bool (const typename Base::Value &)> satisfiabilityTest):
|
|
||||||
satisfiabilityTest(satisfiabilityTest),
|
|
||||||
falsifiabilityVisitor(nullptr)
|
|
||||||
{}
|
|
||||||
|
|
||||||
void setFalsifiabilityVisitor(FalsifiabilityVisitor<ContainedClass> *falsifiabilityVisitor)
|
|
||||||
{
|
|
||||||
this->falsifiabilityVisitor = falsifiabilityVisitor;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator()(const typename Base::OperatorAny & element) const
|
|
||||||
{
|
|
||||||
return countSatisfiable(element.expressions) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator()(const typename Base::OperatorAll & element) const
|
|
||||||
{
|
|
||||||
return countSatisfiable(element.expressions) == element.expressions.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator()(const typename Base::OperatorNone & element) const
|
|
||||||
{
|
|
||||||
return countFalsifiable(element.expressions) == element.expressions.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator()(const typename Base::Value & element) const
|
|
||||||
{
|
|
||||||
return satisfiabilityTest(element);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Visitor to test whether expression's value can be false
|
|
||||||
template <typename ContainedClass>
|
|
||||||
class FalsifiabilityVisitor : public boost::static_visitor<bool>
|
|
||||||
{
|
|
||||||
typedef ExpressionBase<ContainedClass> Base;
|
|
||||||
|
|
||||||
std::function<bool(const typename Base::Value &)> falsifiabilityTest;
|
std::function<bool(const typename Base::Value &)> falsifiabilityTest;
|
||||||
SatisfiabilityVisitor<ContainedClass> *satisfiabilityVisitor;
|
SatisfiabilityVisitor<ContainedClass> *satisfiabilityVisitor;
|
||||||
|
FalsifiabilityVisitor<ContainedClass> *falsifiabilityVisitor;
|
||||||
|
|
||||||
size_t countSatisfiable(const std::vector<typename Base::Variant> & element) const
|
size_t countSatisfiable(const std::vector<typename Base::Variant> & element) const
|
||||||
{
|
{
|
||||||
@@ -180,39 +128,97 @@ namespace LogicalExpressionDetail
|
|||||||
{
|
{
|
||||||
return boost::range::count_if(element, [&](const typename Base::Variant & expr)
|
return boost::range::count_if(element, [&](const typename Base::Variant & expr)
|
||||||
{
|
{
|
||||||
return boost::apply_visitor(*this, expr);
|
return boost::apply_visitor(*falsifiabilityVisitor, expr);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FalsifiabilityVisitor(std::function<bool (const typename Base::Value &)> falsifiabilityTest):
|
PossibilityVisitor(std::function<bool (const typename Base::Value &)> satisfiabilityTest,
|
||||||
|
std::function<bool (const typename Base::Value &)> falsifiabilityTest):
|
||||||
|
satisfiabilityTest(satisfiabilityTest),
|
||||||
falsifiabilityTest(falsifiabilityTest),
|
falsifiabilityTest(falsifiabilityTest),
|
||||||
satisfiabilityVisitor(nullptr)
|
satisfiabilityVisitor(nullptr),
|
||||||
|
falsifiabilityVisitor(nullptr)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void setFalsifiabilityVisitor(SatisfiabilityVisitor<ContainedClass> *satisfiabilityVisitor)
|
void setSatisfiabilityVisitor(SatisfiabilityVisitor<ContainedClass> *satisfiabilityVisitor)
|
||||||
{
|
{
|
||||||
this->satisfiabilityVisitor = satisfiabilityVisitor;
|
this->satisfiabilityVisitor = satisfiabilityVisitor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setFalsifiabilityVisitor(FalsifiabilityVisitor<ContainedClass> *falsifiabilityVisitor)
|
||||||
|
{
|
||||||
|
this->falsifiabilityVisitor = falsifiabilityVisitor;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Visitor to test whether expression's value can be true
|
||||||
|
template <typename ContainedClass>
|
||||||
|
class SatisfiabilityVisitor : public PossibilityVisitor<ContainedClass>
|
||||||
|
{
|
||||||
|
typedef ExpressionBase<ContainedClass> Base;
|
||||||
|
|
||||||
|
public:
|
||||||
|
SatisfiabilityVisitor(std::function<bool (const typename Base::Value &)> satisfiabilityTest,
|
||||||
|
std::function<bool (const typename Base::Value &)> falsifiabilityTest):
|
||||||
|
PossibilityVisitor<ContainedClass>(satisfiabilityTest, falsifiabilityTest)
|
||||||
|
{
|
||||||
|
this->setSatisfiabilityVisitor(this);
|
||||||
|
}
|
||||||
|
|
||||||
bool operator()(const typename Base::OperatorAny & element) const
|
bool operator()(const typename Base::OperatorAny & element) const
|
||||||
{
|
{
|
||||||
return countFalsifiable(element.expressions) == element.expressions.size();
|
return this->countSatisfiable(element.expressions) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator()(const typename Base::OperatorAll & element) const
|
bool operator()(const typename Base::OperatorAll & element) const
|
||||||
{
|
{
|
||||||
return countFalsifiable(element.expressions) != 0;
|
return this->countSatisfiable(element.expressions) == element.expressions.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator()(const typename Base::OperatorNone & element) const
|
bool operator()(const typename Base::OperatorNone & element) const
|
||||||
{
|
{
|
||||||
return countSatisfiable(element.expressions) != 0;
|
return this->countFalsifiable(element.expressions) == element.expressions.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator()(const typename Base::Value & element) const
|
bool operator()(const typename Base::Value & element) const
|
||||||
{
|
{
|
||||||
return falsifiabilityTest(element);
|
return this->satisfiabilityTest(element);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Visitor to test whether expression's value can be false
|
||||||
|
template <typename ContainedClass>
|
||||||
|
class FalsifiabilityVisitor : public PossibilityVisitor<ContainedClass>
|
||||||
|
{
|
||||||
|
typedef ExpressionBase<ContainedClass> Base;
|
||||||
|
|
||||||
|
public:
|
||||||
|
FalsifiabilityVisitor(std::function<bool (const typename Base::Value &)> satisfiabilityTest,
|
||||||
|
std::function<bool (const typename Base::Value &)> falsifiabilityTest):
|
||||||
|
PossibilityVisitor<ContainedClass>(satisfiabilityTest, falsifiabilityTest)
|
||||||
|
{
|
||||||
|
this->setFalsifiabilityVisitor(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator()(const typename Base::OperatorAny & element) const
|
||||||
|
{
|
||||||
|
return this->countFalsifiable(element.expressions) == element.expressions.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator()(const typename Base::OperatorAll & element) const
|
||||||
|
{
|
||||||
|
return this->countFalsifiable(element.expressions) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator()(const typename Base::OperatorNone & element) const
|
||||||
|
{
|
||||||
|
return this->countSatisfiable(element.expressions) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator()(const typename Base::Value & element) const
|
||||||
|
{
|
||||||
|
return this->falsifiabilityTest(element);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -554,13 +560,13 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// calculates if expression can evaluate to "true".
|
/// calculates if expression can evaluate to "true".
|
||||||
bool satisfiable (std::function<bool(const Value &)> satisfiabilityTest, std::function<bool(const Value &)> falsifiabilityTest) const
|
bool satisfiable(std::function<bool(const Value &)> satisfiabilityTest, std::function<bool(const Value &)> falsifiabilityTest) const
|
||||||
{
|
{
|
||||||
LogicalExpressionDetail::SatisfiabilityVisitor<Value> satisfiabilityVisitor(satisfiabilityTest);
|
LogicalExpressionDetail::SatisfiabilityVisitor<Value> satisfiabilityVisitor(satisfiabilityTest, falsifiabilityTest);
|
||||||
LogicalExpressionDetail::FalsifiabilityVisitor<Value> falsifiabilityVisitor(falsifiabilityTest);
|
LogicalExpressionDetail::FalsifiabilityVisitor<Value> falsifiabilityVisitor(satisfiabilityTest, falsifiabilityTest);
|
||||||
|
|
||||||
satisfiabilityVisitor.setFalsifiabilityVisitor(&falsifiabilityVisitor);
|
satisfiabilityVisitor.setFalsifiabilityVisitor(&falsifiabilityVisitor);
|
||||||
falsifiabilityVisitor.setFalsifiabilityVisitor(&satisfiabilityVisitor);
|
falsifiabilityVisitor.setSatisfiabilityVisitor(&satisfiabilityVisitor);
|
||||||
|
|
||||||
return boost::apply_visitor(satisfiabilityVisitor, data);
|
return boost::apply_visitor(satisfiabilityVisitor, data);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user