mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-22 22:13:35 +02:00
BattleAI: retreat
This commit is contained in:
parent
e2b373a784
commit
82a9f82e1c
@ -17,6 +17,7 @@
|
|||||||
#include "../../lib/mapObjects/CGTownInstance.h"
|
#include "../../lib/mapObjects/CGTownInstance.h"
|
||||||
#include "../../lib/spells/CSpellHandler.h"
|
#include "../../lib/spells/CSpellHandler.h"
|
||||||
#include "../../lib/spells/ISpellMechanics.h"
|
#include "../../lib/spells/ISpellMechanics.h"
|
||||||
|
#include "../../lib/battle/BattleStateInfoForRetreat.h"
|
||||||
#include "../../lib/CStack.h" // TODO: remove
|
#include "../../lib/CStack.h" // TODO: remove
|
||||||
// Eventually only IBattleInfoCallback and battle::Unit should be used,
|
// Eventually only IBattleInfoCallback and battle::Unit should be used,
|
||||||
// CUnitState should be private and CStack should be removed completely
|
// CUnitState should be private and CStack should be removed completely
|
||||||
@ -728,14 +729,32 @@ void CBattleAI::print(const std::string &text) const
|
|||||||
|
|
||||||
boost::optional<BattleAction> CBattleAI::considerFleeingOrSurrendering()
|
boost::optional<BattleAction> CBattleAI::considerFleeingOrSurrendering()
|
||||||
{
|
{
|
||||||
if(cb->battleCanSurrender(playerID))
|
BattleStateInfoForRetreat bs;
|
||||||
|
|
||||||
|
bs.canFlee = cb->battleCanFlee();
|
||||||
|
bs.canSurrender = cb->battleCanSurrender(playerID);
|
||||||
|
bs.ourSide = cb->battleGetMySide();
|
||||||
|
bs.ourHero = cb->battleGetMyHero();
|
||||||
|
bs.enemyHero = cb->battleGetFightingHero(!bs.ourSide);
|
||||||
|
|
||||||
|
for(auto stack : cb->battleGetAllStacks(false))
|
||||||
{
|
{
|
||||||
}
|
if(stack->alive())
|
||||||
if(cb->battleCanFlee())
|
|
||||||
{
|
{
|
||||||
|
if(stack->side == bs.ourSide)
|
||||||
|
bs.ourStacks.push_back(stack);
|
||||||
|
else
|
||||||
|
bs.enemyStacks.push_back(stack);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!bs.canFlee || !bs.canSurrender)
|
||||||
|
{
|
||||||
return boost::none;
|
return boost::none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return cb->makeSurrenderRetreatDecision(bs);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include "../../lib/serializer/CTypeList.h"
|
#include "../../lib/serializer/CTypeList.h"
|
||||||
#include "../../lib/serializer/BinarySerializer.h"
|
#include "../../lib/serializer/BinarySerializer.h"
|
||||||
#include "../../lib/serializer/BinaryDeserializer.h"
|
#include "../../lib/serializer/BinaryDeserializer.h"
|
||||||
|
#include "../../lib/battle/BattleStateInfoForRetreat.h"
|
||||||
|
|
||||||
#include "AIGateway.h"
|
#include "AIGateway.h"
|
||||||
#include "Goals/Goals.h"
|
#include "Goals/Goals.h"
|
||||||
@ -488,6 +489,23 @@ void AIGateway::showWorldViewEx(const std::vector<ObjectPosInfo> & objectPositio
|
|||||||
NET_EVENT_HANDLER;
|
NET_EVENT_HANDLER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boost::optional<BattleAction> AIGateway::makeSurrenderRetreatDecision(
|
||||||
|
const BattleStateInfoForRetreat & battleState)
|
||||||
|
{
|
||||||
|
LOG_TRACE(logAi);
|
||||||
|
NET_EVENT_HANDLER;
|
||||||
|
|
||||||
|
double fightRatio = battleState.getOurStrength() / (double)battleState.getEnemyStrength();
|
||||||
|
|
||||||
|
if(fightRatio < 0.3 && battleState.canFlee)
|
||||||
|
{
|
||||||
|
return BattleAction::makeRetreat(battleState.ourSide);
|
||||||
|
}
|
||||||
|
|
||||||
|
return boost::none;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void AIGateway::init(std::shared_ptr<Environment> env, std::shared_ptr<CCallback> CB)
|
void AIGateway::init(std::shared_ptr<Environment> env, std::shared_ptr<CCallback> CB)
|
||||||
{
|
{
|
||||||
LOG_TRACE(logAi);
|
LOG_TRACE(logAi);
|
||||||
|
@ -166,6 +166,7 @@ public:
|
|||||||
void heroBonusChanged(const CGHeroInstance * hero, const Bonus & bonus, bool gain) override;
|
void heroBonusChanged(const CGHeroInstance * hero, const Bonus & bonus, bool gain) override;
|
||||||
void showMarketWindow(const IMarket * market, const CGHeroInstance * visitor) override;
|
void showMarketWindow(const IMarket * market, const CGHeroInstance * visitor) override;
|
||||||
void showWorldViewEx(const std::vector<ObjectPosInfo> & objectPositions) override;
|
void showWorldViewEx(const std::vector<ObjectPosInfo> & objectPositions) override;
|
||||||
|
boost::optional<BattleAction> makeSurrenderRetreatDecision(const BattleStateInfoForRetreat & battleState) override;
|
||||||
|
|
||||||
void battleStart(const CCreatureSet * army1, const CCreatureSet * army2, int3 tile, const CGHeroInstance * hero1, const CGHeroInstance * hero2, bool side) override;
|
void battleStart(const CCreatureSet * army1, const CCreatureSet * army2, int3 tile, const CGHeroInstance * hero1, const CGHeroInstance * hero2, bool side) override;
|
||||||
void battleEnd(const BattleResult * br) override;
|
void battleEnd(const BattleResult * br) override;
|
||||||
|
@ -387,3 +387,9 @@ bool CBattleCallback::battleMakeTacticAction( BattleAction * action )
|
|||||||
sendRequest(&ma);
|
sendRequest(&ma);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boost::optional<BattleAction> CBattleCallback::makeSurrenderRetreatDecision(
|
||||||
|
const BattleStateInfoForRetreat & battleState)
|
||||||
|
{
|
||||||
|
return cl->playerint[getPlayerID().get()]->makeSurrenderRetreatDecision(battleState);
|
||||||
|
}
|
@ -32,6 +32,7 @@ struct CPackForServer;
|
|||||||
class IBattleEventsReceiver;
|
class IBattleEventsReceiver;
|
||||||
class IGameEventsReceiver;
|
class IGameEventsReceiver;
|
||||||
struct ArtifactLocation;
|
struct ArtifactLocation;
|
||||||
|
class BattleStateInfoForRetreat;
|
||||||
|
|
||||||
VCMI_LIB_NAMESPACE_END
|
VCMI_LIB_NAMESPACE_END
|
||||||
|
|
||||||
@ -48,6 +49,7 @@ public:
|
|||||||
//battle
|
//battle
|
||||||
virtual int battleMakeAction(const BattleAction * action) = 0;//for casting spells by hero - DO NOT use it for moving active stack
|
virtual int battleMakeAction(const BattleAction * action) = 0;//for casting spells by hero - DO NOT use it for moving active stack
|
||||||
virtual bool battleMakeTacticAction(BattleAction * action) = 0; // performs tactic phase actions
|
virtual bool battleMakeTacticAction(BattleAction * action) = 0; // performs tactic phase actions
|
||||||
|
virtual boost::optional<BattleAction> makeSurrenderRetreatDecision(const BattleStateInfoForRetreat & battleState) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class IGameActionCallback
|
class IGameActionCallback
|
||||||
@ -104,6 +106,7 @@ public:
|
|||||||
CBattleCallback(boost::optional<PlayerColor> Player, CClient *C);
|
CBattleCallback(boost::optional<PlayerColor> Player, CClient *C);
|
||||||
int battleMakeAction(const BattleAction * action) override;//for casting spells by hero - DO NOT use it for moving active stack
|
int battleMakeAction(const BattleAction * action) override;//for casting spells by hero - DO NOT use it for moving active stack
|
||||||
bool battleMakeTacticAction(BattleAction * action) override; // performs tactic phase actions
|
bool battleMakeTacticAction(BattleAction * action) override; // performs tactic phase actions
|
||||||
|
boost::optional<BattleAction> makeSurrenderRetreatDecision(const BattleStateInfoForRetreat & battleState) override;
|
||||||
|
|
||||||
#if SCRIPTING_ENABLED
|
#if SCRIPTING_ENABLED
|
||||||
scripting::Pool * getContextPool() const override;
|
scripting::Pool * getContextPool() const override;
|
||||||
|
@ -12,6 +12,7 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE)
|
|||||||
${MAIN_LIB_DIR}/battle/BattleHex.cpp
|
${MAIN_LIB_DIR}/battle/BattleHex.cpp
|
||||||
${MAIN_LIB_DIR}/battle/BattleInfo.cpp
|
${MAIN_LIB_DIR}/battle/BattleInfo.cpp
|
||||||
${MAIN_LIB_DIR}/battle/BattleProxy.cpp
|
${MAIN_LIB_DIR}/battle/BattleProxy.cpp
|
||||||
|
${MAIN_LIB_DIR}/battle/BattleStateInfoForRetreat.cpp
|
||||||
${MAIN_LIB_DIR}/battle/CBattleInfoCallback.cpp
|
${MAIN_LIB_DIR}/battle/CBattleInfoCallback.cpp
|
||||||
${MAIN_LIB_DIR}/battle/CBattleInfoEssentials.cpp
|
${MAIN_LIB_DIR}/battle/CBattleInfoEssentials.cpp
|
||||||
${MAIN_LIB_DIR}/battle/CCallbackBase.cpp
|
${MAIN_LIB_DIR}/battle/CCallbackBase.cpp
|
||||||
@ -241,6 +242,7 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE)
|
|||||||
${MAIN_LIB_DIR}/battle/BattleAttackInfo.h
|
${MAIN_LIB_DIR}/battle/BattleAttackInfo.h
|
||||||
${MAIN_LIB_DIR}/battle/BattleHex.h
|
${MAIN_LIB_DIR}/battle/BattleHex.h
|
||||||
${MAIN_LIB_DIR}/battle/BattleInfo.h
|
${MAIN_LIB_DIR}/battle/BattleInfo.h
|
||||||
|
${MAIN_LIB_DIR}/battle/BattleStateInfoForRetreat.h
|
||||||
${MAIN_LIB_DIR}/battle/BattleProxy.h
|
${MAIN_LIB_DIR}/battle/BattleProxy.h
|
||||||
${MAIN_LIB_DIR}/battle/CBattleInfoCallback.h
|
${MAIN_LIB_DIR}/battle/CBattleInfoCallback.h
|
||||||
${MAIN_LIB_DIR}/battle/CBattleInfoEssentials.h
|
${MAIN_LIB_DIR}/battle/CBattleInfoEssentials.h
|
||||||
|
@ -58,7 +58,9 @@ class CLoadFile;
|
|||||||
class CSaveFile;
|
class CSaveFile;
|
||||||
class BinaryDeserializer;
|
class BinaryDeserializer;
|
||||||
class BinarySerializer;
|
class BinarySerializer;
|
||||||
|
class BattleStateInfo;
|
||||||
struct ArtifactLocation;
|
struct ArtifactLocation;
|
||||||
|
class BattleStateInfoForRetreat;
|
||||||
|
|
||||||
#if SCRIPTING_ENABLED
|
#if SCRIPTING_ENABLED
|
||||||
namespace scripting
|
namespace scripting
|
||||||
@ -108,6 +110,11 @@ public:
|
|||||||
|
|
||||||
virtual void showWorldViewEx(const std::vector<ObjectPosInfo> & objectPositions){};
|
virtual void showWorldViewEx(const std::vector<ObjectPosInfo> & objectPositions){};
|
||||||
|
|
||||||
|
virtual boost::optional<BattleAction> makeSurrenderRetreatDecision(const BattleStateInfoForRetreat & battleState)
|
||||||
|
{
|
||||||
|
return boost::none;
|
||||||
|
}
|
||||||
|
|
||||||
virtual void saveGame(BinarySerializer & h, const int version) = 0;
|
virtual void saveGame(BinarySerializer & h, const int version) = 0;
|
||||||
virtual void loadGame(BinaryDeserializer & h, const int version) = 0;
|
virtual void loadGame(BinaryDeserializer & h, const int version) = 0;
|
||||||
};
|
};
|
||||||
|
@ -105,6 +105,22 @@ BattleAction BattleAction::makeEndOFTacticPhase(ui8 side)
|
|||||||
return ba;
|
return ba;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BattleAction BattleAction::makeSurrender(ui8 side)
|
||||||
|
{
|
||||||
|
BattleAction ba;
|
||||||
|
ba.side = side;
|
||||||
|
ba.actionType = EActionType::SURRENDER;
|
||||||
|
return ba;
|
||||||
|
}
|
||||||
|
|
||||||
|
BattleAction BattleAction::makeRetreat(ui8 side)
|
||||||
|
{
|
||||||
|
BattleAction ba;
|
||||||
|
ba.side = side;
|
||||||
|
ba.actionType = EActionType::RETREAT;
|
||||||
|
return ba;
|
||||||
|
}
|
||||||
|
|
||||||
std::string BattleAction::toString() const
|
std::string BattleAction::toString() const
|
||||||
{
|
{
|
||||||
std::stringstream actionTypeStream;
|
std::stringstream actionTypeStream;
|
||||||
|
@ -40,6 +40,8 @@ public:
|
|||||||
static BattleAction makeCreatureSpellcast(const battle::Unit * stack, const battle::Target & target, SpellID spellID);
|
static BattleAction makeCreatureSpellcast(const battle::Unit * stack, const battle::Target & target, SpellID spellID);
|
||||||
static BattleAction makeMove(const battle::Unit * stack, BattleHex dest);
|
static BattleAction makeMove(const battle::Unit * stack, BattleHex dest);
|
||||||
static BattleAction makeEndOFTacticPhase(ui8 side);
|
static BattleAction makeEndOFTacticPhase(ui8 side);
|
||||||
|
static BattleAction makeRetreat(ui8 side);
|
||||||
|
static BattleAction makeSurrender(ui8 side);
|
||||||
|
|
||||||
std::string toString() const;
|
std::string toString() const;
|
||||||
|
|
||||||
|
52
lib/battle/BattleStateInfoForRetreat.cpp
Normal file
52
lib/battle/BattleStateInfoForRetreat.cpp
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* BattleStateInfoForRetreat.cpp, part of VCMI engine
|
||||||
|
*
|
||||||
|
* Authors: listed in file AUTHORS in main folder
|
||||||
|
*
|
||||||
|
* License: GNU General Public License v2.0 or later
|
||||||
|
* Full text of license available in license.txt file, in main folder
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "StdInc.h"
|
||||||
|
#include "BattleStateInfoForRetreat.h"
|
||||||
|
#include "Unit.h"
|
||||||
|
#include "CBattleInfoCallback.h"
|
||||||
|
#include "../CCreatureSet.h"
|
||||||
|
#include "../mapObjects/CGHeroInstance.h"
|
||||||
|
|
||||||
|
VCMI_LIB_NAMESPACE_BEGIN
|
||||||
|
|
||||||
|
BattleStateInfoForRetreat::BattleStateInfoForRetreat()
|
||||||
|
: canFlee(false), canSurrender(false), isLastTurnBeforeDie(false), ourStacks(), enemyStacks(), ourHero(nullptr), enemyHero(nullptr), ourSide(-1)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t getFightingStrength(std::vector<const battle::Unit *> stacks, const CGHeroInstance * hero = nullptr)
|
||||||
|
{
|
||||||
|
uint64_t result = 0;
|
||||||
|
|
||||||
|
for(const battle::Unit * stack : stacks)
|
||||||
|
{
|
||||||
|
result += stack->creatureId().toCreature()->AIValue * stack->getCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(hero)
|
||||||
|
{
|
||||||
|
result = (uint64_t)(result * hero->getFightingStrength());
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t BattleStateInfoForRetreat::getOurStrength() const
|
||||||
|
{
|
||||||
|
return getFightingStrength(ourStacks, ourHero);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t BattleStateInfoForRetreat::getEnemyStrength() const
|
||||||
|
{
|
||||||
|
return getFightingStrength(enemyStacks, enemyHero);
|
||||||
|
}
|
||||||
|
|
||||||
|
VCMI_LIB_NAMESPACE_END
|
38
lib/battle/BattleStateInfoForRetreat.h
Normal file
38
lib/battle/BattleStateInfoForRetreat.h
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* BattleStateInfoForRetreat.h, part of VCMI engine
|
||||||
|
*
|
||||||
|
* Authors: listed in file AUTHORS in main folder
|
||||||
|
*
|
||||||
|
* License: GNU General Public License v2.0 or later
|
||||||
|
* Full text of license available in license.txt file, in main folder
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
VCMI_LIB_NAMESPACE_BEGIN
|
||||||
|
|
||||||
|
namespace battle
|
||||||
|
{
|
||||||
|
class Unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
class CGHeroInstance;
|
||||||
|
|
||||||
|
class DLL_LINKAGE BattleStateInfoForRetreat
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bool canFlee;
|
||||||
|
bool canSurrender;
|
||||||
|
bool isLastTurnBeforeDie;
|
||||||
|
ui8 ourSide;
|
||||||
|
std::vector<const battle::Unit *> ourStacks;
|
||||||
|
std::vector<const battle::Unit *> enemyStacks;
|
||||||
|
const CGHeroInstance * ourHero;
|
||||||
|
const CGHeroInstance * enemyHero;
|
||||||
|
|
||||||
|
BattleStateInfoForRetreat();
|
||||||
|
uint64_t getOurStrength() const;
|
||||||
|
uint64_t getEnemyStrength() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
VCMI_LIB_NAMESPACE_END
|
Loading…
Reference in New Issue
Block a user