Skip to content

Commit

Permalink
Merge pull request #110 from Bam4d/griddly_rts
Browse files Browse the repository at this point in the history
Griddly rts
  • Loading branch information
Bam4d authored May 10, 2021
2 parents a0c8d0a + fb65600 commit b4a6558
Show file tree
Hide file tree
Showing 213 changed files with 2,259 additions and 838 deletions.
5 changes: 4 additions & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,7 @@
path=python/examples/experiments/conditional-action-trees
url=https://github.com/Bam4d/conditional-action-trees
ignore = dirty

[submodule "python/examples/experiments/rts-self-play"]
path = python/examples/experiments/rts-self-play
url = https://github.com/Bam4d/rts-self-play
ignore = dirty
4 changes: 4 additions & 0 deletions bindings/python.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ PYBIND11_MODULE(python_griddly, m) {
game_process.def("get_width", &Py_GameWrapper::getWidth);
game_process.def("get_height", &Py_GameWrapper::getHeight);

// Observation shapes
game_process.def("get_global_observation_shape", &Py_GameWrapper::getGlobalObservationShape);
game_process.def("get_player_observation_shape", &Py_GameWrapper::getPlayerObservationShape);

// Tile size of the global observer
game_process.def("get_tile_size", &Py_GameWrapper::getTileSize);
game_process.def("observe", &Py_GameWrapper::observe);
Expand Down
86 changes: 47 additions & 39 deletions bindings/wrapper/GameWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,27 +9,26 @@
namespace griddly {

class ValidActionNode {
public:
std::unordered_map<uint32_t, std::shared_ptr<ValidActionNode>> children;

bool contains(uint32_t value) {
return children.find(value) != children.end();
}
public:
std::unordered_map<uint32_t, std::shared_ptr<ValidActionNode>> children;

void add(uint32_t value) {
children[value] = std::shared_ptr<ValidActionNode>(new ValidActionNode());
}
bool contains(uint32_t value) {
return children.find(value) != children.end();
}

static py::dict toPyDict(std::shared_ptr<ValidActionNode> node) {
py::dict py_dict;
for(auto child: node->children) {
py_dict[py::cast(child.first)] = toPyDict(child.second);
}
void add(uint32_t value) {
children[value] = std::shared_ptr<ValidActionNode>(new ValidActionNode());
}

return py_dict;
static py::dict toPyDict(std::shared_ptr<ValidActionNode> node) {
py::dict py_dict;
for (auto child : node->children) {
py_dict[py::cast(child.first)] = toPyDict(child.second);
}
};

return py_dict;
}
};

class Py_GameWrapper {
public:
Expand Down Expand Up @@ -65,17 +64,16 @@ class Py_GameWrapper {

const uint32_t getActionTypeId(std::string actionName) const {
auto actionNames = gdyFactory_->getExternalActionNames();
for(int i = 0; i<actionNames.size(); i++) {
if(actionNames[i] == actionName) {
for (int i = 0; i < actionNames.size(); i++) {
if (actionNames[i] == actionName) {
return i;
}
}
throw std::runtime_error("unregistered action");
}

std::vector<py::dict> buildValidActionTrees() const {

std::vector<py::dict> valid_action_trees;
std::vector<py::dict> valid_action_trees;
auto externalActionNames = gdyFactory_->getExternalActionNames();
spdlog::debug("Building tree, {0} actions", externalActionNames.size());
for (int playerId = 1; playerId <= playerCount_; playerId++) {
Expand All @@ -84,10 +82,7 @@ class Py_GameWrapper {
auto location = actionNamesAtLocation.first;
auto actionNames = actionNamesAtLocation.second;



for (auto actionName : actionNames) {

spdlog::debug("[{0}] available at location [{1}, {2}]", actionName, location.x, location.y);

std::shared_ptr<ValidActionNode> treePtr = node;
Expand All @@ -102,29 +97,29 @@ class Py_GameWrapper {
if (gdyFactory_->getAvatarObject().length() == 0) {
auto py_x = locationVec[0];
auto py_y = locationVec[1];
if(!treePtr->contains(py_x)) {
treePtr->add(py_x);
if (!treePtr->contains(py_x)) {
treePtr->add(py_x);
}

treePtr = treePtr->children[py_x];

if(!treePtr->contains(py_y)) {
treePtr->add(py_y);
if (!treePtr->contains(py_y)) {
treePtr->add(py_y);
}

treePtr = treePtr->children[py_y];
}

if (externalActionNames.size() > 1) {
auto actionTypeId = getActionTypeId(actionName);
if(!treePtr->contains(actionTypeId)) {
if (!treePtr->contains(actionTypeId)) {
treePtr->add(actionTypeId);
}

treePtr = treePtr->children[actionTypeId];
}

for(auto id : actionIdsForName) {
for (auto id : actionIdsForName) {
treePtr->add(id);
}
treePtr->add(0);
Expand Down Expand Up @@ -180,14 +175,21 @@ class Py_GameWrapper {
gameProcess_->setLevel(levelString);
}

std::shared_ptr<NumpyWrapper<uint8_t>> reset() {
auto observation = gameProcess_->reset();
if (observation != nullptr) {
auto observer = gameProcess_->getObserver();
return std::shared_ptr<NumpyWrapper<uint8_t>>(new NumpyWrapper<uint8_t>(observer->getShape(), observer->getStrides(), std::move(observation)));
void reset() {
gameProcess_->reset();
}

std::vector<uint32_t> getGlobalObservationShape() const {
auto observer = gameProcess_->getObserver();
if (observer == nullptr) {
return {};
} else {
return observer->getShape();
}
}

return nullptr;
std::vector<uint32_t> getPlayerObservationShape() const {
return players_[0]->getObservationShape();
}

std::shared_ptr<NumpyWrapper<uint8_t>> observe() {
Expand All @@ -197,7 +199,9 @@ class Py_GameWrapper {
throw std::invalid_argument("No global observer configured");
}

return std::shared_ptr<NumpyWrapper<uint8_t>>(new NumpyWrapper<uint8_t>(observer->getShape(), observer->getStrides(), gameProcess_->observe()));
auto observationData = observer->update();

return std::shared_ptr<NumpyWrapper<uint8_t>>(new NumpyWrapper<uint8_t>(observer->getShape(), observer->getStrides(), observationData));
}

py::tuple stepParallel(py::buffer stepArray) {
Expand Down Expand Up @@ -265,13 +269,17 @@ class Py_GameWrapper {

auto playerStepResult = players_[p]->stepSingle(actionName, actionArray, lastPlayer);

playerRewards.push_back(playerStepResult[0].cast<int32_t>());
//playerRewards.push_back(playerStepResult[0].cast<int32_t>());
if (lastPlayer) {
terminated = playerStepResult[1].cast<bool>();
info = playerStepResult[2];
terminated = playerStepResult[0].cast<bool>();
info = playerStepResult[1];
}
}

for(int p = 0; p < playerSize; p++) {
playerRewards.push_back(gameProcess_->getAccumulatedRewards(p+1));
}

return py::make_tuple(playerRewards, terminated, info);
}

Expand Down
33 changes: 20 additions & 13 deletions bindings/wrapper/StepPlayerWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,19 @@ class Py_StepPlayerWrapper {
return {(uint32_t)tileSize[0], (uint32_t)tileSize[1]};
}

std::vector<uint32_t> getObservationShape() const {
return player_->getObserver()->getShape();
}

std::shared_ptr<NumpyWrapper<uint8_t>> observe() {
auto observer = player_->getObserver();
if (observer == nullptr) {
throw std::invalid_argument("No player observer configured");
}

return std::shared_ptr<NumpyWrapper<uint8_t>>(new NumpyWrapper<uint8_t>(observer->getShape(), observer->getStrides(), player_->observe()));
auto observationData = observer->update();

return std::shared_ptr<NumpyWrapper<uint8_t>>(new NumpyWrapper<uint8_t>(observer->getShape(), observer->getStrides(), observationData));
}

py::tuple stepMulti(py::buffer stepArray, bool updateTicks) {
Expand Down Expand Up @@ -100,36 +106,37 @@ class Py_StepPlayerWrapper {
}
}

return performActions(actions, updateTicks);
auto actionResult = player_->performActions(actions, updateTicks);
auto info = buildInfo(actionResult);
auto rewards = gameProcess_->getAccumulatedRewards(player_->getId());
return py::make_tuple(rewards, actionResult.terminated, info);

}

py::tuple stepSingle(std::string actionName, std::vector<int32_t> actionArray, bool updateTicks) {
auto gameProcess = player_->getGameProcess();

if (gameProcess != nullptr && !gameProcess->isInitialized()) {
if (gameProcess_ != nullptr && !gameProcess_->isInitialized()) {
throw std::invalid_argument("Cannot send player commands when game has not been initialized.");
}

auto action = buildAction(actionName, actionArray);

ActionResult actionResult;
if (action != nullptr) {
return performActions({action}, updateTicks);
actionResult = player_->performActions({action}, updateTicks);
} else {
return performActions({}, updateTicks);
actionResult = player_->performActions({}, updateTicks);
}

auto info = buildInfo(actionResult);

return py::make_tuple(actionResult.terminated, info);
}

private:
const std::shared_ptr<Player> player_;
const std::shared_ptr<GDYFactory> gdyFactory_;
const std::shared_ptr<GameProcess> gameProcess_;

py::tuple performActions(std::vector<std::shared_ptr<Action>> actions, bool updateTicks) {
auto actionResult = player_->performActions(actions, updateTicks);
auto info = buildInfo(actionResult);
return py::make_tuple(actionResult.reward, actionResult.terminated, info);
}

py::dict buildInfo(ActionResult actionResult) {
py::dict py_info;

Expand Down
4 changes: 4 additions & 0 deletions docs/_static/custom.css
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,8 @@
.game-gallery p {
margin: 10px !important;
white-space: normal !important;
}

.embedded-video {
text-align: center;
}
Binary file modified docs/games/Bait/img/Bait-level-Block2D-1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/games/Bait/img/Bait-level-Block2D-3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/games/Bait_With_Keys/img/Bait_With_Keys-level-Block2D-1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/games/Bait_With_Keys/img/Bait_With_Keys-level-Block2D-3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/games/Clusters/img/Clusters-level-Block2D-1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/games/Clusters/img/Clusters-level-Block2D-3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/games/Cook_Me_Pasta/img/Cook_Me_Pasta-level-Block2D-1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/games/Cook_Me_Pasta/img/Cook_Me_Pasta-level-Block2D-3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/games/Cook_Me_Pasta/img/Cook_Me_Pasta-level-Block2D-5.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/games/Doggo/img/Doggo-level-Block2D-1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/games/Doggo/img/Doggo-level-Block2D-3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/games/Drunk_Dwarf/img/Drunk_Dwarf-level-Block2D-1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/games/Drunk_Dwarf/img/Drunk_Dwarf-level-Block2D-3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/games/Foragers/img/Foragers-level-Block2D-1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/games/GriddlyRTS/img/GriddlyRTS-level-Block2D-0.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/games/GriddlyRTS/img/GriddlyRTS-level-Block2D-1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/games/GriddlyRTS/img/GriddlyRTS-level-Block2D-2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/games/GriddlyRTS/img/GriddlyRTS-level-Isometric-0.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/games/GriddlyRTS/img/GriddlyRTS-level-Isometric-1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/games/GriddlyRTS/img/GriddlyRTS-level-Isometric-2.png
Binary file modified docs/games/GriddlyRTS/img/GriddlyRTS-level-Sprite2D-0.png
Binary file modified docs/games/GriddlyRTS/img/GriddlyRTS-level-Sprite2D-1.png
Binary file modified docs/games/GriddlyRTS/img/GriddlyRTS-level-Sprite2D-2.png
Binary file modified docs/games/GriddlyRTS/img/GriddlyRTS-level-Vector-0.png
Binary file modified docs/games/GriddlyRTS/img/GriddlyRTS-level-Vector-1.png
Binary file modified docs/games/GriddlyRTS/img/GriddlyRTS-level-Vector-2.png
Binary file modified docs/games/GriddlyRTS/img/GriddlyRTS-tile-base-Isometric.png
Binary file modified docs/games/GriddlyRTS/img/GriddlyRTS-tile-base-Vector.png
Binary file modified docs/games/GriddlyRTS/img/GriddlyRTS-tile-fixed_wall-Vector.png
Diff not rendered.
Binary file modified docs/games/GriddlyRTS/img/GriddlyRTS-tile-minerals-Isometric.png
Binary file modified docs/games/GriddlyRTS/img/GriddlyRTS-tile-minerals-Vector.png
Diff not rendered.
Diff not rendered.
Loading

0 comments on commit b4a6558

Please sign in to comment.