14 个不稳定版本 (3 个破坏性版本)
使用旧的 Rust 2015
0.4.0-alpha.2 | 2018年4月15日 |
---|---|
0.4.0-alpha.0 | 2018年4月14日 |
0.3.3 | 2018年4月15日 |
0.3.2 | 2018年3月6日 |
0.1.7 | 2018年1月12日 |
#692 in 异步
每月 32 次下载
10MB
7K SLoC
这是我对StarCraft II 客户端 API的 Rust 实现。
这个软件包仍在积极开发中,我刚刚决定关于 futures 和 streams 的方向。它目前依赖于 nightly #[async]/await!
,但如果足够的人支持稳定 futures,我会考虑将其作为一个特性来引入,但到目前为止,使用实验性功能而不是稳定组合器是非常方便的。
我尽量使其与 s2client-api 在功能划分上保持一致,例如 Action 接口和 Observer 接口,但也有一些不同,因为 C++ 的惯用语法和 Rust 的惯用语法并不兼容(而且有充分的理由),我还非常感兴趣于 futures-rs 的工作,并认为优雅的异步编程非常适合这个库。特别是,s2client-api 和这个库之间核心区别之一是创建机器人和事件消费。
s2client-api 使用多态来定义机器人,而 sc2-rs 则使用通道在机器人和 API 之间进行通信。让我们看看如何创建一个简单的裸机机器人。
#![feature(proc_macro, generators)]
extern crate futures_await as futures;
extern crate tokio_core;
extern crate sc2;
use futures::prelude::*;
use futures::unsync::mpsc;
use sc2::{
agent::{AgentBuilder},
ai::{OpponentBuilder},
data::{GameSetup, Map, Race},
observer::{Event, EventAck},
LauncherSettings,
MeleeBuilder,
Result,
Error,
};
use tokio_core::reactor;
struct SimpleBot;
impl SimpleBot {
fn new() -> Self {
Self { }
}
/// Spawn our bot's coroutine on the event loop.
fn spawn(
self,
handle: &reactor::Handle,
rx: mpsc::Receiver<(Event, EventAck)>,
) -> Result<()> {
handle.spawn(self.run(rx).map_err(|e| panic!("{:#?}", e)));
Ok(())
}
/// Run the bot.
#[async]
fn run(mut self, rx: mpsc::Receiver<(Event, EventAck)>) -> Result<()> {
// Loop over the game events.
#[async]
for (e, ack) in rx.map_err(|_| -> Error { unreachable!() }) {
match e {
// Triggered once at the start of every game.
Event::GameStarted => println!("Started a new game!"),
// Triggered every time the game updates.
Event::Step => println!("Game Stepped!"),
// Ignore the other events for now.
_ => (),
}
// Notify the coordinator that we have consumed this event.
await!(ack.done())?;
}
Ok(())
}
}
这个机器人简单地设计为接收游戏事件流,并打印 GameStarted 和 GameStepped 的事件消息。通常,你会使用这些事件来观察游戏状态和/或向单位下达命令。但现在,一条消息就足够了。
fn main() {
// Create a new event loop.
let mut core = reactor::Core::new().unwrap();
let handle = core.handle();
// Create a new Agent and set the Race to Terran.
let mut agent = AgentBuilder::new().race(Race::Terran);
// Instantiate our simple bot.
let bot = SimpleBot::new();
// Get the event stream from the Agent and spawn our bot's coroutine.
bot.spawn(&handle, agent.take_event_stream().unwrap()).unwrap();
// Create a match between our bot and a default SC2 built-in AI Opponent.
let melee = MeleeBuilder::new()
.add_player(agent)
.add_player(OpponentBuilder::new())
.launcher_settings(LauncherSettings::new())
.one_and_done(GameSetup::new(Map::LocalMap(
"maps/Ladder/(2)Bel'ShirVestigeLE (Void).SC2Map".into()
)))
.step_interval(1)
.handle(&handle)
.create()
.unwrap();
// Run the match to completion on the event loop.
core.run(melee.into_future()).unwrap();
}
在这里,我们创建一个事件循环,将我们的机器人作为协程启动,并监听来自内置 SC2 AI 对手的肉搏(PvP)比赛的事件。
需要注意的是,默认的LauncherSettings只会在Windows上找到你的SC2。然而,由于无头Linux版本在调试方面并不理想,我为所有像我一样懒得双启动(或者只是更喜欢Linux)的人添加了库中对Wine的支持。好消息是,Wine确实支持SC2,坏消息是,我上次检查的时候,支持需要较新的(可能为预发布版本)Wine。
以下是一些有用的链接,可以帮助你开始使用它
依赖项
~23–32MB
~553K SLoC