diff --git a/python-api-src/lib_sc2_typeenums.cpp b/python-api-src/lib_sc2_typeenums.cpp index 21b0c0945d387938a2fd18e5d5164a523b04710a..3715131af008ed4c9f8bb3dc6fd47a5a37cdb4b8 100644 --- a/python-api-src/lib_sc2_typeenums.cpp +++ b/python-api-src/lib_sc2_typeenums.cpp @@ -4,7 +4,7 @@ namespace py = pybind11; // This file is brought to you by VIM, phew. -void define_pyteenums(py::module & m) +void define_typeenums(py::module & m) { py::enum_<sc2::UNIT_TYPEID>(m, "UNIT_TYPEID") .value("INVALID", sc2::UNIT_TYPEID::INVALID) diff --git a/python-api-src/lib_unit.cpp b/python-api-src/lib_unit.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c3b71e1b404a4a7a8201193f57ecfa58b1d4d09d --- /dev/null +++ b/python-api-src/lib_unit.cpp @@ -0,0 +1,41 @@ +#include "library.h" + +namespace py = pybind11; + +void define_unit(py::module & m) +{ + py::class_<Unit>(m, "Unit") + .def_property_readonly("unit_type", &Unit::getType) + .def_property_readonly("position", &Unit::getPosition) + .def_property_readonly("tile_position", &Unit::getTilePosition) + .def_property_readonly("hit_points", &Unit::getHitPoints) + .def_property_readonly("shields", &Unit::getShields) + .def_property_readonly("energy", &Unit::getEnergy) + .def_property_readonly("player", &Unit::getPlayer) + .def_property_readonly("id", &Unit::getID) + .def_property_readonly("build_percentage", &Unit::getBuildPercentage) + .def_property_readonly("weapon_cooldown", &Unit::getWeaponCooldown) + .def_property_readonly("completed", &Unit::isCompleted) + .def_property_readonly("being_constructed", &Unit::isBeingConstructed) + .def_property_readonly("cloaked", &Unit::isCloaked) + .def_property_readonly("flying", &Unit::isFlying) + .def_property_readonly("alive", &Unit::isAlive) + .def_property_readonly("powered", &Unit::isPowered) + .def_property_readonly("idle", &Unit::isIdle) + .def_property_readonly("burrowed", &Unit::isBurrowed) + .def_property_readonly("valid", &Unit::isValid) + .def_property_readonly("training", &Unit::isTraining) + .def_property_readonly("constructing", &Unit::isConstructing) + .def("stop", &Unit::stop) + .def("attackUnit", &Unit::attackUnit) + .def("attackMove", &Unit::attackMove) + .def("move", py::overload_cast<const CCPosition &>(&Unit::move, py::const_)) + .def("move", py::overload_cast<const CCTilePosition &>(&Unit::move, py::const_)) + .def("rightClick", &Unit::rightClick) + .def("repair", &Unit::repair) + .def("build", &Unit::build) + .def("buildTarget", &Unit::buildTarget) + .def("train", &Unit::train) + .def("morph", &Unit::morph) + .def("__repr__", [](const Unit & unit) { return "<Unit of type: '" + unit.getType().getName() + "'>"; }); +} diff --git a/python-api-src/lib_unittype.cpp b/python-api-src/lib_unittype.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0586d1bd53ad397c9a8d5a3e1ebc8d082ea9f1df --- /dev/null +++ b/python-api-src/lib_unittype.cpp @@ -0,0 +1,43 @@ +#include "library.h" + +namespace py = pybind11; + +void define_unittype(py::module & m) +{ + py::class_<UnitType>(m, "UnitType") + .def("is", &UnitType::is, "Check if UnitType is UnitTypeID") + .def(py::self == py::self) + .def_property_readonly("name", &UnitType::getName) + .def_property_readonly("race", &UnitType::getRace) + .def_property_readonly("is_valid", &UnitType::isValid) + .def_property_readonly("is_building", &UnitType::isBuilding) + .def_property_readonly("is_combat_unit", &UnitType::isCombatUnit) + .def_property_readonly("is_supply_provider", &UnitType::isSupplyProvider) + .def_property_readonly("is_resource_depot", &UnitType::isResourceDepot) + .def_property_readonly("is_refinery", &UnitType::isRefinery) + .def_property_readonly("is_detector", &UnitType::isDetector) + .def_property_readonly("is_geyser", &UnitType::isGeyser) + .def_property_readonly("is_mineral", &UnitType::isMineral) + .def_property_readonly("is_worker", &UnitType::isWorker) + .def_property_readonly("is_morphed_building", &UnitType::isMorphedBuilding) + // Not implemented in CommandCenter + //.def_property_readonly("can_attack", &UnitType::canAttack) + //.def_property_readonly("can_Move", &UnitType::canMove) + .def_property_readonly("is_addon", &UnitType::isAddon) + .def_property_readonly("attack_range", &UnitType::getAttackRange) + .def_property_readonly("tile_width", &UnitType::tileWidth) + .def_property_readonly("tile_height", &UnitType::tileHeight) + .def_property_readonly("supply_provided", &UnitType::supplyProvided) + .def_property_readonly("supply_required", &UnitType::supplyRequired) + .def_property_readonly("mineral_price", &UnitType::mineralPrice) + .def_property_readonly("gas_price", &UnitType::gasPrice) + .def_property_readonly("is_overlord", &UnitType::isOverlord) + .def_property_readonly("is_larva", &UnitType::isLarva) + .def_property_readonly("is_egg", &UnitType::isEgg) + .def_property_readonly("is_queen", &UnitType::isQueen) + .def_property_readonly("is_tank", &UnitType::isTank) + .def("__repr__", [](const UnitType & unit_type) { return "<UnitType: '" + unit_type.getName() + "'>"; }); + + // Not implemented in CommandCenter + //.def("whatBuilds", &UnitType::whatBuilds); +} \ No newline at end of file diff --git a/python-api-src/lib_util.cpp b/python-api-src/lib_util.cpp new file mode 100644 index 0000000000000000000000000000000000000000..116975c45c972f99212d74dc0039aaded2753799 --- /dev/null +++ b/python-api-src/lib_util.cpp @@ -0,0 +1,12 @@ +#include "library.h" + +namespace py = pybind11; + +void define_util(py::module & mod) +{ + py::module m = mod.def_submodule("util"); + + m.def("dist", py::overload_cast<const Unit &, const Unit &>(&Util::Dist)); + m.def("dist", py::overload_cast<const Unit &, const CCPosition &>(&Util::Dist)); + m.def("dist", py::overload_cast<const CCPosition &, const CCPosition &>(&Util::Dist)); +} \ No newline at end of file diff --git a/python-api-src/library.cpp b/python-api-src/library.cpp index 11857558e9db3c08b4028d1441d9d5a77eba7fea..08add75862eba63d93bc8b409868cf8a0d2fe7ad 100644 --- a/python-api-src/library.cpp +++ b/python-api-src/library.cpp @@ -4,7 +4,12 @@ namespace py = pybind11; PYBIND11_MODULE(library, m) { - m.doc() = "pybind11 example plugin"; + m.doc() = "Python API for playing Starcraft II"; + + define_typeenums(m); + define_unit(m); + define_unittype(m); + define_util(m); py::class_<Coordinator>(m, "Coordinator") .def(py::init()) @@ -28,6 +33,7 @@ PYBIND11_MODULE(library, m) .def("OnGameStart", &IDABot::OnGameStart) .def("OnStep", &IDABot::OnStep) .def("OnStep_UpdateIDABot", &IDABot::OnStep_UpdateIDABot) + .def("GetAllUnits", &IDABot::GetAllUnits) .def("GetMyUnits", &IDABot::GetMyUnits); py::class_<sc2::PlayerSetup>(m, "PlayerSetup"); diff --git a/python-api-src/library.h b/python-api-src/library.h index c8bdb794a34492ccfbd2f67a01eded7801d6e9db..14223b336fd9417d262d8c2cc5e195c77d437e34 100644 --- a/python-api-src/library.h +++ b/python-api-src/library.h @@ -5,6 +5,7 @@ #include "../src/IDABot.h" #include <iostream> #include <pybind11/stl.h> /* Automatic conversion from std::vector to Python lists */ +#include <pybind11/operators.h> /* Convenient operator support */ // Wrapper class since the initialization uses pure argc/argv and these cannot be wrapped into Python correctly class Coordinator : public sc2::Coordinator @@ -49,4 +50,7 @@ public: } }; -void define_typeenums(pybind11::module & m); \ No newline at end of file +void define_typeenums(pybind11::module & m); +void define_unit(pybind11::module & m); +void define_unittype(pybind11::module &m); +void define_util(pybind11::module &m); \ No newline at end of file diff --git a/src/Common.h b/src/Common.h index dec31ff1c17f20febfeb62c626591401146db424..fa45feb4e2c7a5fe0d1690082c8c8a1e37fd6313 100644 --- a/src/Common.h +++ b/src/Common.h @@ -10,7 +10,8 @@ #include <string> #include <array> -// Somewhere in the dependency graph someone defines a macro max, which ruins everything +// Somewhere in the dependency graph someone defines a macro called max, +// which breaks all calls to std::limits::max #define NOMINMAX #include <sc2api/sc2_api.h> @@ -25,6 +26,7 @@ typedef float CCHealth; typedef float CCPositionType; typedef size_t CCPlayer; + namespace Players { enum {Self = 0u, Enemy = 1u, Neutral = 2u, Ally = 3u, Size = 4u, None = 5u};