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

Reimplement New TechTree

parent c7ab9fd7
No related branches found
No related tags found
No related merge requests found
......@@ -8,6 +8,7 @@ void define_unittype(py::module & m)
.def(py::init<const sc2::UnitTypeID &, IDABot &>())
.def("is_type_id", &UnitType::is, "Check if UnitType is UnitTypeID")
.def(py::self == py::self)
.def_property_readonly("type_id", &UnitType::getAPIUnitType)
.def_property_readonly("name", &UnitType::getName)
.def_property_readonly("race", &UnitType::getRace)
.def_property_readonly("is_valid", &UnitType::isValid)
......
......@@ -14,14 +14,14 @@ std::string id_to_string(int id)
return sc2::UnitTypeToName(static_cast<sc2::UNIT_TYPEID>(id));
}
void add_requirement(json & requirement, BuildAlternative & alternative)
void add_requirement(BuildDescription & description, json & requirement)
{
std::string type = requirement["type"];
if (type == "and")
{
for (auto & subrequirement : requirement["operands"])
{
add_requirement(subrequirement, alternative);
add_requirement(description, subrequirement);
}
}
else if (type == "unitCount")
......@@ -31,7 +31,7 @@ void add_requirement(json & requirement, BuildAlternative & alternative)
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));
description.addons_needed.push_back(static_cast<sc2::UNIT_TYPEID>(unit));
}
}
else if (requirement["state"] == "CompleteOnly")
......@@ -39,7 +39,7 @@ void add_requirement(json & requirement, BuildAlternative & alternative)
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));
description.buildings_needed.push_back(static_cast<sc2::UNIT_TYPEID>(unit));
}
}
else
......@@ -50,39 +50,52 @@ void add_requirement(json & requirement, BuildAlternative & alternative)
}
}
BuildAlternative parse_build_alternative(json & build_item)
void parse_build_description(BuildDescription & description, json & build_item)
{
BuildAlternative alternative{ build_item["unit"] };
description.resulting_type = 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);
add_requirement(description, requires);
}
return alternative;
}
std::pair<sc2::UNIT_TYPEID, std::vector<BuildAlternative>> parse_unit(json::iterator it)
void TechTreeImproved::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;
sc2::UNIT_TYPEID producer_id = string_to_id(it.key());
//std::string name = sc2::UnitTypeToName(producer_id);
std::vector<BuildDescription> build_descriptions;
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);
BuildDescription description;
description.producer_type = producer_id;
parse_build_description(description, build_item);
if (result_to_data.count(description.resulting_type) > 0)
{
std::cout << "Found more than one way to build " << sc2::UnitTypeToName(description.resulting_type) << " (" << (unsigned int) description.resulting_type << ")" << std::endl;
result_to_data[description.resulting_type].push_back(description);
}
else
{
result_to_data[description.resulting_type] = { description };
}
}
}
return { id, build_alternatives };
producer_to_data[producer_id] = build_descriptions;
}
void TechTreeImproved::LoadData() {
// TODO: Do not hardcode this. Use the latest json available.
// TODO: Check if file exists
std::ifstream i("techtree.json");
json j;
i >> j;
......@@ -91,39 +104,21 @@ void TechTreeImproved::LoadData() {
{
for (json::iterator it = race.begin(); it != race.end(); ++it)
{
auto pair = parse_unit(it);
data[pair.first] = pair.second;
parse_unit(it);
}
}
std::cout << "Done" << std::endl;
}
const std::vector<BuildAlternative> & TechTreeImproved::GetBuildAlternatives(sc2::UNIT_TYPEID unit) const
const std::vector<BuildDescription> & TechTreeImproved::HowToBuild(sc2::UnitTypeID unit) const
{
if (data.count(unit) > 0)
sc2::UNIT_TYPEID unit_id = static_cast<sc2::UNIT_TYPEID>(unit);
if (result_to_data.count(unit) > 0)
{
return data.at(unit);
return result_to_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
......@@ -8,19 +8,27 @@
#include "sc2api/sc2_typeenums.h"
struct BuildAlternative
struct BuildDescription
{
sc2::UNIT_TYPEID type;
sc2::UNIT_TYPEID producer_type;
sc2::UNIT_TYPEID resulting_type;
sc2::AbilityID ability_used;
float time;
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;
std::vector<BuildDescription> data;
std::map<sc2::UNIT_TYPEID, std::vector<BuildDescription>> producer_to_data;
std::map<sc2::UNIT_TYPEID, std::vector<BuildDescription>> result_to_data;
void parse_unit(nlohmann::json::iterator it);
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);
// Given a unit, how can we build it?
const std::vector<BuildDescription> & HowToBuild(sc2::UnitTypeID unit) const;
};
\ No newline at end of file
......@@ -12,8 +12,7 @@ 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);
std::vector<BuildDescription> alts = tree.HowToBuild(sc2::UNIT_TYPEID::TERRAN_GHOST);
return 0;
......
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