Warning: here are trashy fragments of notes made during development. I'm afraid I could forget something important, thus I've decided to keep it as is for a while.
- tutorial like http://sscaitournament.com/index.php?action=tutorial
- enrich docs with comments from BWAPI headers.
- designate different position types in docs.
- remove methods requiring position as tuple, if duplicate method with x,y available
sphinx-build . -b html _build/html
generator.parser
contains everything related to parsing of BWAPI include files.
It returns data structure sufficient to generate binding module.
There're several kinds of things to be passed between python and C++ sides:
- Usual C++ enums (refer to pybind manual).
- Classes.
- Primitive types and STL containers automatically handled by pybind11.
Depending on:
- Availability of class destructor in public space (
This is required just for describing a class using
py::class_
. It doesn't matter even if you're going to use objects only via weakrefs ). - Whether the type is actually a pointer to a class.
- Intended for construction from python side as usual object.
- Class resembles set (may be with some extra methods, marked with +).
- Class is BWAPI::Type with numeric ID and string Name (may be with some extra methods, marked with +). This class works like numeric enum constant, but has some attached functionality.
Possible decisions:
- Building proxy class (for available destructor) holding pointer to actual object, behaving like weakref.
- Possibility to construct typed set on py side and call its methods.
# possible to create C++ side set from pure pythonic pset = Playerset({player1, player2}) pset.getRaces() # passing sets to methods require constructed object # for simplicity, due to rareness of such situations some_bwapi_method(pset) # impossible: some_bwapi_method({player1, player2}) # returned values are also C++ side objects with ability to iterate pset2 = another_bwapi_method() pset2.getRaces() for player in pset2: pass pythonic_set = set(pset2) # for simplicity other set operations are NOT implemented: # impossible: pset2.add(player2) pset2 = Playerset(set(pset2) | {player2}) # Yes, this is slightly suboptimal, but doesn't complicate things.
- Straightforward description of class using pybind11.
- Without ability to construct, enumeration of singletons available in advance.
- With free ability to construct.
- Without ability to construct, one singleton available in advance.
class | 1 | 2 | 3 | 4 | 5 | decision |
---|---|---|---|---|---|---|
Bullet | Y | 1 | ||||
Bulletset | Y | 2 | ||||
Client | 3.3 | |||||
Color | Y | Y+ | 3.2 | |||
DamageType | Y | 3.1 | ||||
Error | Y | 3.1 | ||||
ExplosionType | Y | 3.1 | ||||
Force | Y | 1 | ||||
Forceset | Y+ | 2 | ||||
Game | N | 1 | ||||
GameType | Y | 3.1 | ||||
Order | Y | 3.1 | ||||
Player | Y | 1 | ||||
Playerset | Y+ | 2 | ||||
PlayerType | Y+ | 3.1 | ||||
Race | Y+ | 3.1 | ||||
Region | Y | 1 | ||||
Regionset | Y+ | 2 | ||||
TechType | Y+ | 3.1 | ||||
Unit | Y | 1 | ||||
UnitCommandType | Y | 3.1 | ||||
Unitset | Y+ | 2 | ||||
UnitSizeType | Y | 3.1 | ||||
UnitType | Y+ | 3.1 | ||||
UpgradeType | Y+ | 3.1 | ||||
WeaponType | Y+ | 3.1 |
Note that handling of all type cases must also be done in return values and function/method parameters.
BWAPI::Game
is now a separate module instead being class instance. Game instances are getting replaced
during run time, we're forced to use static wrapper above it: Broodwar->
.
Simply as pybind11 manual says:
py::class_<BWAPI::Race>(m, "Race")
.def("getWorker", ...)
.def("getCenter", ...)
.def("getRefinery", ...)
.def("getTransport", ...)
.def("getSupplyProvider", ...);
Yet again, we need to choose pythonic name: "Race"
.
Straightforward pybind11 classes used in conjunction with returning as weakref.
namespace Races
{
extern const Race Zerg;
extern const Race Terran;
extern const Race Protoss;
extern const Race Random;
extern const Race None;
extern const Race Unknown;
}
→
{
auto o = py::dict();
o["Zerg"] = py::cast(BWAPI::Races::Zerg, py::return_value_policy::reference);
o["Terran"] = py::cast(BWAPI::Races::Terran, py::return_value_policy::reference);
o["Protoss"] = py::cast(BWAPI::Races::Protoss, py::return_value_policy::reference);
o["Random"] = py::cast(BWAPI::Races::Random, py::return_value_policy::reference);
o["None"] = py::cast(BWAPI::Races::None, py::return_value_policy::reference);
o["Unknown"] = py::cast(BWAPI::Races::Unknown, py::return_value_policy::reference);
m.attr("Races") = o;
}
Python side then can build dummy object converting this dict keys into properties:
Races.Terran.getRefinery()
some_bwapi_method(Races.Terran)
TODO: implement all for: BulletType DamageType Error ExplosionType GameType Order PlayerType Race TechType UnitCommandType UnitSizeType UnitType UpgradeType WeaponType
+ AIModule.h
+ ArithmaticFilter.h
BestFilter.h
+ Bullet.h
Bulletset.h
set methods ? (empty)
+ BulletType.h
Client.h
+ Color.h
Color is the one of few types open for construction from python side.
ComparisonFilter.h
+ Constants.h
only TILE_SIZE constant, она нигде не используется
+ CoordinateType.h
+ DamageType.h
+ Error.h
Event.h
+ EventType.h
+ ExplosionType.h
Filters.h
+ Flag.h
+ Force.h
Forceset.h
set methods
Game.h
+ GameType.h
+ Input.h
+ Interface.h
есть возможность вешать эвенты на сущности, но это по сути уже частичная
имплементация самого AI алгоритма. и работает оно тупо проверяя указанный
колбэк с определённой периодичностью.
явно не то, ради чего стоит усложнять биндинг
+ InterfaceEvent.h
+ Latency.h
+ Order.h
+ Player.h
Playerset.h
set methods
+ PlayerType.h
+ Position.h
условно выполнено. отброшена вся векторная логика, позиции выдаются без
различия в скейле. предполагается считать на стороне питона, так как
транслировать простейшие операции через барьер биндинга очень медленно.
PositionUnit.h
+ Race.h
+ Region.h
Regionset.h
set methods
+ SetContainer.h
+ TechType.h
+ TournamentAction.h
+ Type.h
UnaryFilter.h
+ Unit.h
UnitCommand.h
+ UnitCommandType.h
Unitset.h
set methods
+ UnitSizeType.h
UnitType.h
constants from line 905
static methods from line 926 (including __all__)
+ UpgradeType.h
WeaponType.h
static methods from line 311 (including __all__)
+ WindowsTypes.h