问题标签 [game-ai]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c# - AI中枚举器的替代方案
我正在开发一个多人游戏的服务器,该游戏必须控制数千个在世界各地运行的生物。每个生物都有一个带有心跳方法的 AI,如果玩家在附近,每隔几毫秒/秒就会调用一次,这样他们就可以做出反应。
目前,人工智能使用枚举器作为“例程”,例如
它们从“状态方法”中调用,这些方法在 foreachs 中调用,在心跳中产生,因此您在每个滴答声中都回到同一个位置。
自然也必须在循环中调用例程,因为否则它们不会执行。但由于我不是编写这些 AI 的人,而是不一定是程序员的新手,所以我在服务器启动之前预编译 AI(简单的 .cs 文件)。这给了我这样的 AI 脚本:
替换Do
为迭代例程调用的 foreach 。
我真的很喜欢这种设计,因为 AI 易于理解,但功能强大。这不是简单的状态,但也不难理解/编写行为树。
现在到我实际的“问题”,我不喜欢Do
包装器,我不喜欢预编译我的脚本。但是我想不出没有循环的任何其他方法来实现它,由于冗长和要编写这些脚本的人的技能水平,我想隐藏它。
我希望有一种方法可以在没有显式循环的情况下调用例程,但这是不可能的,因为我必须从 state 方法中让步。
而且我不能使用 async/await,因为它不符合我所依赖的 tick 设计(AI 可能非常复杂,老实说,我不知道如何使用 async 来实现它)。另外,我只是交易Do()
,await
并没有太大的改进。
所以我的问题是:谁能想到摆脱那个循环包装器的方法?我愿意使用其他可以用作脚本的.NET语言(在服务器启动时编译它们),如果有一种以某种方式支持它的话。
java - 转向行为:到达行为问题
我正在努力在我的一个 OpenGL Android 项目中实现转向行为,但我在理解为什么我的 Arrive 行为代码的行为不正常时遇到了一些麻烦。
在更新循环期间,我的程序计算一个转向力来更新移动代理的位置。目前,它的行为与“Seek”行为相同,因为它会移动到 Targetpos 中定义的位置,但它不会在接近应有的点时减速和停止,而是继续向前移动并一遍又一遍地越过目标再次。
对此的任何帮助将不胜感激,下面是应该为代理返回正确转向力的代码。
减速只是一个 1-3 的枚举,编码代理应该减速的不同速率。
c++ - 让我的敌人靠近我的玩家 C++
我正试图让我Enemy
移动到我的Player
.
我知道的事情:
- 球员的位置
- 敌人的位置
- 敌人的速度
我需要做的事情:
- 知道玩家的方向,让敌人移动
所以我认为我需要做的是根据玩家的位置“标准化”敌人的位置,这样我就知道该去哪里,并且两者都有一个基于Vector2f
.
这是我在敌人中的代码:
错误是:
我究竟做错了什么?
2d - 如何在没有昂贵的跳跃模拟的情况下在 2D 平台游戏中生成航点地图?
我正在开发一款游戏(使用 Game Maker:Studio Professional v1.99.355),它需要同时具有用户可修改的关卡几何和基于平台物理的 AI 寻路。因此,我需要一种方法来动态确定可以从哪些其他平台访问哪些平台,以便构建可以提供给 A* 的节点图。
我目前的方法或多或少是这样的:
对于每个平台,请考虑关卡中的其他平台。
对于这些平台中的每一个,如果它明显无法到达(例如,由于高于最大跳跃高度),则不要形成链接并移动到下一个平台。
如果链接似乎可行,则在起始平台上放置一个 ai_character 实例并(在当前步骤事件中)模拟跳跃尝试。
3.a 对起始平台上每个可能的起始位置重复此跳跃尝试。
如果此尝试成功,请记录实时复制所需的数据并转移到下一个平台。
如果没有,请不要形成链接。
对所有平台重复。
这种方法或多或少有效,并产生了一个链接结构,当可视化时看起来像这样:
链接平台(超链接,因为没有代表。)
在此示例中,右下角大部分隐藏的粉红色幽灵正试图到达黑白框。浅蓝色矩形只是用来突出识别平台所在的位置,实际平台是灰色框的行。链接线在起点处为绿色,在目的地处为红色。
这种方法的一个巨大而明显的问题是,对于只有 17 个平台的级别(如上所示),生成节点图需要一秒钟的时间。原因很明显,屏幕中心的黄色文本向我们展示了构建图形需要多长时间:超过 24,000(!)个模拟帧,每个帧都伴随着对每个块的碰撞检查 - 我实际上只是运行角色的 step 事件在一个 while 循环中,因此它通常会在一个框架中处理平台游戏移动的所有操作现在执行 24,000 次。
这显然是不可接受的。如果它仅在 17 个平台上扩展得如此糟糕,那么我需要支持的数百个平台将是一个笑话。哎呀,以这个几何时间成本可能需要数年时间。
为了加快速度,我专注于另一个重要的调试数字,测试计数器:239。如果我只是尝试了起始平台和目标平台的所有可能组合,我将需要运行 17 * 16 = 272 次测试。通过找出各种方法来预测跳跃是否不可能,我设法将运行的昂贵测试的数量减少了高达 33 次(12%!)。然而,我添加到代码中的异常和特殊情况越多,我就越确信实际问题出在跳跃模拟代码中,这让我终于想到了我的问题:
你如何确定一个角色是否有可能从一个平台跳到另一个平台,并且最好不需要模拟整个跳跃?
我的特定平台物理:
跳跃的高度是固定的,除非你碰到天花板。
水平运动没有加速度或惯性。
允许水平空气控制。
更多信息:我找到了这个视频,它描述了一个类似的问题,但没有提供一个好的解决方案。这实际上是我找到的唯一资源。
c++ - 存储玩家上交 Zobrist 哈希
我目前正在中国跳棋极小极大算法中实现转置表。在中国跳棋中,没有棋子被捕获,棋盘在功能上是 81 个空格。玩家轮流在棋盘上移动棋子。
该过程的一部分涉及为棋盘状态创建哈希。到目前为止,我已经有了一个可以为每个棋盘状态创建(希望)唯一哈希的有效方法:
更重要的是,我在 applyMove 函数(和 undoMove 函数)中逐步执行此操作:
这是因为 XOR 函数的可逆性。
我现在遇到的问题是哈希函数不存储轮到谁了。也就是说,你可以有两个相同的游戏板,但它们会在 minimax 算法中返回不同的值,因为一个试图最大化分数,另一个试图最小化它。
基本上,我的问题是:如何将玩家的回合存储在增量生成的散列函数中,同时保持完美反转它的能力(最好是便宜)?假设玩家的回合是整数而不是布尔值,因为游戏最终将有 6 名玩家而不是 2 名玩家。
artificial-intelligence - 游戏中的 Q-learning 没有按预期工作
我试图在我编写的一个简单游戏中实现 Q-learning。该游戏基于玩家必须“跳跃”以避免迎面而来的盒子。
我设计了具有两个动作的系统;jump
和do_nothing
状态是与下一个块的距离(划分和地板以确保没有大量状态)。
我的问题似乎是我的算法实现没有考虑“未来的奖励”,所以它最终跳错了时间。
这是我对 Q-learning 算法的实现;
以下是它使用的一些属性:
我必须使用 lastAction/lastDistance 来计算 Q,因为我不能使用当前数据(将作用于之前帧中执行的操作)。
think
在完成所有渲染和游戏内容(物理、控件、死亡等)后,每帧调用一次该方法。
artificial-intelligence - 如何理解转向行为的转向力
我阅读了有关如何实现转向行为的 Seek 行为的教程。链接在这里 。这是说明算法的图表:
.
我知道速度、力、加速度都是矢量。但是,公式“steering = desired_velocity - current_velocity”中的“steering”如何变成本文中的力而不是速度?为什么这有意义?这是否意味着我们可以将它们混合在一个计算中?这是否意味着一个速度矢量加上或减去另一个速度矢量可以产生一个力矢量?如果不是,为什么结果被称为“力”?我知道转向行为如何在人工智能中发挥作用。实现这一点的关键是我们可以将所有不同的转向力相加在一起,得到一个结果总力。这个总力可以用公式“a = F/m”来得到加速度。之后,我们可以使用这个加速度来计算游戏循环更新中物体的新位置和速度。根据我的看法,
c# - 敌人出现在玩家机会 1 对 5 后面
我写了一个脚本,让敌人出现在玩家身后,每 3 分钟有 1 次机会,我已经将 1 次 5 机会更改为 1 次机会以进行测试,但我不确定是否有用。
我知道如何将敌人置于玩家身后,但没有 1 对 5 的机会。
我已经用 1 到 5 之间的随机数进行了尝试。如果随机数等于 1,他必须生成敌人,否则不会。
这是代码:
c# - 实现和使用 MinMax 与四排 (connect4) 游戏
我正在尝试为连续四个(或 connect4 或连接四个)游戏实现 MinMax 算法。
我想我明白了,它应该建立一个有一定深度的可能板树,评估它们并返回它们的分数,然后我们只取这些分数的最大值。
因此,aiChooseCol()
通过调用检查每个可能列的分数MinMax()
并返回具有最高分数的列。
现在我不确定,这是正确的打电话方式MinMax()
吗?
检查是否正确temp = Math.Max(temp, 1000);
?
我还没有制作启发式函数,但这至少应该识别一个获胜的列并选择它,但目前它只是选择左边的第一个空闲列......我不知道我做错了什么。
一些注意事项:
FillSignInBoardAccordingToCol()
如果成功则返回布尔值。
该board
类型有一个char[,]
包含实际棋盘和玩家标志的数组。
此代码在 AI Player 类中。
lisp - 用 lisp 实现的井字游戏正在完成游戏而不是单步走
我正在制作一个简单的 CLI tic-tac-toe 游戏,其 AI 使用 Negamax 算法和 LISP 进行 alpha-beta 修剪,我对 AI 如何移动有疑问。它没有做出应有的单步棋,而是完全进行游戏,因此游戏仅持续两步。我已经通过(步骤)运行它,看起来问题是在 negamax 函数的(when(> value bestValue))块中设置了 bestPath 变量,即使它说该块没有被执行为。此外,它设置的值不是正确的值,如果它适合设置它的话。有什么建议么?这是我的代码。
这是AI的代码。