- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我正在为一款游戏编写一些决策 AI,我想出了以下代码。
if(pushedLeft && leftFree && leftExists)
GoLeft();
else if(pushedRight && rightFree && rightExists)
GoRight();
else if(leftFree && leftExists)
GoLeft();
else if(rightFree && rightExists)
GoRight();
else if(pushedLeft && leftExists)
GoLeft();
else if(pushedRight && rightExists)
GoRight();
else if(leftExists)
GoLeft();
else if(rightExists)
GoRight();
// else do nothing...
这是一个相当长的 if
语句流,具有类似的条件!
请注意,它构成了这个漂亮的图案:
L1 L2 L3 -> L
R1 R2 R3 -> R
L2 L3 -> L
R2 R3 -> R
L1 L3 -> L
R1 R3 -> R
L3 -> L
R3 -> R
(nothing) -> 0
这段代码的目的是根据一些传入的状态信息来决定对象应该向左还是向右移动(或者根本不移动)。每条信息都有不同的优先级。我可以将它写在这样的有序列表中:
Highest Priority
----------------
Don't ever move into an invalid space
Prefer to move into an unoccupied space
Prefer to move in the push direction
Prefer to move left
----------------
Lowest Priority
很明显,添加额外的信息输入来做出此决定将使条件的数量增加一倍。并且将这些输入的潜在值数量加倍(例如:允许上/下/左/右)也会使条件数量加倍。 (所以这是 n×m2 条件,对吧?)
所以我的问题是:
是否有一种漂亮、令人满意、优雅的编码方式?
我在想一定有一个很好的“n×m”方式来做到这一点(编辑:我最初在这里有“n+m”,但这似乎是不可能的,因为有 n×m 个输入条件)。适用于我的代码和一般问题的东西?
最好是性能与上述条件版本一样好或更好的东西。理想情况下,避免堆分配的东西 - 对于在游戏开发场景中使用很重要(尽管如有必要,这些总是可以通过缓存等进行优化)。
还有:这个问题是否有任何“Googleable 术语”?我怀疑这不是一个罕见的问题 - 但我不知道它的名字。
更新:一个想法感谢Superpig's answer , 是计算各种选项的分数。像这样:
int nothingScore = 1 << 4;
int leftScore = (1 << 1) + (pushedLeft ? 1 << 2 : 0) + (leftFree ? 1 << 3 : 0) + (leftExists ? 1 << 5 : 0);
int rightScore = (pushedRight ? 1 << 2 : 0) + (rightFree ? 1 << 3 : 0) + (rightExists ? 1 << 5 : 0);
当然有更好的方法来编写评分代码(以及其他评分方法)。然后仍然是计算分数后选择要做什么的问题。当然,可能还有更好的完全不涉及评分的方法。
更新 2: 我有 posted and accepted my own answer here (因为 Superpig 的不是一个完整的解决方案,而且到目前为止,甚至远程都没有其他答案在正确的轨道上)。我没有对各种输出进行评分,而是选择了一种使用位域的选项消除方法。这允许仅使用单个整数进行内存决策。
最佳答案
这本质上是一个分类问题;您想要决策树(或行为树)之类的东西。您正在尝试针对情况(有效性、自由度、插入方向等)获取一堆离散输入,并将结果分类为“上、下、左或右”。
我怀疑,如果您希望 if 语句的长链具有更好或相同的性能 - 至少在指令计数/完成的比较次数方面 - 那么您将必须使您的以你在那里做的方式进行比较。计算所有方向的分数然后检查最大值,或递归地将移动列表划分为首选和非首选等方法最终都会比纯比较序列做更多的工作。
我认为,您可以只构建一个查找表。你有 4 位指示方向是否有效,4 位指示方向是否被占用,2 位指示插入方向,总共 10 位 - 所以有 1024 种不同的情况,每种情况下的行为可以是仅用 2 位(因此,1 字节)进行描述 - 使总表大小为 1024 字节。
单个条目将是这样的结构:
union DecisionSituation
{
unsigned short Index;
struct
{
bool ValidLeft : 1;
bool ValidRight : 1;
bool ValidUp : 1;
bool ValidDown : 1;
bool OccupiedLeft : 1;
bool OccupiedRight : 1;
bool OccupiedUp : 1;
bool OccupiedDown : 1;
Direction PushDirection : 2;
} Flags;
}
您可以通过填写该结构中的标志来描述您的情况,然后读取“索引”值以获得您的查找表索引。
编辑:此外,关于您的评分函数,因为您执行的是严格的位模式,我认为您可以跳过所有三元运算符:
int leftScore = (leftExists << 4) | (leftFree << 3) | (pushedLeft << 2) | 1;
int rightScore = (rightExists << 4) | (rightFree << 3) | (pushedRight << 2) | 0;
// Find the highest scoring direction here
// If none of the scores are at least (1 << 4) it means none of them existed
if(highest score < (1 << 4)) return nothing;
// otherwise just return the highest scoring direction
关于c# - 一种更优雅的编写决策代码的方式来评估具有不同优先级的多个输入?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10968197/
我只想从客户端向服务器发送数组 adc_array=[w, x, y, z]。下面是客户端代码,而我的服务器是在只接受 json 的 python 中。编译代码时我没有收到任何错误,但收到 2 条警告
我是 lua 和 Node js 的新手,我正在尝试将我正在开发的移动应用程序连接到服务器。问题是它连接到服务器,但我尝试传递的数据丢失或无法到达服务器。对我正在做的事情有什么问题有什么想法吗? th
我在这个页面上工作 http://www.haskell.org/haskellwiki/99_questions/Solutions/4 我理解每个函数的含义,看到一个函数可以像这样以多种方式定义,
我目前正在尝试将数据写入 excel 以生成报告。我可以将数据写入 csv 文件,但它不会按照我想要的顺序出现在 excel 中。我需要数据在每列的最佳和最差适应性下打印,而不是全部打印在平均值下。这
所以,我正在做一个项目,现在我有一个问题,所以我想得到你的帮助:) 首先,我已经知道如何编写和读取 .txt 文件,但我想要的不仅仅是 x.hasNext()。 我想知道如何像 .ini 那样编写、读
我正在尝试编写一个函数,该函数将返回作为输入给出的任何数字的阶乘。现在,我的代码绝对是一团糟。请帮忙。 function factorialize(num) { for (var i=num, i
这个问题已经有答案了: Check variable equality against a list of values (16 个回答) 已关闭 4 年前。 有没有一种简洁或更好的方法来编写这个条件
我对 VR 完全陌生,正在 AFrame 中为一个类(class)项目开发 VR 太空射击游戏,并且想知道 AFrame 中是否有 TDD 的任何文档/标准。有人能指出我正确的方向吗? 最佳答案 几乎
我正在尝试创建一个 for 循环,它将重现以下功能代码块,但以一种更具吸引力的方式。这是与 Soundcould 小部件 API 实现一起使用的 here on stackoverflow $(doc
我有一个非常令人困惑的问题。我正在尝试更改属性文件中的属性,但它只是没有更改... 这是代码: package config; import java.io.FileNotFoundException
我对 VR 完全陌生,正在 AFrame 中为一个类(class)项目开发 VR 太空射击游戏,并且想知道 AFrame 中是否有 TDD 的任何文档/标准。有人能指出我正确的方向吗? 最佳答案 几乎
我正在开发一个用户模式(Ring3)代码级调试器。它还应支持.NET可执行文件的本机(x86)调试。基本上,我需要执行以下操作: 1).NET在隐身模式下加载某些模块,而没有LOAD_DLL_DEBU
我有一个列表,我知道有些项目是不必要打印的,我正在尝试通过 if 语句来做到这一点...但是它变得非常复杂,所以有没有什么方法可以在 if 语句中包含多个索引而无需打印重写整个声明。 看起来像这样的东
我很好奇以不同方式编写 if 语句是否会影响程序的速度和效率。所以,例如写一个这样的: bool isActive = true; bool isResponding = false; if (isA
我在搜索网站的源代码时找到了一种以另一种方式(我认为)编写 if 语句的方法。 代替: if(a)b; 或: a?b:''; 我读了: !a||b; 第三种方式和前两种方式一样吗?如果是,为什么我们要
我的数据采用以下格式(HashMap的列表) {TeamName=India, Name=Sachin, Score=170} {TeamName=India, Name=Sehwag, Score=
我目前正在完成 More JOIN operations sqlzoo 的教程,遇到了下面的代码作为#12 的答案: SELECT yr,COUNT(title) FROM movie JOIN ca
我正试图找到一种更好的方法来编写这段代码: def down_up(array, player) 7.downto(3).each do |row| 8.times do |col
出于某种原因,我的缓冲区中充满了乱码,我不确定为什么。我什至用十六进制编辑器检查了我的文件,以验证我的字符是否以 2 字节的 unicode 格式保存。我不确定出了什么问题。 [打开文件] fseek
阅读编码恐怖片时,我刚刚又遇到了 FizzBuzz。 原帖在这里:Coding Horror: Why Can't Programmers.. Program? 对于那些不知道的人:FizzBu
我是一名优秀的程序员,十分优秀!