因此,我正在自学各种AI技术,我想最好的方法是创建自己的Python机器人,该机器人可以使用在线开源Pokemon模拟器玩Pokemon游戏。
问题是该模拟器的所有源代码都是用JavaScript编写的,而我的机器人则使用Python。最初,我通过下载服务器的.js文件解决了获取有效Pokemon完整列表的问题,该文件(方便地)包含所有有效Pokemon /动作作为JSON对象,可以轻松导入到Python中。当我只需要Pokemon名称之类的时候,这一切都很好,但是现在,我在构建实际的引擎时,我发现它使用相同的JSON文件作为其实际的游戏代码。
例如,这是神奇宝贝“能力” Aftermath
。请注意onAfterDamage
:
"aftermath": {
desc: "If this Pokemon is knocked out with a contact move, that move's user loses 1/4 of its maximum HP, rounded down. If any active Pokemon has the Damp Ability, this effect is prevented.",
shortDesc: "If this Pokemon is KOed with a contact move, that move's user loses 1/4 its max HP.",
id: "aftermath",
name: "Aftermath",
onAfterDamageOrder: 1,
onAfterDamage: function (damage, target, source, move) {
if (source && source !== target && move && move.flags['contact'] && !target.hp) {
this.damage(source.maxhp / 4, source, target);
}
},
rating: 2.5,
num: 106,
}
如您所见,onAfterDamage
是一种JavaScript函数,据我所知,我无法轻易地从Python调用它。所以现在我正处于十字路口:
停止从服务器获取.js文件,并完全用Python编写我自己的代码,本质上是自己“翻译” JavaScript代码。
用JavaScript而不是Python重写我的整个机器人,尽管我对JavaScript的经验和适应程度要差得多。
找到一种方法,运行从我的Python机器人内部从服务器下载的JavaScript代码,从该代码内部调用任意函数并返回结果。
选项1的问题很快就过时了-当引入新的Pokemon机制或创建新的Pokemon时,我不会“免费”获得它-我必须找出发生了什么变化并自己实施更改。
我想避免选择2只是因为我不太习惯编写JavaScript-过去我曾涉猎这一点,但它与我最喜欢的语言相去甚远,不是我想在什么时候处理的这不是我项目的主要重点。
我意识到选项3带来了相当大的安全风险-同时我有把握地确定,不会有中间人会对该机器人进行中间人攻击,除非我自己,否则可能没人会使用,我仍然只是从某处的服务器上下载随机JavaScript并尝试执行它。
我见过类似PyExecJS之类的东西,但是它们不再得到维护,而且我还没有真正看到有人推荐过类似的替代品。 PyExecJS的功能正是我正在寻找的功能(即功能execjs.eval(js_code)
),但是我不确定我是否要使用已经达到停产状态的产品。 I've seen the answers here,但他们不建议您替换PyExecJS;他们只会向该用户表明他们使用的是错误的。
我还看到人们建议使用Selenium或运行无头浏览器,但是我不确定是否要处理所有这些额外的开销。我在校外做过的第一个编程项目与此非常相似,我最终使用Selenium用Java对其进行编码。我对该体验感到不满意,并且我不希望再次这样做,尤其是当我只需要执行已经在本地下载的JavaScript时。
我在这里完全脱离基地了吗?我应该采取另一种方法,还是我应该手工将所有这些JS代码转换为Python?
答案 0 :(得分:0)
理想情况下,您可以像其他任何可执行文件一样从cli运行.js
文件。使用node -e
,您可以在cli上执行JavaScript代码。
关于此帖子https://stackoverflow.com/a/450329/6478277,您可以类似地在本地节点上运行脚本。
node -e "function func(){console.log(123)};func();"
来自文件
print subprocess.check_output(['node -e "require(\"./file.js\").test()"'])
file.js可能类似于
module.exports = {
test: () => console.log(123),
}