如何为游戏生成随机算术表达式

时间:2015-01-07 23:45:03

标签: math random expression integer-arithmetic

我想知道你是否可以帮我解决这个问题。我目前在我的代码上使用了很多开关,if-else等,我根本不喜欢它。

我想生成两个随机的算术表达式,其中一个形式类似于下面的那些:

1)号码

例如: 19

2)号码操作号

例如: 22 * 4

3)(编号操作编号)操作编号

例如:(10 * 4)/ 5

4)((编号操作编号)操作编号)操作编号

例如:((25 * 2)/ 10) - 2

在我有2个算术表达式之后,游戏包括匹配它们并确定哪个更大。

我想知道如何随机选择每个算术表达式的数字和运算,以便得到整数结果(不是浮点数),并且两个表达式都具有尽可能接近的结果。个人数字不应高于30。

我的意思是,我不希望结果是1000和其他14因为他们可能太容易发现哪一方更大,所以他们应该像:

expresion 1:((25 + 15)/ 10)* 4(16)

表达式2:((7 * 2)+ 10)/ 8(其为3)

结果(16和3)是整数,足够接近

可行的操作是+, - ,*和/

可以在两个不同形式的情景之间进行匹配,例如

((7 * 2)+ 10)/ 8 和 (18/3)* 2

我非常感谢你能给我的所有帮助。 在此先感谢!!

最好的问候。

1 个答案:

答案 0 :(得分:3)

我认为合理的方法是从总数开始,然后递归构造一个随机expression tree来达到总数。您可以在每个等式中选择所需的运算符数,并确保所有值都是整数。另外,你可以选择你想要两个方程的值的接近程度,如果你愿意,甚至可以使它们相等。我将以上面的表达式1 作为示例。

((25 + 15) / 10) * 4 = 16

我们从总16开始,并将其作为树的根:

   16

要展开节点(叶子),我们选择operator并将其设置为节点的值,并创建包含operands的两个子节点。在这种情况下,我们选择乘法作为运算符。

乘法是唯一一个真正让我们在尝试保持所有操作数整数时遇到麻烦的运算符。我们可以通过在我们的范围[1..30]中构建一个整数除数表来满足这个约束(或者可能更多,我们将在下面看到)。在这种情况下,我们的表格会告诉我们16的除数是{2,4,8}。 (如果我们当前值的除数列表为空,我们可以选择不同的运算符,或者完全不同的叶子。)

我们选择一个随机除数,比如4并将其设置为我们节点的right子节点。左孩子显然是value/right,也是整数。

    *
   / \
  4   4

现在我们需要选择另一个叶子来扩展。我们可以随机选择一片叶子,随机地走树,直到我们到达一片叶子,从我们当前的子节点(left)向上和向右走,直到我们到达一片叶子,或者其他什么。

在这种情况下,我们的选择算法选择扩展左子节点和除法运算符。在除法的情况下,我们为right子项生成随机数(在本例中为10),并将left设置为value*right。 (顺序在这里很重要!乘法不是这样。)

     *
    / \
   ÷    4
  / \
 40 10

这说明了为什么我说除数表可能需要超出我们规定的范围,因为某些中间值可能略大于30.您可以调整代码以避免这种情况,或者确保大值是在达到最终等式之前进一步扩展。

在示例中,我们通过选择最左边的子项以使用加法运算符进行扩展来完成此操作。在这种情况下,我们只需为[1..value-1]子项选择right范围内的随机整数,为value-right选择left

      *
     / \
    ÷    4
   / \
  +  10
 / \
25 15

您可以根据需要重复执行任意数量的操作。要重建最终的等式,您只需执行树的有序遍历。要在示例中加上括号,除了根之外,在遍历期间离开任何内部(运算符)节点时,都要将括号括在整个等式中。