Deal with setting targets
This commit is contained in:
parent
c9b8e663f8
commit
47a27960a2
|
@ -32,9 +32,6 @@ endif (WINDOWS)
|
||||||
|
|
||||||
|
|
||||||
SET(_LINKS Arbutils CreatureLib pkmnLib -lpthread)
|
SET(_LINKS Arbutils CreatureLib pkmnLib -lpthread)
|
||||||
if (NOT WINDOWS)
|
|
||||||
SET(_LINKS ${LINKS} -lbfd -ldl)
|
|
||||||
endif()
|
|
||||||
target_link_libraries(pkmnlib_ai PUBLIC ${_LINKS})
|
target_link_libraries(pkmnlib_ai PUBLIC ${_LINKS})
|
||||||
target_compile_options(pkmnlib_ai PRIVATE -Wall -Wextra -Werror)
|
target_compile_options(pkmnlib_ai PRIVATE -Wall -Wextra -Werror)
|
||||||
|
|
||||||
|
@ -43,5 +40,5 @@ if (AIRUNNER)
|
||||||
file(GLOB_RECURSE RUNNER_SRC_FILES test_runner/*.cpp test_runner/*.hpp)
|
file(GLOB_RECURSE RUNNER_SRC_FILES test_runner/*.cpp test_runner/*.hpp)
|
||||||
add_executable(pkmnlib_ai_runner ${RUNNER_SRC_FILES})
|
add_executable(pkmnlib_ai_runner ${RUNNER_SRC_FILES})
|
||||||
target_compile_options(pkmnlib_ai_runner PRIVATE -Wall -Wextra -Werror)
|
target_compile_options(pkmnlib_ai_runner PRIVATE -Wall -Wextra -Werror)
|
||||||
target_link_libraries(pkmnlib_ai_runner PUBLIC pkmnlib_ai)
|
target_link_libraries(pkmnlib_ai_runner PUBLIC pkmnlib_ai -lpthread)
|
||||||
endif()
|
endif()
|
|
@ -17,6 +17,27 @@ namespace PkmnLibAI {
|
||||||
NaiveAI _naive;
|
NaiveAI _naive;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
class SimulatedResult {
|
||||||
|
public:
|
||||||
|
std::optional<float> Score;
|
||||||
|
CreatureLib::Battling::CreatureIndex Target;
|
||||||
|
|
||||||
|
SimulatedResult(std::optional<float> score, CreatureLib::Battling::CreatureIndex target)
|
||||||
|
: Score(score), Target(target) {}
|
||||||
|
SimulatedResult() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class ScoredOption {
|
||||||
|
public:
|
||||||
|
u8 OptionIndex;
|
||||||
|
std::optional<float> Score;
|
||||||
|
CreatureLib::Battling::CreatureIndex Target;
|
||||||
|
|
||||||
|
ScoredOption(u8 optionIndex, SimulatedResult result)
|
||||||
|
: OptionIndex(optionIndex), Score(result.Score), Target(result.Target) {}
|
||||||
|
ScoredOption() {}
|
||||||
|
};
|
||||||
|
|
||||||
float ScoreBattle(PkmnLib::Battling::Battle* battle, PkmnLib::Battling::Pokemon* user) {
|
float ScoreBattle(PkmnLib::Battling::Battle* battle, PkmnLib::Battling::Pokemon* user) {
|
||||||
auto side = user->GetBattleSide().GetValue();
|
auto side = user->GetBattleSide().GetValue();
|
||||||
if (battle->HasEnded()) {
|
if (battle->HasEnded()) {
|
||||||
|
@ -62,9 +83,9 @@ namespace PkmnLibAI {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<std::tuple<u8, float>> ScoreChoicesThreaded(PkmnLib::Battling::Battle* battle,
|
std::vector<ScoredOption> ScoreChoicesThreaded(PkmnLib::Battling::Battle* battle,
|
||||||
PkmnLib::Battling::Pokemon* user, uint8_t depth) {
|
PkmnLib::Battling::Pokemon* user, uint8_t depth) {
|
||||||
std::vector<std::future<std::tuple<u8, float>>> threadPool;
|
std::vector<std::future<ScoredOption>> threadPool;
|
||||||
auto side = user->GetBattleSide().GetValue();
|
auto side = user->GetBattleSide().GetValue();
|
||||||
for (u8 moveIndex = 0; moveIndex < (u8)user->GetMoves().Count(); ++moveIndex) {
|
for (u8 moveIndex = 0; moveIndex < (u8)user->GetMoves().Count(); ++moveIndex) {
|
||||||
auto move = user->GetMoves()[moveIndex];
|
auto move = user->GetMoves()[moveIndex];
|
||||||
|
@ -75,7 +96,7 @@ namespace PkmnLibAI {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
threadPool.push_back(std::async([this, battle, side, moveIndex, depth] {
|
threadPool.push_back(std::async([this, battle, side, moveIndex, depth] {
|
||||||
auto v = std::tuple(moveIndex, SimulateTurn(battle, side->GetSideIndex(), 0, moveIndex, depth));
|
auto v = ScoredOption(moveIndex, SimulateTurn(battle, side->GetSideIndex(), 0, moveIndex, depth));
|
||||||
asThreadCleanup();
|
asThreadCleanup();
|
||||||
return v;
|
return v;
|
||||||
}));
|
}));
|
||||||
|
@ -90,21 +111,21 @@ namespace PkmnLibAI {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
threadPool.push_back(std::async([this, battle, side, i, depth] {
|
threadPool.push_back(std::async([this, battle, side, i, depth] {
|
||||||
auto v = std::tuple((u8)(i + 4), SimulateTurn(battle, side->GetSideIndex(), 0, i + 4, depth));
|
auto v = ScoredOption((u8)(i + 4), SimulateTurn(battle, side->GetSideIndex(), 0, i + 4, depth));
|
||||||
asThreadCleanup();
|
asThreadCleanup();
|
||||||
return v;
|
return v;
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
std::vector<std::tuple<u8, float>> results(threadPool.size());
|
std::vector<ScoredOption> results(threadPool.size());
|
||||||
for (size_t i = 0; i < threadPool.size(); ++i) {
|
for (size_t i = 0; i < threadPool.size(); ++i) {
|
||||||
results[i] = threadPool[i].get();
|
results[i] = threadPool[i].get();
|
||||||
}
|
}
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::tuple<int, float>> ScoreChoices(PkmnLib::Battling::Battle* battle,
|
std::vector<ScoredOption> ScoreChoices(PkmnLib::Battling::Battle* battle, PkmnLib::Battling::Pokemon* user,
|
||||||
PkmnLib::Battling::Pokemon* user, uint8_t depth) {
|
uint8_t depth) {
|
||||||
std::vector<std::tuple<int, float>> scoredMoves;
|
std::vector<ScoredOption> scoredMoves;
|
||||||
auto side = user->GetBattleSide().GetValue();
|
auto side = user->GetBattleSide().GetValue();
|
||||||
for (u8 moveIndex = 0; moveIndex < (u8)user->GetMoves().Count(); ++moveIndex) {
|
for (u8 moveIndex = 0; moveIndex < (u8)user->GetMoves().Count(); ++moveIndex) {
|
||||||
auto move = user->GetMoves()[moveIndex];
|
auto move = user->GetMoves()[moveIndex];
|
||||||
|
@ -133,32 +154,60 @@ namespace PkmnLibAI {
|
||||||
return scoredMoves;
|
return scoredMoves;
|
||||||
}
|
}
|
||||||
|
|
||||||
float SimulateTurn(PkmnLib::Battling::Battle* originalBattle, u8 sideIndex, u8 pokemonIndex, u8 index,
|
std::optional<CreatureLib::Battling::CreatureIndex>
|
||||||
|
GetTarget(PkmnLib::Battling::Pokemon* user, ArbUt::BorrowedPtr<const CreatureLib::Library::AttackData> move) {
|
||||||
|
switch (move->GetTarget()) {
|
||||||
|
|
||||||
|
case CreatureLib::Library::AttackTarget::Adjacent: return {};
|
||||||
|
case CreatureLib::Library::AttackTarget::AdjacentAlly: return {};
|
||||||
|
case CreatureLib::Library::AttackTarget::AdjacentAllySelf: return user->GetBattleIndex();
|
||||||
|
case CreatureLib::Library::AttackTarget::AdjacentOpponent: return GetOppositeIndex(user);
|
||||||
|
case CreatureLib::Library::AttackTarget::All: return GetOppositeIndex(user);
|
||||||
|
case CreatureLib::Library::AttackTarget::AllAdjacent: return GetOppositeIndex(user);
|
||||||
|
case CreatureLib::Library::AttackTarget::AllAdjacentOpponent: return GetOppositeIndex(user);
|
||||||
|
case CreatureLib::Library::AttackTarget::AllAlly: return user->GetBattleIndex();
|
||||||
|
case CreatureLib::Library::AttackTarget::AllOpponent: return GetOppositeIndex(user);
|
||||||
|
case CreatureLib::Library::AttackTarget::Any: return GetOppositeIndex(user);
|
||||||
|
case CreatureLib::Library::AttackTarget::RandomOpponent: return GetOppositeIndex(user);
|
||||||
|
case CreatureLib::Library::AttackTarget::Self: return user->GetBattleIndex();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SimulatedResult SimulateTurn(PkmnLib::Battling::Battle* originalBattle, u8 sideIndex, u8 pokemonIndex, u8 index,
|
||||||
u8 depth) {
|
u8 depth) {
|
||||||
auto battle = BattlePointerWrapper(originalBattle->Clone());
|
auto battle = BattlePointerWrapper(originalBattle->Clone());
|
||||||
auto user =
|
auto user =
|
||||||
dynamic_cast<PkmnLib::Battling::Pokemon*>(battle->GetCreature(sideIndex, pokemonIndex).GetValue());
|
dynamic_cast<PkmnLib::Battling::Pokemon*>(battle->GetCreature(sideIndex, pokemonIndex).GetValue());
|
||||||
auto target = GetOppositeIndex(user);
|
CreatureLib::Battling::CreatureIndex target;
|
||||||
if (index < 4) {
|
if (index < 4) {
|
||||||
auto move = user->GetMoves()[index];
|
auto move = user->GetMoves()[index];
|
||||||
if (!move.HasValue()) {
|
if (!move.HasValue()) {
|
||||||
return std::numeric_limits<float>::min();
|
return {};
|
||||||
}
|
}
|
||||||
|
if (move.GetValue()->GetRemainingUses() <= 0) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
auto targetOption = GetTarget(user, move.GetValue()->GetAttack());
|
||||||
|
if (!targetOption.has_value()) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
target = targetOption.value();
|
||||||
auto choice = new CreatureLib::Battling::AttackTurnChoice(user, move.GetValue(), target);
|
auto choice = new CreatureLib::Battling::AttackTurnChoice(user, move.GetValue(), target);
|
||||||
if (!battle->TrySetChoice(choice)) {
|
if (!battle->TrySetChoice(choice)) {
|
||||||
delete choice;
|
delete choice;
|
||||||
return std::numeric_limits<float>::min();
|
return {};
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
auto mon = battle->GetParties()[sideIndex]->GetParty()->GetParty().At(index - 4);
|
auto mon = battle->GetParties()[sideIndex]->GetParty()->GetParty().At(index - 4);
|
||||||
auto choice = new CreatureLib::Battling::SwitchTurnChoice(user, mon);
|
auto choice = new CreatureLib::Battling::SwitchTurnChoice(user, mon);
|
||||||
if (!battle->TrySetChoice(choice)) {
|
if (!battle->TrySetChoice(choice)) {
|
||||||
delete choice;
|
delete choice;
|
||||||
return std::numeric_limits<float>::min();
|
return {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
battle->TrySetChoice(_naive.GetChoice(
|
battle->TrySetChoice(_naive.GetChoice(
|
||||||
battle.Battle, dynamic_cast<PkmnLib::Battling::Pokemon*>(battle->GetCreature(target).GetValue())));
|
battle.Battle,
|
||||||
|
dynamic_cast<PkmnLib::Battling::Pokemon*>(battle->GetCreature(GetOppositeIndex(user)).GetValue())));
|
||||||
|
|
||||||
float score;
|
float score;
|
||||||
if (depth <= 1) {
|
if (depth <= 1) {
|
||||||
|
@ -168,16 +217,20 @@ namespace PkmnLibAI {
|
||||||
float summedScore = 0;
|
float summedScore = 0;
|
||||||
size_t amount = 0;
|
size_t amount = 0;
|
||||||
for (auto& option : scoredChoices) {
|
for (auto& option : scoredChoices) {
|
||||||
summedScore += std::get<1>(option);
|
auto v = option.Score;
|
||||||
|
if (!v.has_value()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
summedScore += v.value();
|
||||||
amount++;
|
amount++;
|
||||||
}
|
}
|
||||||
if (amount == 0) {
|
if (amount == 0) {
|
||||||
return std::numeric_limits<float>::min();
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
score = summedScore / amount;
|
score = summedScore / amount;
|
||||||
}
|
}
|
||||||
return score;
|
return SimulatedResult(score, target);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -189,25 +242,32 @@ namespace PkmnLibAI {
|
||||||
auto side = user->GetBattleSide().GetValue();
|
auto side = user->GetBattleSide().GetValue();
|
||||||
auto& party = battle->GetParties()[side->GetSideIndex()]->GetParty()->GetParty();
|
auto& party = battle->GetParties()[side->GetSideIndex()]->GetParty()->GetParty();
|
||||||
|
|
||||||
auto target = GetOppositeIndex(user);
|
|
||||||
if (scoredChoices.empty()) {
|
if (scoredChoices.empty()) {
|
||||||
return battle->GetLibrary()->GetMiscLibrary()->ReplacementAttack(user, target);
|
return battle->GetLibrary()->GetMiscLibrary()->ReplacementAttack(user, GetOppositeIndex(user));
|
||||||
}
|
}
|
||||||
|
|
||||||
i32 highest = -1;
|
i32 highest = -1;
|
||||||
float highestScore = -std::numeric_limits<float>::infinity();
|
float highestScore = -std::numeric_limits<float>::infinity();
|
||||||
|
CreatureLib::Battling::CreatureIndex highestTarget;
|
||||||
|
|
||||||
for (auto& option : scoredChoices) {
|
for (auto& option : scoredChoices) {
|
||||||
if (std::get<1>(option) > highestScore) {
|
auto v = option.Score;
|
||||||
highestScore = std::get<1>(option);
|
if (!v.has_value()) {
|
||||||
highest = std::get<0>(option);
|
continue;
|
||||||
|
}
|
||||||
|
if (v.value() > highestScore) {
|
||||||
|
highestScore = v.value();
|
||||||
|
highest = option.OptionIndex;
|
||||||
|
highestTarget = option.Target;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (highest == -1) {
|
if (highest == -1) {
|
||||||
return battle->GetLibrary()->GetMiscLibrary()->ReplacementAttack(user, target);
|
return battle->GetLibrary()->GetMiscLibrary()->ReplacementAttack(user, GetOppositeIndex(user));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (highest < 4) {
|
if (highest < 4) {
|
||||||
return new CreatureLib::Battling::AttackTurnChoice(user, user->GetMoves()[highest].GetValue(), target);
|
return new CreatureLib::Battling::AttackTurnChoice(user, user->GetMoves()[highest].GetValue(),
|
||||||
|
highestTarget);
|
||||||
} else {
|
} else {
|
||||||
return new CreatureLib::Battling::SwitchTurnChoice(user, party.At(highest - 4));
|
return new CreatureLib::Battling::SwitchTurnChoice(user, party.At(highest - 4));
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
#ifndef PKMNLIB_AI_BUILDLIBRARY_HPP
|
||||||
|
#define PKMNLIB_AI_BUILDLIBRARY_HPP
|
||||||
|
|
||||||
|
#include <PkmnLib/Battling/Library/BattleLibrary.hpp>
|
||||||
|
#include <filesystem>
|
||||||
|
#include "BuildMoves.hpp"
|
||||||
|
#include "BuildNatures.hpp"
|
||||||
|
#include "BuildSpecies.hpp"
|
||||||
|
#include "BuildTypes.hpp"
|
||||||
|
#include "GrowthRatesBuilder.hpp"
|
||||||
|
|
||||||
|
class BuildLibrary {
|
||||||
|
static PkmnLib::Library::TimeOfDay GetTime() { return PkmnLib::Library::TimeOfDay::Morning; }
|
||||||
|
|
||||||
|
public:
|
||||||
|
static PkmnLib::Battling::BattleLibrary* Build(const std::string& pathString) {
|
||||||
|
auto path = std::filesystem::path(pathString);
|
||||||
|
auto* typesLibrary = BuildTypes::Build(path / "Types.csv");
|
||||||
|
auto* natureLibrary = BuildNatures::Build(path / "Natures.csv");
|
||||||
|
auto* movesLibrary = BuildMoves::Build(path / "Moves.json", typesLibrary);
|
||||||
|
auto* speciesLibrary = BuildSpecies::BuildLibrary(path / "Pokemon.json", typesLibrary, movesLibrary);
|
||||||
|
auto* itemsLibrary = BuildItems::Build(path / "Items.json");
|
||||||
|
auto* growthRates = GrowthRatesBuilder::Build(path / "GrowthRates.json");
|
||||||
|
auto scriptsPath = path / "Scripts";
|
||||||
|
|
||||||
|
if (typesLibrary == nullptr || speciesLibrary == nullptr || natureLibrary == nullptr ||
|
||||||
|
movesLibrary == nullptr || itemsLibrary == nullptr || growthRates == nullptr) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto settings = new PkmnLib::Library::LibrarySettings(100, 4, 4096);
|
||||||
|
auto staticLibrary = new PkmnLib::Library::PokemonLibrary(settings, speciesLibrary, movesLibrary, itemsLibrary,
|
||||||
|
growthRates, typesLibrary, natureLibrary);
|
||||||
|
|
||||||
|
auto scriptResolver = PkmnLib::Battling::BattleLibrary::CreateScriptResolver();
|
||||||
|
|
||||||
|
auto battleLib = new PkmnLib::Battling::BattleLibrary(
|
||||||
|
staticLibrary, new PkmnLib::Battling::StatCalculator(), new PkmnLib::Battling::DamageLibrary(),
|
||||||
|
new PkmnLib::Battling::ExperienceLibrary(), scriptResolver, new PkmnLib::Battling::MiscLibrary(GetTime));
|
||||||
|
|
||||||
|
scriptResolver->Initialize(battleLib);
|
||||||
|
|
||||||
|
auto asScriptResolver = dynamic_cast<AngelScriptResolver*>(scriptResolver);
|
||||||
|
|
||||||
|
for (const auto& dirEntry : std::filesystem::recursive_directory_iterator(scriptsPath)) {
|
||||||
|
if (dirEntry.is_directory())
|
||||||
|
continue;
|
||||||
|
if (dirEntry.path().parent_path().stem() == "Interfaces")
|
||||||
|
continue;
|
||||||
|
if (dirEntry.path().extension() != ".as")
|
||||||
|
continue;
|
||||||
|
std::ifstream in(dirEntry.path());
|
||||||
|
std::string contents((std::istreambuf_iterator<char>(in)), std::istreambuf_iterator<char>());
|
||||||
|
asScriptResolver->CreateScript(dirEntry.path().c_str(), contents.c_str());
|
||||||
|
}
|
||||||
|
asScriptResolver->FinalizeModule();
|
||||||
|
return battleLib;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // PKMNLIB_AI_BUILDLIBRARY_HPP
|
|
@ -70,7 +70,17 @@ u8 RunBattle(ArbUt::Random& rand, const PkmnLib::Battling::BattleLibrary* librar
|
||||||
aiTwo->GetChoice(battle, static_cast<PkmnLib::Battling::Pokemon*>(battle->GetCreature(1, 0).GetValue()));
|
aiTwo->GetChoice(battle, static_cast<PkmnLib::Battling::Pokemon*>(battle->GetCreature(1, 0).GetValue()));
|
||||||
EnsureNotNull(c1);
|
EnsureNotNull(c1);
|
||||||
EnsureNotNull(c2);
|
EnsureNotNull(c2);
|
||||||
Ensure(battle->TrySetChoice(c1));
|
if (!battle->TrySetChoice(c1)) {
|
||||||
|
if (c1->GetKind() == CreatureLib::Battling::TurnChoiceKind::Attack) {
|
||||||
|
auto a = (CreatureLib::Battling::AttackTurnChoice*)c1;
|
||||||
|
THROW("Failed to set move choice of move: '"
|
||||||
|
<< a->GetAttack()->GetAttack()->GetName() << "' targeting side "
|
||||||
|
<< (i32)a->GetTarget().GetSideIndex() << " and index " << (i32)a->GetTarget().GetCreatureIndex());
|
||||||
|
} else {
|
||||||
|
THROW("Failed to set choice of kind: "
|
||||||
|
<< CreatureLib::Battling::TurnChoiceKindHelper::ToString(c1->GetKind()));
|
||||||
|
}
|
||||||
|
}
|
||||||
Ensure(battle->TrySetChoice(c2));
|
Ensure(battle->TrySetChoice(c2));
|
||||||
if (battle->GetCurrentTurn() >= 2000) {
|
if (battle->GetCurrentTurn() >= 2000) {
|
||||||
std::cout << ((CreatureLib::Battling::AttackTurnChoice*)c1)->GetAttack()->GetAttack()->GetName()
|
std::cout << ((CreatureLib::Battling::AttackTurnChoice*)c1)->GetAttack()->GetAttack()->GetName()
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include "../extern/args.hpp"
|
#include "../extern/args.hpp"
|
||||||
#include "AIResolver.hpp"
|
#include "AIResolver.hpp"
|
||||||
#include "BuildData/BuildItems.hpp"
|
#include "BuildData/BuildItems.hpp"
|
||||||
|
#include "BuildData/BuildLibrary.hpp"
|
||||||
#include "BuildData/BuildMoves.hpp"
|
#include "BuildData/BuildMoves.hpp"
|
||||||
#include "BuildData/BuildNatures.hpp"
|
#include "BuildData/BuildNatures.hpp"
|
||||||
#include "BuildData/BuildSpecies.hpp"
|
#include "BuildData/BuildSpecies.hpp"
|
||||||
|
@ -11,20 +12,11 @@
|
||||||
#include "BuildData/GrowthRatesBuilder.hpp"
|
#include "BuildData/GrowthRatesBuilder.hpp"
|
||||||
#include "Runner.hpp"
|
#include "Runner.hpp"
|
||||||
|
|
||||||
static const char* ScriptsPath = nullptr;
|
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
args::ArgumentParser parser("PkmnLib AI Runner.", "");
|
args::ArgumentParser parser("PkmnLib AI Runner.", "");
|
||||||
args::HelpFlag help(parser, "help", "Display this help menu", {'h', "help"});
|
args::HelpFlag help(parser, "help", "Display this help menu", {'h', "help"});
|
||||||
|
|
||||||
std::string workingDirectory;
|
std::string workingDirectory;
|
||||||
std::string typesFile = "Types.csv";
|
|
||||||
std::string naturesFile = "Natures.csv";
|
|
||||||
std::string pokemonFile = "Pokemon.json";
|
|
||||||
std::string moveFile = "Moves.json";
|
|
||||||
std::string itemsFile = "Items.json";
|
|
||||||
std::string growthRatesFile = "GrowthRates.json";
|
|
||||||
std::string scriptsPath = "Scripts";
|
|
||||||
|
|
||||||
args::HelpFlag helpFlag(parser, "help", "Display this help menu", {'h', "help"});
|
args::HelpFlag helpFlag(parser, "help", "Display this help menu", {'h', "help"});
|
||||||
args::ValueFlag<std::string> workingDirFlag(parser, "Working Directory", "Which work directory to use.",
|
args::ValueFlag<std::string> workingDirFlag(parser, "Working Directory", "Which work directory to use.",
|
||||||
|
@ -52,47 +44,11 @@ int main(int argc, char** argv) {
|
||||||
if (!workingDirectory.empty()) {
|
if (!workingDirectory.empty()) {
|
||||||
chdir(std::filesystem::path(workingDirectory).c_str());
|
chdir(std::filesystem::path(workingDirectory).c_str());
|
||||||
}
|
}
|
||||||
|
auto battleLib = BuildLibrary::Build("");
|
||||||
auto* typesLibrary = BuildTypes::Build(typesFile);
|
if (battleLib == nullptr) {
|
||||||
auto* natureLibrary = BuildNatures::Build(naturesFile);
|
|
||||||
auto* movesLibrary = BuildMoves::Build(moveFile, typesLibrary);
|
|
||||||
auto* speciesLibrary = BuildSpecies::BuildLibrary(pokemonFile, typesLibrary, movesLibrary);
|
|
||||||
auto* itemsLibrary = BuildItems::Build(itemsFile);
|
|
||||||
auto* growthRates = GrowthRatesBuilder::Build(growthRatesFile);
|
|
||||||
ScriptsPath = scriptsPath.c_str();
|
|
||||||
|
|
||||||
if (typesLibrary == nullptr || speciesLibrary == nullptr || natureLibrary == nullptr || movesLibrary == nullptr ||
|
|
||||||
itemsLibrary == nullptr || growthRates == nullptr) {
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto settings = new PkmnLib::Library::LibrarySettings(100, 4, 4096);
|
|
||||||
auto staticLibrary = new PkmnLib::Library::PokemonLibrary(settings, speciesLibrary, movesLibrary, itemsLibrary,
|
|
||||||
growthRates, typesLibrary, natureLibrary);
|
|
||||||
|
|
||||||
auto scriptResolver = PkmnLib::Battling::BattleLibrary::CreateScriptResolver();
|
|
||||||
|
|
||||||
auto battleLib = new PkmnLib::Battling::BattleLibrary(
|
|
||||||
staticLibrary, new PkmnLib::Battling::StatCalculator(), new PkmnLib::Battling::DamageLibrary(),
|
|
||||||
new PkmnLib::Battling::ExperienceLibrary(), scriptResolver, new PkmnLib::Battling::MiscLibrary());
|
|
||||||
|
|
||||||
scriptResolver->Initialize(battleLib);
|
|
||||||
|
|
||||||
auto asScriptResolver = dynamic_cast<AngelScriptResolver*>(scriptResolver);
|
|
||||||
|
|
||||||
for (const auto& dirEntry : std::filesystem::recursive_directory_iterator(ScriptsPath)) {
|
|
||||||
if (dirEntry.is_directory())
|
|
||||||
continue;
|
|
||||||
if (dirEntry.path().parent_path().stem() == "Interfaces")
|
|
||||||
continue;
|
|
||||||
if (dirEntry.path().extension() != ".as")
|
|
||||||
continue;
|
|
||||||
std::ifstream in(dirEntry.path());
|
|
||||||
std::string contents((std::istreambuf_iterator<char>(in)), std::istreambuf_iterator<char>());
|
|
||||||
asScriptResolver->CreateScript(dirEntry.path().c_str(), contents.c_str());
|
|
||||||
}
|
|
||||||
asScriptResolver->FinalizeModule();
|
|
||||||
|
|
||||||
auto ai1 = AIResolver::Resolve(ArbUt::StringView(ai1Flag.Get().c_str(), ai1Flag.Get().size()));
|
auto ai1 = AIResolver::Resolve(ArbUt::StringView(ai1Flag.Get().c_str(), ai1Flag.Get().size()));
|
||||||
auto ai2 = AIResolver::Resolve(ArbUt::StringView(ai2Flag.Get().c_str(), ai1Flag.Get().size()));
|
auto ai2 = AIResolver::Resolve(ArbUt::StringView(ai2Flag.Get().c_str(), ai1Flag.Get().size()));
|
||||||
|
|
||||||
|
@ -100,7 +56,9 @@ int main(int argc, char** argv) {
|
||||||
Runner::Run(battleLib, ai1, ai2, runsFlag.Get());
|
Runner::Run(battleLib, ai1, ai2, runsFlag.Get());
|
||||||
} catch (ArbUt::Exception& e) {
|
} catch (ArbUt::Exception& e) {
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
std::cout << "Exception with message: " << std::endl << e.what() << std::endl << e.GetStacktrace(10) << std::endl;
|
std::cout << "Exception with message: " << std::endl
|
||||||
|
<< e.what() << std::endl
|
||||||
|
<< e.GetStacktrace(10) << std::endl;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue