Skip to content
Snippets Groups Projects
IDABot.cpp 4.93 KiB
Newer Older
#include "IDABot.h"
#include "Util.h"

IDABot::IDABot()
	: m_map(*this)
	, m_bases(*this)
	, m_unitInfo(*this)
	, m_techTree(*this)
    , m_buildingPlacer(*this)
{
}

void IDABot::OnGameStart()
{
	// ----------------------------------------------------------------- 
	// Initialize all start (base) locations.
	// -----------------------------------------------------------------
	for (auto & loc : Observation()->GetGameInfo().enemy_start_locations)
	{
		m_baseLocations.push_back(loc);
	}
	m_baseLocations.push_back(Observation()->GetStartLocation());

	// -----------------------------------------------------------------
	// Initialize all info, units, etc.
	// -----------------------------------------------------------------
	setUnits();
	m_techTree.onStart();
	m_map.onStart();
	m_unitInfo.onStart();
	m_bases.onStart();
    m_buildingPlacer.onStart();

    UnitType target { sc2::UNIT_TYPEID::TERRAN_FUSIONCORE, *this };
    std::vector<UnitType> needed = { target };
    build_order.clear();

    std::cout << "Creating plan: ";

    while (!needed.empty())
    {
        UnitType target = needed.back();
	    TypeData target_data = m_techTree.getData(target);
        build_order.push_back(target);
        std::cout << target.getName();
        needed.pop_back();
        
        if (!target_data.requiredUnits.empty())
        {
            // We only need one of the required units, so we pick the first.
            // TODO: Pick in a smarter way.
            UnitType subtarget = target_data.requiredUnits.front();
            needed.push_back(subtarget);

            std::cout << ", ";
        }
    }

    std::cout << "." << std::endl;
    std::cout << "Created build plan of " << build_order.size() << " steps." << std::endl;
}

void IDABot::OnStep()
{
	// -----------------------------------------------------------------
	// Update units, map info, unit info, and base info.
	// -----------------------------------------------------------------
	setUnits();
	m_map.onFrame();
	m_unitInfo.onFrame();
	m_bases.onFrame();

	// -----------------------------------------------------------------
	// Draw debug interface, and send debug interface to the Sc2 client.
	// -----------------------------------------------------------------
	Debug()->SendDebug();
    m_buildingPlacer.drawReservedTiles();
}

void IDABot::setUnits()
{
	m_allUnits.clear();
	Control()->GetObservation();
	for (auto & unit : Observation()->GetUnits())
	{
		m_allUnits.push_back(Unit(unit, *this));
	}
}

CCRace IDABot::GetPlayerRace(int player) const
{
	auto playerID = Observation()->GetPlayerID();
	for (auto & playerInfo : Observation()->GetGameInfo().player_info)
	{
		if (playerInfo.player_id == playerID)
		{
			return playerInfo.race_actual;
		}
	}

	BOT_ASSERT(false, "Failed to find the player's race!");
	return sc2::Race::Random;
}

const MapTools & IDABot::Map() const
{
	return m_map;
}

const BaseLocationManager & IDABot::Bases() const
{
	return m_bases;
}

const UnitInfoManager & IDABot::UnitInfo() const
{
	return m_unitInfo;
}

int IDABot::GetCurrentFrame() const
{
	return (int)Observation()->GetGameLoop();
}

const TechTree & IDABot::TechTree() const
{
    return m_techTree;
}

int IDABot::GetCurrentSupply() const
{
	return Observation()->GetFoodUsed();
}

int IDABot::GetMaxSupply() const
{
	return Observation()->GetFoodCap();
}

int IDABot::GetMinerals() const
{
	return Observation()->GetMinerals();
}

int IDABot::GetGas() const
{
	return Observation()->GetVespene();
}

Unit IDABot::GetUnit(const CCUnitID & tag) const
{
	return Unit(Observation()->GetUnit(tag), *(IDABot *)this);
}

const std::vector<Unit> & IDABot::GetAllUnits() const
{
	return m_allUnits;
}

const std::vector<Unit> & IDABot::GetMyUnits() const
{
	return UnitInfo().getUnits(Players::Self);
}

const std::vector<Unit> IDABot::GetUnits(const UnitType & type, int player) const
{
    std::vector<Unit> units;
    for (const Unit & unit : GetAllUnits()) {
        if (unit.getPlayer() == player)
        {
            if (!type.isValid() || (type.isValid() && unit.getType() == type))
            {
                units.push_back(unit);
            }
        }
    }
    return units;
}

CCPosition IDABot::GetStartLocation() const
{
	return Observation()->GetStartLocation();
}

const std::vector<CCPosition> & IDABot::GetStartLocations() const
{
	return m_baseLocations;
}

void IDABot::OnError(const std::vector<sc2::ClientError> & client_errors, const std::vector<std::string> & protocol_errors)
{
	// This is called when the sc2api (Google's API) has an error.
BuildingPlacer & IDABot::BuildingPlacer()
{
    return m_buildingPlacer;
}

const TypeData & IDABot::Data(const UnitType & type) const
{
	return m_techTree.getData(type);
}

const TypeData & IDABot::Data(const Unit & unit) const
{
	return m_techTree.getData(unit.getType());
}

const TypeData & IDABot::Data(const CCUpgrade & type) const
{
	return m_techTree.getData(type);
}

const TypeData & IDABot::Data(const MetaType & type) const
{
	return m_techTree.getData(type);
}