1 /* This file is part of KsirK.
2    Copyright (C) 2002-2007 Gael de Chalendar <kleag@free.fr>
3 
4    KsirK is free software; you can redistribute it and/or
5    modify it under the terms of the GNU General Public
6    License as published by the Free Software Foundation, either version 2
7    of the License, or (at your option) any later version.
8 
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    General Public License for more details.
13 
14    You should have received a copy of the GNU General Public License
15    along with this program; if not, write to the Free Software
16    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17    02110-1301, USA
18 */
19 
20 #ifndef AIPLAYER_H
21 #define AIPLAYER_H
22 
23 #include "GameLogic/gameautomaton.h"
24 #include "GameLogic/player.h"
25 #include "GameLogic/country.h"
26 
27 #include <QThread>
28 
29 namespace Ksirk
30 {
31 
32 namespace GameLogic
33 {
34 
35 class Nationality;
36 class ONU;
37 class AIPlayerIO;
38 class GameAutomaton;
39 
40 /**
41   * This class represents a computer player. It holds all strategic routines.
42   * @author Gael de Chalendar (aka Kleag)
43   */
44 class AIPlayer : public Player
45 {
46 Q_OBJECT
47 
48 public:
49   /**
50     * Constructor with simple initializations
51     */
52   explicit AIPlayer(
53           const QString & nomPlayer, unsigned int nbArmies,
54           Nationality * myNation,  PlayersArray& players, ONU* world,
55           GameAutomaton* game );
56 
57   /** Default destructor. */
58   ~AIPlayer() override;
59 
60   /**
61     * The idendification of the player. Overwrite this in
62     * classes inherting KPlayer to run time identify them.
63     *
64     * @return 2 for this class.
65   */
rtti()66   int rtti() const override {return 2;}
67 
68   /**
69     * Returns true (an AIPlayer is an AI)
70     */
71   bool isAI() const override;
72 
73     /** set stopMe to true in order for the run method to return */
74   void stop();
75 
76   /**
77     * Saves this AI player as XML. Used in game saving.
78     * @param xmlStream The stream on which to write the XML
79     */
80   void saveXml(QTextStream& xmlStream) override;
81 
isRunning()82   bool isRunning () const {return m_thread.isRunning();}
83 
84 public Q_SLOTS:
85   void start ( QThread::Priority priority = QThread::InheritPriority ) {m_thread.start(priority);}
86 
87 protected:
88   /**
89     * This function is called whenever the player should choose an action
90     * (attack, defense, etc.). It has the responsibility to choose the correct
91     * action depending on the state of the game.
92     */
93   void actionChoice(GameLogic::GameAutomaton::GameState state) override;
94 
95   /** Returns a pair of countries where the attacker have enough armies to
96     * attack and the defender is a ennemy neighbour of the attacker */
97   virtual QPair< const Country*, const Country* > chooseBelligerant();
98 
99   /**
100     * Chooses the next action. In the current basic setting, chooses at random
101     * between the three possibilities. For each, chooses randomly the
102     * parameters.If the randomly chosen parameters end by an impossible
103     * action, continue with next player.
104     */
105   virtual void chooseAttackMoveArmiesOrNextPlayer();
106 
107   /**
108     * Chooses a country to receive a new army in dotation
109     */
110   virtual Country* chooseReceivingCountry();
111 
112   /**
113     * chooses to continue invasion with a certain amount of armies or to stop it
114     */
115   virtual void chooseInvasionAction();
116 
117   /**
118     * make all what is necessary to prepare and launch an attack
119     * @return true if was able to prepare an attack ; false otherwise
120     */
121   bool attackAction();
122 
123   /**
124     * makes all what is necessary to prepare and start the moving of armies
125     */
126   virtual bool moveArmiesAction();
127 
128   /**
129     * makes what is necessary to finish my turn
130     */
131   void nextPlayerAction();
132 
133 protected: // Private attributes
134   class MyThread: public QThread
135   {
136   protected:
137     void run () override;
138 
139   public:
MyThread(AIPlayer & p)140     explicit MyThread(AIPlayer& p) : me(p) {}
setStopMe(bool value)141     void setStopMe ( bool value ) { stopMe = value; }
142   private:
143     /** indicates to the thread if the run method should return */
144     bool stopMe;
145     AIPlayer& me;
146   };
147 
148   AIPlayerIO* aiPlayerIO();
149 
150 /**
151     * Pointer to the players. Information about them is necessary decide of
152     * a strategy
153     */
154   PlayersArray& allPlayers;
155 
156   /**
157     * Pointer to the World to consult it in order to decide the actions
158     */
159   ONU* m_world;
160 
161   /**
162     * a pointer to the game. Necessary to be able to access the number of
163     * attackers, etc. This solution is not very pretty... but an important
164     * architectural change should be done to avoid it (@todo).
165     */
166   GameAutomaton* m_game;
167 
168  /**
169    * a pointer to the game attribute defenseAuto
170    *
171    */
172  // GameAutomaton* m_defenseAuto;
173 
174   /** pointers to the source and target country of an attack */
175   const Country* m_src;
176   const Country* m_dest;
177 
178   /** number of armies to move during an invasion or an end of turn moving */
179   unsigned int m_toMove;
180 
181   bool m_hasVoted;
182   bool m_actionWaitingStart;
183 
184   MyThread m_thread;
185 
186 private: // Private methods
187   /**
188     * chooses whether to defend with one or two armies. Always chooses the maximum possible
189     */
190   void chooseDefenseAction();
191 
192   /**
193     * Takes the decision to recycle armies or not
194     */
195   void chooseWetherToRecycle();
196 
197   /**
198     * chooses a country where to place a new army
199     */
200   void placeArmiesAction();
201 
202   /** Makes the choice of nb armies to move during an invasion or an end of turn moving */
203   void chooseNbToMoveOrStop();
204 
205   /** Starts the timer of this player that will make it "think" all 200 ms. */
206   void run();
207 
208   void requestAck();
209 };
210 
211 } // closing namespace GameLogic
212 } // closing namespace Ksirk
213 #endif
214 
215