#include "library.h" namespace py = pybind11; PYBIND11_MODULE(library, m) { m.doc() = "Python API for playing Starcraft II"; define_typeenums(m); define_unit(m); define_unittype(m); define_util(m); define_point(m); define_base_location(m); define_tech_tree(m); define_map_tools(m); define_building_placer(m); py::class_<Coordinator>(m, "Coordinator") .def(py::init()) .def("set_participants", &sc2::Coordinator::SetParticipants, "participants"_a) .def("launch_starcraft", &sc2::Coordinator::LaunchStarcraft) .def("start_game", &sc2::Coordinator::StartGame, "map_path"_a) .def("update", &sc2::Coordinator::Update); py::enum_<sc2::Race>(m, "Race") .value("Terran", sc2::Race::Terran) .value("Zerg", sc2::Race::Zerg) .value("Protoss", sc2::Race::Protoss) .value("Random", sc2::Race::Random); // Stupid anonymous enum, used as int everywhere. Best work-around I could think of. py::module players = m.def_submodule("Players", "Constants for referring to players"); players.attr("Self") = (int) Players::Self; players.attr("Enemy") = (int) Players::Enemy; players.attr("Neutral") = (int) Players::Neutral; players.attr("Ally") = (int) Players::Ally; players.attr("Size") = (int) Players::Size; // These are probably used for players.attr("None") = (int) Players::None; // creating arrays of fixed length?? /* TODO: These also needs to be defined typedef SC2Type<ABILITY_ID> AbilityID; typedef SC2Type<UPGRADE_ID> UpgradeID; typedef SC2Type<BUFF_ID> BuffID; */ py::class_<sc2::UnitTypeID>(m, "UnitTypeID") .def(py::init<sc2::UNIT_TYPEID>()); py::implicitly_convertible<sc2::UNIT_TYPEID, sc2::UnitTypeID>(); py::class_<sc2::Agent>(m, "Agent") .def(py::init()); // IDABot is a specialization of Agent py::class_<IDABot, PyIDABot, sc2::Agent>(m, "IDABot") .def(py::init()) // TODO: The following 3 are CamelCased, but if the name is changed // the name used for inheritance in Pyhon stays the same. Weird. .def("OnGameStart", &IDABot::OnGameStart) .def("OnStep", &IDABot::OnStep) .def("get_all_units", &IDABot::GetAllUnits) .def("get_my_units", &IDABot::GetMyUnits) .def("get_player_race", &IDABot::GetPlayerRace) .def_property_readonly("base_location_manager", &IDABot::Bases) .def_property_readonly("tech_tree", &IDABot::TechTree) .def_property_readonly("map_tools", &IDABot::Map) .def_property_readonly("building_placer", &IDABot::BuildingPlacer) .def_property_readonly("start_location", &IDABot::GetStartLocation) .def_property_readonly("minerals", &IDABot::GetMinerals) .def_property_readonly("current_supply", &IDABot::GetCurrentSupply) .def_property_readonly("max_supply", &IDABot::GetMaxSupply) .def_property_readonly("gas", &IDABot::GetGas); py::class_<sc2::PlayerSetup>(m, "PlayerSetup"); py::enum_<sc2::Difficulty>(m, "Difficulty") .value("VeryEasy", sc2::Difficulty::VeryEasy) .value("Easy", sc2::Difficulty::Easy) .value("Medium", sc2::Difficulty::Medium) .value("MediumHard", sc2::Difficulty::MediumHard) .value("Hard", sc2::Difficulty::Hard) .value("HardVeryHard", sc2::Difficulty::HardVeryHard) .value("VeryHard", sc2::Difficulty::VeryHard) .value("CheatVision", sc2::Difficulty::CheatVision) .value("CheatMoney", sc2::Difficulty::CheatMoney) .value("CheatInsane", sc2::Difficulty::CheatInsane); py::class_<sc2::Color>(m, "Color") .def(py::init<>()) .def(py::init<int, int, int>()) .def_readwrite("r", &sc2::Color::r) .def_readwrite("g", &sc2::Color::g) .def_readwrite("b", &sc2::Color::b); py::module colors = m.def_submodule("Colors", "Constants for common colors"); colors.attr("White") = sc2::Colors::White; colors.attr("Red") = sc2::Colors::Red; colors.attr("Green") = sc2::Colors::Green; colors.attr("Yellow") = sc2::Colors::Yellow; colors.attr("Blue") = sc2::Colors::Blue; colors.attr("Teal") = sc2::Colors::Teal; colors.attr("Purple") = sc2::Colors::Purple; colors.attr("Black") = sc2::Colors::Black; colors.attr("Gray") = sc2::Colors::Gray; m.def("create_participants", &sc2::CreateParticipant, "Create participant from agent"); m.def("create_computer", &sc2::CreateComputer, "Create participant from built-in Starcraft computer"); }