1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-03-17 20:58:07 +02:00

Battle is run and result is stored.

This commit is contained in:
Michał W. Urbańczyk 2011-09-29 11:24:15 +00:00
parent 96a5bdaa5b
commit 131b9d6e1a
8 changed files with 203 additions and 47 deletions

View File

@ -1,3 +1,128 @@
#include "Client.h"
#include "../lib/Connection.h"
#include "../CThreadHelper.h"
#include "../lib/CGameState.h"
#include "../lib/BattleAction.h"
#include "../lib/CGameInterface.h"
#include "CheckTime.h"
#define NOT_LIB
#include "../lib/RegisterTypes.cpp"
template <typename T> class CApplyOnCL;
class CBaseForCLApply
{
public:
virtual void applyOnClAfter(CClient *cl, void *pack) const =0;
virtual void applyOnClBefore(CClient *cl, void *pack) const =0;
virtual ~CBaseForCLApply(){}
template<typename U> static CBaseForCLApply *getApplier(const U * t=NULL)
{
return new CApplyOnCL<U>;
}
};
template <typename T> class CApplyOnCL : public CBaseForCLApply
{
public:
void applyOnClAfter(CClient *cl, void *pack) const
{
T *ptr = static_cast<T*>(pack);
ptr->applyCl(cl);
}
void applyOnClBefore(CClient *cl, void *pack) const
{
T *ptr = static_cast<T*>(pack);
ptr->applyFirstCl(cl);
}
};
static CApplier<CBaseForCLApply> *applier = NULL;
void CClient::run()
{
setThreadName(-1, "CClient::run");
try
{
CPack *pack = NULL;
while(!terminate)
{
pack = serv->retreivePack(); //get the package from the server
if (terminate)
{
delete pack;
pack = NULL;
break;
}
handlePack(pack);
pack = NULL;
}
}
catch (const std::exception& e)
{
tlog3 << "Lost connection to server, ending listening thread!\n";
tlog1 << e.what() << std::endl;
if(!terminate) //rethrow (-> boom!) only if closing connection was unexpected
{
tlog1 << "Something wrong, lost connection while game is still ongoing...\n";
throw;
}
}
}
void CClient::handlePack( CPack * pack )
{
CBaseForCLApply *apply = applier->apps[typeList.getTypeID(pack)]; //find the applier
if(apply)
{
apply->applyOnClBefore(this,pack);
tlog5 << "\tMade first apply on cl\n";
gs->apply(pack);
tlog5 << "\tApplied on gs\n";
apply->applyOnClAfter(this,pack);
tlog5 << "\tMade second apply on cl\n";
}
else
{
tlog1 << "Message cannot be applied, cannot find applier! TypeID " << typeList.getTypeID(pack) << std::endl;
}
delete pack;
}
void CClient::requestMoveFromAI(const CStack *s)
{
boost::thread(&CClient::requestMoveFromAIWorker, this, s);
}
void CClient::requestMoveFromAIWorker(const CStack *s)
{
BattleAction ba;
try
{
CheckTime timer("AI was thinking for ");
ba = ai->activeStack(s);
MakeAction temp_action(ba);
*serv << &temp_action;
}
catch(...)
{
tlog0 << "AI thrown an exception!\n";
}
}
CClient::CClient()
{
gs = NULL;
serv = NULL;
ai = NULL;
curbaction = NULL;
terminate = false;
applier = new CApplier<CBaseForCLApply>;
registerTypes2(*applier);
}

View File

@ -1,17 +1,25 @@
#pragma once
#include "../global.h"
class CGameState;
class CConnection;
struct CPack;
class CBattleGameInterface;
struct BattleAction;
class CStack;
class CClient/* : public IGameCallback*/
{
public:
bool terminate;
BattleAction *curbaction;
CGameState *gs;
CConnection *serv;
CClient()
{
CBattleGameInterface *ai;
}
CClient();
//void commitPackage(CPackForClient *) OVERRIDE {};
void run();
void handlePack( CPack * pack ); //applies the given pack and deletes it
void requestMoveFromAI(const CStack *s);
void requestMoveFromAIWorker(const CStack *s);
};

View File

@ -135,9 +135,11 @@
<ClCompile Include="BattleCallback.cpp" />
<ClCompile Include="Client.cpp" />
<ClCompile Include="main.cpp" />
<ClCompile Include="NetPacksRunner.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="BattleCallback.h" />
<ClInclude Include="CheckTime.h" />
<ClInclude Include="Client.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

View File

@ -81,10 +81,17 @@ int main(int argc, char** argv)
tlog0 << "Cl created\n";
CBattleCallback * cbc = new CBattleCallback(gs, color, &cl);
tlog0 << "Cbc created\n";
CBattleGameInterface *ai = CDynLibHandler::getNewBattleAI(battleAIName);
tlog0 << "AI created\n";
ai->init(cbc);
if(battleAIName.size())
{
cl.ai = CDynLibHandler::getNewBattleAI(battleAIName);
cl.ai->playerID = color;
tlog0 << "AI created\n";
cl.ai->init(cbc);
}
else
tlog0 << "Not loading AI, only simulation will be run\n";
tlog0 << cbc->battleGetAllStacks().size() << std::endl;
cl.run();
}
catch(std::exception &e)
{

View File

@ -240,7 +240,7 @@ CPack * CConnection::retreivePack()
boost::unique_lock<boost::mutex> lock(*rmx);
tlog5 << "Listening... ";
*this >> ret;
tlog5 << "\treceived server message of type " << typeid(*ret).name() << std::endl;
tlog5 << "\treceived message of type " << typeid(*ret).name() << std::endl;
return ret;
}

View File

@ -462,6 +462,16 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance *hero1, const CGHer
{
CSaveFile resultFile("result.vdrst");
resultFile << *battleResult.data;
int casualtiesPoints = 0;
tlog0 << boost::format("Winner side %d\nWinner casualties:\n") % battleResult.data->winner;
for(std::map<ui32,si32>::const_iterator i = battleResult.data->casualties[battleResult.data->winner].begin(); i != battleResult.data->casualties[battleResult.data->winner].end(); i++)
{
const CCreature *c = VLC->creh->creatures[i->first];
tlog0 << boost::format("\t* %d of %s\n") % i->second % c->namePl;
casualtiesPoints = c->AIValue * i->second;
}
tlog0 << boost::format("Total causalties points: %d\n") % casualtiesPoints;
return;
}
@ -626,17 +636,12 @@ void CGameHandler::handleConnection(std::set<int> players, CConnection &c)
{
while(1)//server should never shut connection first //was: while(!end2)
{
{
boost::unique_lock<boost::mutex> lock(*c.rmx);
c >> pack; //get the package
tlog5 << "Received client message of type " << typeid(*pack).name() << std::endl;
}
pack = c.retreivePack();
int packType = typeList.getTypeID(pack); //get the id of type
CBaseForGHApply *apply = applier->apps[packType]; //and appropriae applier object
if(packType != typeList.getTypeID<QueryReply>() &&
(packType != typeList.getTypeID<ArrangeStacks>() || !isAllowedArrangePack((ArrangeStacks*)pack)) && // for dialogs like garrison
states[getCurrentPlayer()].queries.size())
if(packType != typeList.getTypeID<QueryReply>()
&&(packType != typeList.getTypeID<ArrangeStacks>() || !isAllowedArrangePack((ArrangeStacks*)pack)) // for dialogs like garrison
&& vstd::contains(states.players, getCurrentPlayer()) && states[getCurrentPlayer()].queries.size())
{
complain("Answer the query before attempting any further actions!");
PackageApplied applied;
@ -1997,13 +2002,7 @@ void CGameHandler::save( const std::string &fname )
void CGameHandler::close()
{
tlog0 << "We have been requested to close.\n";
if(gs->initialOpts->mode == StartInfo::DUEL)
{
exit(0);
}
tlog0 << "We have been requested to close.\n";
//BOOST_FOREACH(CConnection *cc, conns)
// if(cc && cc->socket && cc->socket->is_open())
// cc->socket->close();

View File

@ -501,23 +501,14 @@ void CVCMIServer::loadGame()
void CVCMIServer::startDuel(const std::string &battle, const std::string &leftAI, const std::string &rightAI)
{
//we need three connections
CConnection *conns[1] = {0};
for (int i = 0; i < 1 ; i++)
CConnection *conns[3] = {0};
for (int i = 0; i < 3 ; i++)
{
boost::system::error_code error;
//boost::system::error_code error;
tlog0<<"Listening for connections at port " << acceptor->local_endpoint().port() << std::endl;
tcp::socket * s = new tcp::socket(acceptor->get_io_service());
boost::thread acc(boost::bind(vaccept,acceptor,s,&error));
// sr->setToTrueAndNotify();
// delete mr;
acc.join();
//tcp::socket * s = new tcp::socket(acceptor->get_io_service());
//acceptor->accept(*s, error);
acceptor->accept(*s, error);
if (error)
{
@ -537,26 +528,39 @@ void CVCMIServer::startDuel(const std::string &battle, const std::string &leftAI
si.mode = StartInfo::DUEL;
si.mapname = battle;
tlog0 << "Preparing gh!\n";
CGameHandler *gh = new CGameHandler();
gh->init(&si,std::time(NULL));
BOOST_FOREACH(CConnection *c, conns)
{
ui8 player = gh->conns.size();
tlog0 << boost::format("Preparing connection %d!\n") % (int)player;
c->addStdVecItems(gh->gs, VLC);
gh->connections[gh->conns.size()] = c;
gh->connections[player] = c;
gh->conns.insert(c);
gh->states.addPlayer(player);
*c << si;
std::set<int> pom;
pom.insert(player);
boost::thread(boost::bind(&CGameHandler::handleConnection,gh,pom,boost::ref(*c)));
}
tlog0 << boost::format("Sending start info to connections!\n");
*gh->connections[0] << leftAI << ui8(0);
//*gh->connections[1] << rightAI << ui8(1);
//*gh->connections[2] << std::string() << ui8(254);
*gh->connections[1] << rightAI << ui8(1);
*gh->connections[2] << std::string() << ui8(254);
tlog0 << "Starting battle!\n";
gh->runBattle();
tlog0 << "Battle over!\n";
delNull(gh);
tlog0 << "Removed gh!\n";
boost::this_thread::sleep(boost::posix_time::milliseconds(1000));
tlog0 << "Dying...\n";
exit(0);
}

View File

@ -1,6 +1,17 @@
bin_PROGRAMS = odpalarka
odpalarka_LDADD = $(top_builddir)/lib/libvcmi.la
odpalarka_CXXFLAGS = @SDL_CXXFLAGS@
odpalarka_LDFLAGS = -L$(top_builddir)/lib
odpalarka_SOURCES = main.cpp
bin_PROGRAMS = vcmiserver
vcmiserver_LDADD = $(top_builddir)/lib/libvcmi.la
vcmiserver_CXXFLAGS = @SDL_CXXFLAGS@
vcmiserver_LDFLAGS = -L$(top_builddir)/lib
vcmiserver_SOURCES = \
../CConsoleHandler.cpp \
../CConsoleHandler.h \
../CThreadHelper.cpp \
../CThreadHelper.h \
CGameHandler.cpp \
CGameHandler.h \
CVCMIServer.cpp \
CVCMIServer.h \
NetPacksServer.cpp \
stdafx.cpp \
stdafx.h