initial commit, lordsawar source, slightly modified
[lordsawar] / src / AI_Diplomacy.cpp
1 //  Copyright (C) 2007, 2008, 2009 Ben Asselstine
2 //
3 //  This program is free software; you can redistribute it and/or modify
4 //  it under the terms of the GNU General Public License as published by
5 //  the Free Software Foundation; either version 3 of the License, or
6 //  (at your option) any later version.
7 //
8 //  This program is distributed in the hope that it will be useful,
9 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 //  GNU Library General Public License for more details.
12 //
13 //  You should have received a copy of the GNU General Public License
14 //  along with this program; if not, write to the Free Software
15 //  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 
16 //  02110-1301, USA.
17
18 #include <iostream>
19 #include "AI_Diplomacy.h"
20 #include "player.h"
21 #include "playerlist.h"
22 #include "citylist.h"
23 #include "history.h"
24 #include "game.h"
25 #include "GameScenarioOptions.h"
26 #include "city.h"
27
28 using namespace std;
29
30 #define debug(x) {cerr<<__FILE__<<": "<<__LINE__<<": "<<x<<flush<<endl;}
31 //#define debug(x)
32
33 AI_Diplomacy* AI_Diplomacy::instance = 0;
34
35 AI_Diplomacy::AI_Diplomacy(Player *owner)
36 :d_owner(owner)
37 {
38   instance = this;
39 }
40
41 AI_Diplomacy::~AI_Diplomacy()
42 {
43   instance = 0;
44 }
45
46 void AI_Diplomacy::considerCuspOfWar()
47 {
48   Playerlist *pl = Playerlist::getInstance();
49   
50   if (GameScenarioOptions::s_cusp_of_war &&
51       GameScenarioOptions::s_round == CUSP_OF_WAR_ROUND)
52   {
53     for (Playerlist::iterator it = pl->begin(); it != pl->end(); ++it)
54     {
55       Player *other = *it;
56       if (other->getType() == Player::HUMAN && !other->isDead() &&
57           d_owner->getDiplomaticState(other) != Player::AT_WAR)
58       {
59         d_owner->proposeDiplomacy (Player::PROPOSE_WAR, *it);
60         other->proposeDiplomacy (Player::PROPOSE_WAR, d_owner);
61         d_owner->declareDiplomacy (Player::AT_WAR, *it);
62   
63         History_DiplomacyWar *item = new History_DiplomacyWar();
64         item->fillData(other);
65         d_owner->addHistory(item);
66       }
67     }
68   }
69 }
70
71 void AI_Diplomacy::makeFriendsAndEnemies()
72 {
73   // Declare war with enemies, make peace with friends
74   // according to their diplomatic scores
75   Playerlist *pl = Playerlist::getInstance();
76   for (Playerlist::iterator it = pl->begin(); it != pl->end(); it++)
77     {
78       if (pl->getNeutral() == (*it))
79         continue;
80       if ((*it)->isDead())
81         continue;
82       if ((*it) == d_owner)
83         continue;
84       if (d_owner->getDiplomaticState(*it) != Player::AT_WAR)
85         {
86           if (d_owner->getDiplomaticScore (*it) < DIPLOMACY_MIN_SCORE + 2)
87             d_owner->proposeDiplomacy (Player::PROPOSE_WAR , *it);
88         }
89       else if (d_owner->getDiplomaticState(*it) != Player::AT_PEACE)
90         {
91           if (d_owner->getDiplomaticScore (*it) > DIPLOMACY_MAX_SCORE - 2)
92             d_owner->proposeDiplomacy (Player::PROPOSE_PEACE, *it);
93         }
94     }
95 }
96
97 void AI_Diplomacy::makeRequiredEnemies()
98 {
99   for (std::list<Player *>::iterator it = new_enemies.begin();
100        it != new_enemies.end(); it++)
101     d_owner->proposeDiplomacy (Player::PROPOSE_WAR , *it);
102 }
103
104 void AI_Diplomacy::neutralsDwindlingNeedFirstEnemy()
105 {
106   Playerlist *pl = Playerlist::getInstance();
107   // find a close player if neutral cities are getting low
108   Citylist *cl = Citylist::getInstance();
109   int target_level = (int)((float)cl->size() * (float) 0.06);
110   target_level++;
111   bool at_war = false;
112   guint32 neutral_cities = cl->countCities(pl->getNeutral());
113   if (neutral_cities && (int)neutral_cities > target_level)
114     {
115       //Pick a new opponent if we don't already have one.
116       for (Playerlist::iterator it = pl->begin(); it != pl->end(); it++)
117         {
118           if (pl->getNeutral() == (*it))
119             continue;
120           if ((*it)->isDead())
121             continue;
122           if ((*it) == d_owner)
123             continue;
124           if (d_owner->getDiplomaticState(*it) != Player::AT_WAR)
125             at_war = true;
126         }
127       if (at_war == false)
128         {
129           // not at war?  great.  let's pick a player to attack.
130           City *first_city = cl->getFirstCity(d_owner);
131           if (first_city)
132             {
133               City *c;
134               c = cl->getNearestForeignCity(first_city->getPos());
135               if (c)
136                 d_owner->proposeDiplomacy(Player::PROPOSE_WAR, c->getOwner());
137             }
138         }
139     }
140 }
141
142 void AI_Diplomacy::gangUpOnTheBully()
143 {
144   Playerlist *pl = Playerlist::getInstance();
145   Citylist *cl = Citylist::getInstance();
146   // declare war with the strong player.
147   // declare peace with every other.
148   int target_level = (int)((float)cl->size() * (float)0.35);
149   if (pl->countPlayersAlive() <  MAX_PLAYERS / 2)
150     return;
151   for (Playerlist::iterator it = pl->begin(); it != pl->end(); it++)
152     {
153       if (pl->getNeutral() == (*it))
154         continue;
155       if ((*it)->isDead())
156         continue;
157       if ((*it) == d_owner)
158         continue;
159       if (cl->countCities(*it) > target_level && pl->countPlayersAlive() > 4)
160         {
161           if (d_owner->getDiplomaticState(*it) != Player::AT_WAR)
162             d_owner->proposeDiplomacy(Player::PROPOSE_WAR, *it);
163           for (Playerlist::iterator pit = pl->begin(); pit != pl->end(); pit++)
164             {
165               if (pl->getNeutral() == (*pit))
166                 continue;
167               if ((*pit)->isDead())
168                 continue;
169               if ((*pit) == d_owner)
170                 continue;
171               if ((*pit) == *it)
172                 continue;
173               if ((*pit)->getType() == Player::HUMAN)
174                 continue;
175               if (d_owner->getDiplomaticState(*pit) != Player::AT_PEACE)
176                 d_owner->declareDiplomacy(Player::AT_PEACE, *pit);
177             }
178         }
179     }
180 }
181
182 void AI_Diplomacy::makeProposals()
183 {
184   makeFriendsAndEnemies();
185   makeRequiredEnemies();
186   neutralsDwindlingNeedFirstEnemy();
187   gangUpOnTheBully();
188 }
189
190 void AI_Diplomacy::needNewEnemy(Player *player)
191 {
192   new_enemies.push_back(player);
193 }
194 // End of file