3

我正在编写一款游戏,玩家在 JVM 上编写相互竞争的 AI 代理。现在架构看起来是这样的:

  1. 处理物理模拟的核心服务器模块,并从玩家那里获取消息作为输入以改变世界。核心还根据各种规则(想想战争迷雾)从每个玩家的角度确定世界的样子。
  2. 播放器模块从核心接收世界的更新版本,对其进行处理,并基于该处理将消息作为输入流式传输到核心。

这个想法是核心与两个播放器模块一起编译,然后运行模拟,产生一个输出流,可以回放以生成比赛的可视化。

我的问题是,如果每个玩家都在一个 Java 线程上运行,是否有可能确保两个玩家线程获得等量的资源(我认为主要是 CPU 时间)?因为我无法控制每个 AI 正在执行的处理的性质,所以其中一个玩家可能效率极低,但编写方式使其线程消耗了如此多的资源,而另一个玩家的 AI 资源匮乏并且可以不公平竞争。

我觉得如果没有硬实时操作系统,这是不可能的,JVM 甚至还没有接近,但如果有一种方法可以相当接近,我很想探索它。

4

3 回答 3

3

“播放器模块从核心接收世界的更新版本,对其进行处理,并将消息作为基于该处理的输入流传输到核心”。这意味着播放器模块内部有一个循环,它接收更新消息并将结果消息发送到核心。然后我会使用轻量级的actor模型,每个玩家都是一个actor,所有的actor都使用同一个ExecutorService。由于被激活的参与者通过相同的执行任务队列,他们获得了大致相同的 CPU 访问权限。

于 2013-01-15T07:04:52.743 回答
1

您的直觉是正确的,这在 Java 中是不可能的。即使你有一个实时操作系统,仍然有人可以编写一个资源密集型的 AI 线程。

您可以采取几种方法至少在这里有所帮助。首先确保给两个播放器模块线程相同的优先级。如果你在一台有 2 个以上处理器的机器上运行,并且你将每个播放器模块线程设置为具有最高优先级,那么理论上它们都应该在有事可做时都运行。但是,如果没有什么可以阻止播放器模块自己生成新线程,那么您不能保证播放器不会这样做。

所以简短的回答是否定的,你不能在 java 中做出这些保证。

根据您的模拟工作方式,也许您可​​以拥有“转弯”的概念。所以模拟指示玩家 1 移动,然后玩家 2 移动,来回移动,因此他们每个人一次只能移动一个“移动”。不过,不确定这是否适用于您的情况。

于 2013-01-15T04:56:21.997 回答
0

如果您有任何关于线程必须做多少工作的旋钮(或只是设置它们的优先级),您可以设置另一个线程,使用ThreadMXBeans 定期监视线程并使用ThreadInfo.getThreadCpuTime. 然后,您可以比较每个玩家的 CPU 时间并做出相应的反应。
不确定这对您来说是否足够及时和准确,但随着时间的推移,您可以平衡 CPU 使用率。
但是,将工作拆分为数据包并使用之前建议的 Executor 应该是更好的方法,并且更像 java。

于 2013-01-15T11:40:54.100 回答