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