initial commit, lordsawar source, slightly modified
[lordsawar] / src / AI_Diplomacy.cpp
diff --git a/src/AI_Diplomacy.cpp b/src/AI_Diplomacy.cpp
new file mode 100644 (file)
index 0000000..e2efeac
--- /dev/null
@@ -0,0 +1,194 @@
+//  Copyright (C) 2007, 2008, 2009 Ben Asselstine
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation; either version 3 of the License, or
+//  (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//  GNU Library General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 
+//  02110-1301, USA.
+
+#include <iostream>
+#include "AI_Diplomacy.h"
+#include "player.h"
+#include "playerlist.h"
+#include "citylist.h"
+#include "history.h"
+#include "game.h"
+#include "GameScenarioOptions.h"
+#include "city.h"
+
+using namespace std;
+
+#define debug(x) {cerr<<__FILE__<<": "<<__LINE__<<": "<<x<<flush<<endl;}
+//#define debug(x)
+
+AI_Diplomacy* AI_Diplomacy::instance = 0;
+
+AI_Diplomacy::AI_Diplomacy(Player *owner)
+:d_owner(owner)
+{
+  instance = this;
+}
+
+AI_Diplomacy::~AI_Diplomacy()
+{
+  instance = 0;
+}
+
+void AI_Diplomacy::considerCuspOfWar()
+{
+  Playerlist *pl = Playerlist::getInstance();
+  
+  if (GameScenarioOptions::s_cusp_of_war &&
+      GameScenarioOptions::s_round == CUSP_OF_WAR_ROUND)
+  {
+    for (Playerlist::iterator it = pl->begin(); it != pl->end(); ++it)
+    {
+      Player *other = *it;
+      if (other->getType() == Player::HUMAN && !other->isDead() &&
+          d_owner->getDiplomaticState(other) != Player::AT_WAR)
+      {
+        d_owner->proposeDiplomacy (Player::PROPOSE_WAR, *it);
+        other->proposeDiplomacy (Player::PROPOSE_WAR, d_owner);
+        d_owner->declareDiplomacy (Player::AT_WAR, *it);
+  
+        History_DiplomacyWar *item = new History_DiplomacyWar();
+        item->fillData(other);
+       d_owner->addHistory(item);
+      }
+    }
+  }
+}
+
+void AI_Diplomacy::makeFriendsAndEnemies()
+{
+  // Declare war with enemies, make peace with friends
+  // according to their diplomatic scores
+  Playerlist *pl = Playerlist::getInstance();
+  for (Playerlist::iterator it = pl->begin(); it != pl->end(); it++)
+    {
+      if (pl->getNeutral() == (*it))
+       continue;
+      if ((*it)->isDead())
+       continue;
+      if ((*it) == d_owner)
+       continue;
+      if (d_owner->getDiplomaticState(*it) != Player::AT_WAR)
+       {
+         if (d_owner->getDiplomaticScore (*it) < DIPLOMACY_MIN_SCORE + 2)
+           d_owner->proposeDiplomacy (Player::PROPOSE_WAR , *it);
+       }
+      else if (d_owner->getDiplomaticState(*it) != Player::AT_PEACE)
+       {
+         if (d_owner->getDiplomaticScore (*it) > DIPLOMACY_MAX_SCORE - 2)
+           d_owner->proposeDiplomacy (Player::PROPOSE_PEACE, *it);
+       }
+    }
+}
+
+void AI_Diplomacy::makeRequiredEnemies()
+{
+  for (std::list<Player *>::iterator it = new_enemies.begin();
+       it != new_enemies.end(); it++)
+    d_owner->proposeDiplomacy (Player::PROPOSE_WAR , *it);
+}
+
+void AI_Diplomacy::neutralsDwindlingNeedFirstEnemy()
+{
+  Playerlist *pl = Playerlist::getInstance();
+  // find a close player if neutral cities are getting low
+  Citylist *cl = Citylist::getInstance();
+  int target_level = (int)((float)cl->size() * (float) 0.06);
+  target_level++;
+  bool at_war = false;
+  guint32 neutral_cities = cl->countCities(pl->getNeutral());
+  if (neutral_cities && (int)neutral_cities > target_level)
+    {
+      //Pick a new opponent if we don't already have one.
+      for (Playerlist::iterator it = pl->begin(); it != pl->end(); it++)
+       {
+         if (pl->getNeutral() == (*it))
+           continue;
+         if ((*it)->isDead())
+           continue;
+         if ((*it) == d_owner)
+           continue;
+         if (d_owner->getDiplomaticState(*it) != Player::AT_WAR)
+           at_war = true;
+       }
+      if (at_war == false)
+       {
+         // not at war?  great.  let's pick a player to attack.
+         City *first_city = cl->getFirstCity(d_owner);
+         if (first_city)
+           {
+             City *c;
+             c = cl->getNearestForeignCity(first_city->getPos());
+             if (c)
+               d_owner->proposeDiplomacy(Player::PROPOSE_WAR, c->getOwner());
+           }
+       }
+    }
+}
+
+void AI_Diplomacy::gangUpOnTheBully()
+{
+  Playerlist *pl = Playerlist::getInstance();
+  Citylist *cl = Citylist::getInstance();
+  // declare war with the strong player.
+  // declare peace with every other.
+  int target_level = (int)((float)cl->size() * (float)0.35);
+  if (pl->countPlayersAlive() <  MAX_PLAYERS / 2)
+    return;
+  for (Playerlist::iterator it = pl->begin(); it != pl->end(); it++)
+    {
+      if (pl->getNeutral() == (*it))
+       continue;
+      if ((*it)->isDead())
+       continue;
+      if ((*it) == d_owner)
+       continue;
+      if (cl->countCities(*it) > target_level && pl->countPlayersAlive() > 4)
+       {
+         if (d_owner->getDiplomaticState(*it) != Player::AT_WAR)
+           d_owner->proposeDiplomacy(Player::PROPOSE_WAR, *it);
+         for (Playerlist::iterator pit = pl->begin(); pit != pl->end(); pit++)
+           {
+             if (pl->getNeutral() == (*pit))
+               continue;
+             if ((*pit)->isDead())
+               continue;
+             if ((*pit) == d_owner)
+               continue;
+             if ((*pit) == *it)
+               continue;
+             if ((*pit)->getType() == Player::HUMAN)
+               continue;
+             if (d_owner->getDiplomaticState(*pit) != Player::AT_PEACE)
+               d_owner->declareDiplomacy(Player::AT_PEACE, *pit);
+           }
+       }
+    }
+}
+
+void AI_Diplomacy::makeProposals()
+{
+  makeFriendsAndEnemies();
+  makeRequiredEnemies();
+  neutralsDwindlingNeedFirstEnemy();
+  gangUpOnTheBully();
+}
+
+void AI_Diplomacy::needNewEnemy(Player *player)
+{
+  new_enemies.push_back(player);
+}
+// End of file