#bot #sc2 #macro #procedural #api #proc-macro #rust-sc2

sc2-proc-macro

rust-sc2 API 的过程宏

1 个稳定版本

1.0.0 2021年2月4日

#271#bot


2 个包中使用 (通过 sc2-macro)

自定义许可证

6KB
154

rust-sc2

StarCraft II API 的 Rust 实现

该库旨在简单易用,同时非常快速且功能强大。然而,它提供了高和低层级的抽象。这个库受到了 python-sc2 库的启发,因此人们可能会发现将其切换到 rust-sc2 很容易。它最初是因为其他 rust 库过时、功能不足和低级而创建的。

欢迎在 Discord 服务器上的 #rust 频道中提问

入门

安装 Rust >= 1.42.0

警告:在 rustc 1.45.0 - 1.46.0 中编译中断,您将遇到以下错误

thread 'rustc' has overflowed its stack
error: could not compile `rust-sc2`.

在 Cargo.toml 中添加依赖项

[dependencies]
rust-sc2 = { git = "https://github.com/UltraMachine/rust-sc2" }

30行以下最简单的竞技性机器人

use rust_sc2::prelude::*;

#[bot]
#[derive(Default)]
struct WorkerRush;
impl Player for WorkerRush {
    fn get_player_settings(&self) -> PlayerSettings {
        PlayerSettings::new(Race::Protoss, None)
    }
    fn on_start(&mut self) -> SC2Result<()> {
        for worker in self.units.my.workers.iter() {
            worker.attack(Target::Pos(self.enemy_start), false);
        }
        Ok(())
    }
}

fn main() -> SC2Result<()> {
    let mut bot = WorkerRush::default();
    run_vs_computer(
        &mut bot,
        Computer::new(Race::Random, Difficulty::Medium, None),
        "EternalEmpireLE",
        Default::default(),
    )
}

更高级的示例请参阅 examples 文件夹。

可选功能

  • "rayon" - 启用并行性并使所有类型线程安全
  • "serde" - 为 ids、Race、GameResult 等添加 SerializeDeserialize 实现

逐步制作机器人

首先,导入 rust-sc2 库

use rust_sc2::prelude::*;

创建你的机器人结构体(可以是 Unit 或 C 类型的)

#[bot]
struct MyBot;
#[bot]
struct MyBot {
    /* fields here */
}

然后为你的机器人实现 Player 特性

// You mustn't call any of these methods by hands, they're for API only
impl Player for MyBot {
    // Must be implemented
    fn get_player_settings(&self) -> PlayerSettings {
        // Race can be Terran, Zerg, Protoss or Random
        // If bot name is None, it'll be shown as "foo(whatever)" in game
        PlayerSettings::new(Race::Random, Some("Bot Name"))
    }

    // Methods below aren't necessary to implement (Empty by default)

    // Called once on first step
    fn on_start(&mut self) -> SC2Result<()> {
        /* your awesome code here */
    }

    // Called on every game step
    fn on_step(&mut self, iteration: usize) -> SC2Result<()> {
        /* your awesome code here */
    }

    // Called once on last step
    // "result" says if your bot won or lost game
    fn on_end(&self, result: GameResult) -> SC2Result<()> {
        /* your awesome code here */
    }

    // Called on different events, see more in `examples/events.rs`
    fn on_event(&mut self, event: Event) -> SC2Result<()> {
        /* your awesome code here */
    }
}

你也可以添加一个构建它的方法

impl MyBot {
    // It's necessary to have #[bot_new] here
    #[bot_new]
    fn new() -> Self {
        Self {
            /* initializing fields */
        }
    }
}

如果您的机器人实现了 Default,您可以简单地调用 MyBot::default(),但如果您想对初始化器有更多的控制

impl MyBot {
    // You don't need #[bot_new] here, because of "..Default::default()"
    fn new() -> Self {
        Self {
            /* initializing fields */
            ..Default::default()
        }
    }
}

剩下的就是运行它

fn main() -> SC2Result<()> {
    let mut bot = MyBot::new();
    run_vs_computer(
        &mut bot,
        Computer::new(
            Race::Random,
            Difficulty::VeryEasy,
            None,              // AI Build (random here)
        ),
        "EternalEmpireLE", // Map name
        LaunchOptions::default(),
    )
}

依赖项

~3.5–4.5MB
~89K SLoC