mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +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)) | ||||
| 		return EBuildingState::FORBIDDEN; //forbidden | ||||
|  | ||||
| 	std::function<bool(BuildingID id)> allowedTest; | ||||
| 	std::function<bool(BuildingID id)> possiblyNotBuiltTest; | ||||
| 	auto possiblyNotBuiltTest = [&](BuildingID id) -> bool | ||||
| 	{ | ||||
| 		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)) | ||||
| 		{ | ||||
| @@ -533,12 +535,6 @@ EBuildingState::EBuildingState CGameInfoCallback::canBuildStructure( const CGTow | ||||
| 		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)) | ||||
| 		return EBuildingState::FORBIDDEN; | ||||
|  | ||||
|   | ||||
| @@ -99,74 +99,22 @@ namespace LogicalExpressionDetail | ||||
| 		} | ||||
| 	}; | ||||
|  | ||||
| 	template <typename ContainedClass> | ||||
| 	class SatisfiabilityVisitor; | ||||
|  | ||||
| 	template <typename ContainedClass> | ||||
| 	class FalsifiabilityVisitor; | ||||
|  | ||||
| 	/// Visitor to test whether expression's value can be true | ||||
| 	template <typename ContainedClass> | ||||
| 	class SatisfiabilityVisitor : public boost::static_visitor<bool> | ||||
| 	class PossibilityVisitor : public boost::static_visitor<bool> | ||||
| 	{ | ||||
| 		typedef ExpressionBase<ContainedClass> Base; | ||||
|  | ||||
| 	protected: | ||||
| 		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; | ||||
| 		SatisfiabilityVisitor<ContainedClass> *satisfiabilityVisitor; | ||||
| 		FalsifiabilityVisitor<ContainedClass> *falsifiabilityVisitor; | ||||
|  | ||||
| 		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::apply_visitor(*this, expr); | ||||
| 				return boost::apply_visitor(*falsifiabilityVisitor, expr); | ||||
| 			}); | ||||
| 		} | ||||
|  | ||||
| 	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), | ||||
| 			satisfiabilityVisitor(nullptr) | ||||
| 			satisfiabilityVisitor(nullptr), | ||||
| 			falsifiabilityVisitor(nullptr) | ||||
| 		{} | ||||
|  | ||||
| 		void setFalsifiabilityVisitor(SatisfiabilityVisitor<ContainedClass> *satisfiabilityVisitor) | ||||
| 		void setSatisfiabilityVisitor(SatisfiabilityVisitor<ContainedClass> *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 | ||||
| 		{ | ||||
| 			return countFalsifiable(element.expressions) == element.expressions.size(); | ||||
| 			return this->countSatisfiable(element.expressions) != 0; | ||||
| 		} | ||||
|  | ||||
| 		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 | ||||
| 		{ | ||||
| 			return countSatisfiable(element.expressions) != 0; | ||||
| 			return this->countFalsifiable(element.expressions) == element.expressions.size(); | ||||
| 		} | ||||
|  | ||||
| 		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". | ||||
| 	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::FalsifiabilityVisitor<Value> falsifiabilityVisitor(falsifiabilityTest); | ||||
| 		LogicalExpressionDetail::SatisfiabilityVisitor<Value> satisfiabilityVisitor(satisfiabilityTest, falsifiabilityTest); | ||||
| 		LogicalExpressionDetail::FalsifiabilityVisitor<Value> falsifiabilityVisitor(satisfiabilityTest, falsifiabilityTest); | ||||
|  | ||||
| 		satisfiabilityVisitor.setFalsifiabilityVisitor(&falsifiabilityVisitor); | ||||
| 		falsifiabilityVisitor.setFalsifiabilityVisitor(&satisfiabilityVisitor); | ||||
| 		falsifiabilityVisitor.setSatisfiabilityVisitor(&satisfiabilityVisitor); | ||||
|  | ||||
| 		return boost::apply_visitor(satisfiabilityVisitor, data); | ||||
| 	} | ||||
|   | ||||
		Reference in New Issue
	
	Block a user