Auto-balance the number of AIs

If there are uneven the number of human players in each team
This commit is contained in:
Benau 2016-05-08 08:08:57 +08:00
parent 1af4853f40
commit bb01c83d6e
4 changed files with 58 additions and 34 deletions

View File

@ -49,6 +49,7 @@ SoccerAI::SoccerAI(AbstractKart *kart)
#endif
m_world = dynamic_cast<SoccerWorld*>(World::getWorld());
m_track = m_world->getTrack();
m_cur_team = m_world->getKartTeam(m_kart->getWorldKartId());
// Don't call our own setControllerName, since this will add a
// billboard showing 'AIBaseController' to the kart.
@ -75,25 +76,6 @@ void SoccerAI::reset()
AIBaseController::reset();
m_saving_ball = false;
if (race_manager->getNumPlayers() == 1)
{
// Same handle in SoccerWorld::createKart
if (race_manager->getKartInfo(0).getSoccerTeam() == SOCCER_TEAM_RED)
{
m_cur_team = (m_kart->getWorldKartId() % 2 == 0 ?
SOCCER_TEAM_BLUE : SOCCER_TEAM_RED);
}
else
{
m_cur_team = (m_kart->getWorldKartId() % 2 == 0 ?
SOCCER_TEAM_RED : SOCCER_TEAM_BLUE);
}
}
else
{
m_cur_team = (m_kart->getWorldKartId() % 2 == 0 ?
SOCCER_TEAM_BLUE : SOCCER_TEAM_RED);
}
} // reset
//-----------------------------------------------------------------------------

View File

@ -54,6 +54,8 @@ SoccerWorld::SoccerWorld() : WorldWithRank()
}
m_use_highscores = false;
m_red_ai = 0;
m_blue_ai = 0;
} // SoccerWorld
//-----------------------------------------------------------------------------
@ -355,22 +357,10 @@ AbstractKart *SoccerWorld::createKart(const std::string &kart_ident, int index,
if (kart_type == RaceManager::KT_AI)
{
if (race_manager->getNumPlayers() == 1)
{
// Make AI even when single player choose a different team
if (race_manager->getKartInfo(0).getSoccerTeam() == SOCCER_TEAM_RED)
{
team = (index % 2 == 0 ? SOCCER_TEAM_BLUE : SOCCER_TEAM_RED);
}
if (index < m_red_ai)
team = SOCCER_TEAM_RED;
else
{
team = (index % 2 == 0 ? SOCCER_TEAM_RED : SOCCER_TEAM_BLUE);
}
}
else
{
team = (index % 2 == 0 ? SOCCER_TEAM_BLUE : SOCCER_TEAM_RED);
}
team = SOCCER_TEAM_BLUE;
m_kart_team_map[index] = team;
}
else
@ -642,3 +632,44 @@ void SoccerWorld::resetBall()
m_ball->reset();
m_ball->getPhysicalObject()->reset();
} // resetBall
//-----------------------------------------------------------------------------
void SoccerWorld::setAITeam()
{
const int total_player = race_manager->getNumPlayers();
const int total_karts = race_manager->getNumberOfKarts();
// No AI
if ((total_karts - total_player) == 0) return;
int red_player = 0;
int blue_player = 0;
for (int i = 0; i < total_player; i++)
{
SoccerTeam team = race_manager->getKartInfo(i).getSoccerTeam();
assert(team != SOCCER_TEAM_NONE);
team == SOCCER_TEAM_BLUE ? blue_player++ : red_player++;
}
int avaliable_ai = total_karts - red_player - blue_player;
while (avaliable_ai > 0)
{
if ((m_red_ai + red_player) > (m_blue_ai + blue_player))
{
m_blue_ai++;
avaliable_ai--;
}
else if ((m_blue_ai + blue_player) > (m_red_ai + red_player))
{
m_red_ai++;
avaliable_ai--;
}
else if ((m_blue_ai + blue_player) == (m_red_ai + red_player))
{
blue_player > red_player ? m_red_ai++ : m_blue_ai++;
avaliable_ai--;
}
}
Log::debug("SoccerWorld","blue AI: %d red AI: %d", m_blue_ai, m_red_ai);
} // setAITeam

View File

@ -91,6 +91,9 @@ private:
int m_red_defender;
int m_blue_defender;
int m_red_ai;
int m_blue_ai;
/** Set the team for the karts */
void initKartList();
/** Function to init the locations of two goals on the polygon map */
@ -177,6 +180,8 @@ public:
{
return (team == SOCCER_TEAM_BLUE ? m_blue_defender : m_red_defender);
}
// ------------------------------------------------------------------------
void setAITeam();
}; // SoccerWorld

View File

@ -42,6 +42,7 @@
#include "karts/kart_properties_manager.hpp"
#include "modes/overworld.hpp"
#include "modes/profile_world.hpp"
#include "modes/soccer_world.hpp"
#include "network/network_config.hpp"
#include "physics/btKart.hpp"
#include "physics/physics.hpp"
@ -191,6 +192,11 @@ void World::init()
m_karts.push_back(ReplayPlay::get()->getGhostKart(k));
}
// Assign team of AIs for soccer mode before createKart
SoccerWorld* sw = dynamic_cast<SoccerWorld*>(this);
if (sw)
sw->setAITeam();
for(unsigned int i=0; i<num_karts; i++)
{
if (race_manager->getKartType(i) == RaceManager::KT_GHOST) continue;