Skip to content
Snippets Groups Projects
Commit c7ab9fd7 authored by David Bergström's avatar David Bergström
Browse files

Add new tech tree implementation

parent 25ae3af0
No related branches found
No related tags found
No related merge requests found
...@@ -4,3 +4,9 @@ ...@@ -4,3 +4,9 @@
[submodule "lib/s2client-api"] [submodule "lib/s2client-api"]
path = lib/s2client-api path = lib/s2client-api
url = git@github.com:Blizzard/s2client-api.git url = git@github.com:Blizzard/s2client-api.git
[submodule "lib/sc2-gamedata"]
path = lib/sc2-gamedata
url = git@github.com:noorus/sc2-gamedata.git
[submodule "lib/json"]
path = lib/json
url = git@github.com:nlohmann/json.git
Subproject commit 7bfc406ded0434c438dd22139a8baa97f2ffa90e
Subproject commit a82b9aeed5be23149e3f79b31793bdc29bab3923
...@@ -2,6 +2,7 @@ include_directories(SYSTEM ...@@ -2,6 +2,7 @@ include_directories(SYSTEM
${PROJECT_SOURCE_DIR}/lib/s2client-api/include ${PROJECT_SOURCE_DIR}/lib/s2client-api/include
${PROJECT_SOURCE_DIR}/lib/s2client-api/contrib/protobuf/src ${PROJECT_SOURCE_DIR}/lib/s2client-api/contrib/protobuf/src
${PROJECT_BINARY_DIR}/lib/s2client-api/generated ${PROJECT_BINARY_DIR}/lib/s2client-api/generated
${PROJECT_SOURCE_DIR}/lib/json/include
) )
# All the source files for the bot. # All the source files for the bot.
......
...@@ -5,6 +5,7 @@ include_directories(SYSTEM ...@@ -5,6 +5,7 @@ include_directories(SYSTEM
${PROJECT_SOURCE_DIR}/lib/s2client-api/include ${PROJECT_SOURCE_DIR}/lib/s2client-api/include
${PROJECT_SOURCE_DIR}/lib/s2client-api/contrib/protobuf/src ${PROJECT_SOURCE_DIR}/lib/s2client-api/contrib/protobuf/src
${PROJECT_BINARY_DIR}/lib/s2client-api/generated ${PROJECT_BINARY_DIR}/lib/s2client-api/generated
${PROJECT_SOURCE_DIR}/lib/json/include
) )
link_directories(${PROJECT_BINARY_DIR}/s2client-api/bin) link_directories(${PROJECT_BINARY_DIR}/s2client-api/bin)
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "UnitInfoManager.h" #include "UnitInfoManager.h"
#include "BuildingPlacer.h" #include "BuildingPlacer.h"
#include "TechTree.h" #include "TechTree.h"
#include "TechTreeImproved.h"
#include "MetaType.h" #include "MetaType.h"
#include "Unit.h" #include "Unit.h"
......
...@@ -8,6 +8,20 @@ MyAgent::MyAgent() ...@@ -8,6 +8,20 @@ MyAgent::MyAgent()
void MyAgent::OnGameStart() void MyAgent::OnGameStart()
{ {
IDABot::OnGameStart(); IDABot::OnGameStart();
sc2::UnitTypeID wanted_type = sc2::UNIT_TYPEID::TERRAN_GHOST;
sc2::UnitTypeData wanted_data = Observation()->GetUnitTypeData()[wanted_type];
std::cout << "Looking up: " << wanted_data.name << std::endl;
sc2::UnitTypeData requirement = Observation()->GetUnitTypeData()[wanted_data.tech_requirement];
std::cout << "Found tech requirement: " << requirement.name << "(" << wanted_data.tech_requirement << ")" << std::endl;
std::cout << std::boolalpha;
std::cout << "Require attached (Is addon?): " << wanted_data.require_attached << std::endl;
std::cout << "Found ability_id" << wanted_data.ability_id << std::endl;
// TODO: What/who can use this ability??
sc2::AbilityData ability_to_create = Observation()->GetAbilityData()[wanted_data.ability_id];
std::cout << "Button name for ability " << ability_to_create.button_name << std::endl;
} }
void MyAgent::OnStep() void MyAgent::OnStep()
......
#include "TechTreeImproved.h"
using json = nlohmann::json;
TechTreeImproved::TechTreeImproved() { }
sc2::UNIT_TYPEID string_to_id(const std::string & str)
{
return static_cast<sc2::UNIT_TYPEID>(std::stoi(str));
}
std::string id_to_string(int id)
{
return sc2::UnitTypeToName(static_cast<sc2::UNIT_TYPEID>(id));
}
void add_requirement(json & requirement, BuildAlternative & alternative)
{
std::string type = requirement["type"];
if (type == "and")
{
for (auto & subrequirement : requirement["operands"])
{
add_requirement(subrequirement, alternative);
}
}
else if (type == "unitCount")
{
if (requirement["state"] == "CompleteOnlyAtUnit")
{
for (auto & unit : requirement["unit"])
{
//std::cout << "Addon: " << sc2::UnitTypeToName(static_cast<sc2::UNIT_TYPEID>(unit)) << " (" << unit << ")" << std::endl;
alternative.addons_needed.push_back(static_cast<sc2::UNIT_TYPEID>(unit));
}
}
else if (requirement["state"] == "CompleteOnly")
{
for (auto & unit : requirement["unit"])
{
//std::cout << "Just building: " << sc2::UnitTypeToName(static_cast<sc2::UNIT_TYPEID>(unit)) << " (" << unit << ")" << std::endl;
alternative.buildings_needed.push_back(static_cast<sc2::UNIT_TYPEID>(unit));
}
}
else
{
//std::cout << "Unsupported" << std::endl;
//std::cout << requirement << std::endl;
}
}
}
BuildAlternative parse_build_alternative(json & build_item)
{
BuildAlternative alternative{ build_item["unit"] };
if (build_item.find("requires") != build_item.end())
{
//std::cout << "Building unit: " << id_to_string(build_item["unit"]) << " requires" << std::endl;
auto & requires = build_item["requires"][0];
add_requirement(requires, alternative);
}
return alternative;
}
std::pair<sc2::UNIT_TYPEID, std::vector<BuildAlternative>> parse_unit(json::iterator it)
{
sc2::UNIT_TYPEID id = string_to_id(it.key());
std::string name = sc2::UnitTypeToName(id);
std::vector<BuildAlternative> build_alternatives;
if (it.value().find("builds") != it.value().end())
{
auto & builds = it.value()["builds"];
for (auto & build_item : builds)
{
BuildAlternative build_alternative = parse_build_alternative(build_item);
build_alternatives.push_back(build_alternative);
}
}
return { id, build_alternatives };
}
void TechTreeImproved::LoadData() {
// TODO: Do not hardcode this. Use the latest json available.
std::ifstream i("techtree.json");
json j;
i >> j;
for (auto & race : j)
{
for (json::iterator it = race.begin(); it != race.end(); ++it)
{
auto pair = parse_unit(it);
data[pair.first] = pair.second;
}
}
std::cout << "Done" << std::endl;
}
const std::vector<BuildAlternative> & TechTreeImproved::GetBuildAlternatives(sc2::UNIT_TYPEID unit) const
{
if (data.count(unit) > 0)
{
return data.at(unit);
}
else
{
std::cout << "No information about unit type " << sc2::UnitTypeToName(unit) << " (" << static_cast<int>(unit) << ")" << std::endl;
return {};
}
}
std::vector<std::pair<sc2::UNIT_TYPEID, BuildAlternative>> TechTreeImproved::HowToBuild(sc2::UNIT_TYPEID unit_type)
{
std::vector<std::pair<sc2::UNIT_TYPEID, BuildAlternative>> alternatives;
for (auto & pair : data)
{
for (const BuildAlternative & alternative : pair.second)
{
if (alternative.type == unit_type)
{
alternatives.push_back({ pair.first, alternative });
}
}
}
return alternatives;
}
\ No newline at end of file
#pragma once
#include "nlohmann/json.hpp"
#include <string>
#include <vector>
#include <fstream>
#include <iostream>
#include "sc2api/sc2_typeenums.h"
struct BuildAlternative
{
sc2::UNIT_TYPEID type;
std::vector<sc2::UNIT_TYPEID> buildings_needed;
std::vector<sc2::UNIT_TYPEID> addons_needed;
};
class TechTreeImproved
{
std::map<sc2::UNIT_TYPEID, std::vector<BuildAlternative>> data;
public:
TechTreeImproved();
void LoadData();
const std::vector<BuildAlternative> & GetBuildAlternatives(sc2::UNIT_TYPEID) const;
std::vector<std::pair<sc2::UNIT_TYPEID, BuildAlternative>> TechTreeImproved::HowToBuild(sc2::UNIT_TYPEID unit);
};
\ No newline at end of file
...@@ -5,9 +5,18 @@ ...@@ -5,9 +5,18 @@
#include "sc2utils/sc2_manage_process.h" #include "sc2utils/sc2_manage_process.h"
#include "sc2api/sc2_api.h" #include "sc2api/sc2_api.h"
#include "TechTreeImproved.h"
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
TechTreeImproved tree;
tree.LoadData();
std::vector<BuildAlternative> alts = tree.GetBuildAlternatives(sc2::UNIT_TYPEID::TERRAN_BARRACKS);
std::vector<std::pair<sc2::UNIT_TYPEID, BuildAlternative>> alts2 = tree.HowToBuild(sc2::UNIT_TYPEID::TERRAN_GHOST);
return 0;
sc2::Coordinator coordinator; sc2::Coordinator coordinator;
if (!coordinator.LoadSettings(argc, argv)) if (!coordinator.LoadSettings(argc, argv))
{ {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment