是否有任何种类的“表达式类” (C ++) [英] Is there any kind of "expression class" (C++)
问题描述
我创建一个游戏,让玩家输入输入,改变一些状态,然后检查一个目标值是否为真(明显这个描述被大大简化),我想能够有这个目标值如果玩家生命低于某个值,如果剩余的敌人的数量等于零,任何东西。是否有任何表达式类可以容纳一个简单的value1 compare-operator value2并检查?即:
表达式目标(x = 4);
如果没有,是否有任何建议如何开发一个表达式类?
编辑:另一个(更倾向于我想要实现的)示例:
game.init(){expression goal = FileRead(goalfile); }
game.checkstate(){if(goal)exit(1); } // exit 1是游戏胜利状态
//另一个更具体的例子:
class level1 {public:expression goal(total_enemies == 0); };
class level2 {public:expression goal(player.x == goal.x&& player.y == goal.y); };
动态表达式 p>
如果你想从用户那里接收一个字符串并从中构建一个表达式,也许 C ++数学表达式库适合您的帐单?
template< typename T&
void trig_function()
{
std :: string expression_string =clamp(-1.0,sin(2 * pi * x)+ cos(x / 2 * pi),+ 1.0) ;
T x;
exprtk :: symbol_table< T> symbol_table;
symbol_table.add_variable(x,x);
symbol_table.add_constants();
exprtk :: expression< T>表达;
expression.register_symbol_table(symbol_table);
exprtk :: parser< T>解析器
parser.compile(expression_string,expression);
for(x = T(-5.0); x <= T(+5.0); x + = 0.001)
{
T y = expression.value ;
printf(%19.15f \t%19.15f \\\
,x,y);
}
}
也有嵌入脚本语言的可能性,例如作为 Lua 或 Python ,这将给你(甚至)更多的权力。
如果你使用的是 Qt ,您可以使用 QtScript (Javascript-ish)运行从QObject派生对象读取(静态或动态)属性的表达式。
使用上面的一个可以让你不必编写自己的解析器,AST和赋值器,然而对于一小组操作符,如果你使用 Boost.Spirit 或其他一些体面的解析库。
静态表达式
要在一组预定义表达式之间进行选择(即在编译时已知),应将表达式存储在多态函数对象中。
对于C ++ 11,如果可以使用,请使用 std :: function
和lambda表达式。
std :: function< bool(int,int)> expr = [](int a,int b){a * 2< b};
对于早期的编译器,我建议在 Boost (boost::)或C ++ 0x TR1(std::),具体取决于您的编译器。此外,Boost.Lambda将在这里有帮助,因为它允许您构建和存储表达式以供以后评估。但是,如果你不熟悉C ++和模板(或函数式编程),它可能会吓得你有点。
这样你可以写
使用命名空间boost :: lambda;
boost :: function< bool(int,int)> myexpr1 =(_1 + _2)> 20;
boost :: function< bool(int,int)> myexpr2 =(_1 * _2)> 42;
std :: cout<< myexpr1(4,7)< < myexpr2(2,5);
使用bind,它如下所示:
boost :: function< bool(Player&)> check = bind(& Player :: getHealth,_1)> 20;
玩家p1;
if(check(p1)){dostuff(); }
check = bind(& Player :: getGold,_1)< 42;
if(check(p1)){doOtherStuff(); }
I am creating a game that lets the player enter input, changes some states, then checks if a "goal value" is true (obviously this description is muchly simplified), and I want to be able to have that goal value be anything from if the players life is below a certain value to if the amount of enemies remaining is equal to zero. Is there any "expression class" that can hold a simple "value1 compare-operator value2" and check it? ie:
expression goal(x = 4);
if not, does anybody have any suggestions as to how I could develop an expression class?
EDIT: another (more towards what I am trying to achieve) example:
game.init(){ expression goal = FileRead(goalfile); }
game.checkstate(){ if(goal) exit(1); } //exit 1 is the games win state
//another more specific eg.:
class level1 { public: expression goal(total_enemies == 0); };
class level2 { public: expression goal(player.x == goal.x && player.y == goal.y); };
Dynamic expressions
If you want to receive a string from the user and built an expression from that, maybe the C++ Mathematical Expression Library fits your bill?
template<typename T>
void trig_function()
{
std::string expression_string = "clamp(-1.0,sin(2 * pi * x) + cos(x / 2 * pi),+1.0)";
T x;
exprtk::symbol_table<T> symbol_table;
symbol_table.add_variable("x",x);
symbol_table.add_constants();
exprtk::expression<T> expression;
expression.register_symbol_table(symbol_table);
exprtk::parser<T> parser;
parser.compile(expression_string,expression);
for (x = T(-5.0); x <= T(+5.0); x += 0.001)
{
T y = expression.value();
printf("%19.15f\t%19.15f\n",x,y);
}
}
There are also the possibility embed a scripting language, such as Lua or Python, which will give you (even) more power. This is something to consider if you're writing a game, since you'll likely want to script large parts of it.
If you're using Qt, you can use QtScript (Javascript-ish) to run expressions that read (static or dynamic) properties from your QObject-derived objects.
Using one of the above keeps you from having to write your own parser, AST and evaluator, however for a small set of operators it shouldn't be too hard to hack together something if you use Boost.Spirit or some other decent parsing library.
Static expressions
For selecting between a set of predefined expressions (i.e. known at compile time), you should store the expression in a polymorphic function object.
For C++11, if that's available to you, use std::function
and lambda expressions.
std::function<bool (int, int)> expr = [](int a, int b) { a*2 < b };
For earlier compilers, I recommend function and bind, either in Boost (boost::) or C++0x TR1 (std::), depending on your compiler. Also, Boost.Lambda will be of help here, as it allows you to construct and store expressions for later evaluation. However, if you're not familiar with C++ and templates (or functional programming), it will likely scare you quite a bit.
With that you could write
using namespace boost::lambda;
boost::function<bool (int, int)> myexpr1 = (_1 + _2) > 20;
boost::function<bool (int, int)> myexpr2 = (_1 * _2) > 42;
std::cout << myexpr1(4,7) << " " << myexpr2(2,5);
with bind, it'd look like:
boost::function<bool (Player&)> check = bind(&Player::getHealth, _1) > 20;
Player p1;
if (check(p1)) { dostuff(); }
check = bind(&Player::getGold, _1) < 42;
if (check(p1)) { doOtherStuff(); }
这篇关于是否有任何种类的“表达式类” (C ++)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!