是否有任何种类的“表达式类” (C ++) [英] Is there any kind of "expression class" (C++)

查看:201
本文介绍了是否有任何种类的“表达式类” (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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆