5 个版本
0.1.4 | 2021 年 8 月 28 日 |
---|---|
0.1.3 | 2021 年 8 月 28 日 |
0.1.2 | 2021 年 8 月 22 日 |
0.1.1 | 2021 年 8 月 8 日 |
0.1.0 | 2021 年 8 月 7 日 |
在 WebAssembly 中排名第 604
87KB
2K SLoC
Yare-Rust
一个用于使用 Rust 为 yare 创建机器人的库。
工作原理
您创建一个 Rust 库并将其编译为 wasm。然后,您使用 wasm2yareio 脚本来生成一个 JavaScript yare 机器人。结果可以复制到游戏中。
设置
您需要 Rust 和一些额外的工具。
rustup toolchain add nightly
rustup target add wasm32-unknown-unknown
rustup component add llvm-tools-preview
rustup update
创建一个新的 Rust 库。
cargo new --lib my-yare-bot
将以下内容放入您的 Cargo.toml
中。
[lib]
crate-type = ["cdylib"]
[dependencies]
yareio = "0.1"
[profile.release]
opt-level = "s"
lto = true
然后从链接的子模块中复制 wasm2yareio.js
到您的项目中,并安装一个依赖项。确保您的 Node 是最新的。
npm i minify
示例
这是一个示例机器人。您需要定义一个名为 tick
的外部函数,它有一个参数。这将每帧被调用。
#[no_mangle]
pub extern "C" fn tick(_tick: u32) {
unsafe {
let me = player::me();
let Position {x, y} = base::position(0);
for index in 0..spirit::count() {
if spirit::player_id(index) == me && spirit::hp(index) > 0 {
spirit::goto(index, x, y);
}
}
}
}
您应该为这些函数创建安全的包装器,这样您就不必在机器人代码中有 unsafe
块。例如,您可以这样做
use std::ffi::CString;
use yareio::spirit;
use yareio::player;
/// Your own Spirit struct with all the information you want.
struct Spirit {
index: usize,
alive: bool,
friendly: bool,
}
impl Spirit {
/// Safe wrapper for moving a spirit.
fn goto(&self, x: f32, y: f32) {
unsafe { spirit::goto(self.index, x, y) }
}
/// Safe wrapper for using shout.
fn shout(&self, string: &str) {
let c_string = CString::new(string).unwrap();
unsafe { spirit::shout(self.index, c_string.as_ptr()) }
}
}
/// Parse all spirits into your own Spirit structs.
fn get_spirits() -> Vec<Spirit> {
unsafe {
let me = player::me();
let count = spirit::count();
let mut spirits = Vec::with_capacity(count);
for index in 0..count {
spirits.push(Spirit {
index,
alive: spirit::hp(index) > 0,
friendly: spirit::player_id(index) == me,
});
}
spirits
}
}
// No unsafe block needed here!
#[no_mangle]
pub extern "C" fn tick(_tick: u32) {
let all_spirits = get_spirits();
for spirit in all_spirits {
if spirit.friendly && spirit.alive {
spirit.goto(123., 456.);
spirit.shout("Hello, world!");
}
}
}
查看这个 模板 以了解如何结构您的代码的示例!
构建
要构建您的 yare 机器人,您首先需要将其编译为 wasm。使用这个
cargo rustc --target wasm32-unknown-unknown --release -- -C target-feature=+multivalue
然后,您想要通过 wasm2yareio 传递它。
node wasm2yareio target/wasm32-unknown-unknown/release/my-yare-bot.wasm
还建议您安装 tampermonkey 脚本来自动将您的代码上传到 yare.io: 点击安装。
无头
该库包含 dbenson24 对游戏的头无脑实现。它并不完整,但可用于回归测试或可能用于机器学习。
要使用它,您需要启用 "headless" 功能。您很可能想要在测试时这样做。命令可能看起来像这样
cargo test --features yareio/headless --release
测试应该看起来像这样
#[cfg(test)]
mod tests {
use std::rc::Rc;
use yareio::yare_impl::{Headless, Outcome, SimulationResult, Shape};
#[test]
fn win_against_rush() {
let bots: &[Rc<dyn Fn(u32)>] = &[Rc::new(my_bot_func), Rc::new(rush)];
let shapes = &[Shape::Circle, Shape::Square];
let headless = Headless::init(bots, shapes, None);
let SimulationResult(_tick, outcome) = headless.simulate();
assert!(matches!(outcome, Outcome::Victory(0)));
}
}
确保您的机器人在运行多个测试时是线程安全的。如果您与自己对战,请确保您没有写入相同的可变静态变量。
此外,还有未经文档记录的 ffi 绑定,可以从其他语言运行头无脑模拟。
依赖项
~0–340KB