File indexing completed on 2024-12-08 03:47:29
0001 /* This file is part of KsirK. 0002 Copyright (C) 2002-2007 Gael de Chalendar <kleag@free.fr> 0003 0004 KsirK is free software; you can redistribute it and/or 0005 modify it under the terms of the GNU General Public 0006 License as published by the Free Software Foundation, either version 2 0007 of the License, or (at your option) any later version. 0008 0009 This program is distributed in the hope that it will be useful, 0010 but WITHOUT ANY WARRANTY; without even the implied warranty of 0011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0012 General Public License for more details. 0013 0014 You should have received a copy of the GNU General Public License 0015 along with this program; if not, write to the Free Software 0016 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 0017 02110-1301, USA 0018 */ 0019 0020 #ifndef AIPLAYER_H 0021 #define AIPLAYER_H 0022 0023 #include "GameLogic/gameautomaton.h" 0024 #include "GameLogic/player.h" 0025 #include "GameLogic/country.h" 0026 0027 #include <QThread> 0028 0029 namespace Ksirk 0030 { 0031 0032 namespace GameLogic 0033 { 0034 0035 class Nationality; 0036 class ONU; 0037 class AIPlayerIO; 0038 class GameAutomaton; 0039 0040 /** 0041 * This class represents a computer player. It holds all strategic routines. 0042 * @author Gael de Chalendar (aka Kleag) 0043 */ 0044 class AIPlayer : public Player 0045 { 0046 Q_OBJECT 0047 0048 public: 0049 /** 0050 * Constructor with simple initializations 0051 */ 0052 explicit AIPlayer( 0053 const QString & nomPlayer, unsigned int nbArmies, 0054 Nationality * myNation, PlayersArray& players, ONU* world, 0055 GameAutomaton* game ); 0056 0057 /** Default destructor. */ 0058 ~AIPlayer() override; 0059 0060 /** 0061 * The idendification of the player. Overwrite this in 0062 * classes inherting KPlayer to run time identify them. 0063 * 0064 * @return 2 for this class. 0065 */ 0066 int rtti() const override {return 2;} 0067 0068 /** 0069 * Returns true (an AIPlayer is an AI) 0070 */ 0071 bool isAI() const override; 0072 0073 /** set stopMe to true in order for the run method to return */ 0074 void stop(); 0075 0076 /** 0077 * Saves this AI player as XML. Used in game saving. 0078 * @param xmlStream The stream on which to write the XML 0079 */ 0080 void saveXml(QTextStream& xmlStream) override; 0081 0082 bool isRunning () const {return m_thread.isRunning();} 0083 0084 public Q_SLOTS: 0085 void start ( QThread::Priority priority = QThread::InheritPriority ) {m_thread.start(priority);} 0086 0087 protected: 0088 /** 0089 * This function is called whenever the player should choose an action 0090 * (attack, defense, etc.). It has the responsibility to choose the correct 0091 * action depending on the state of the game. 0092 */ 0093 void actionChoice(GameLogic::GameAutomaton::GameState state) override; 0094 0095 /** Returns a pair of countries where the attacker have enough armies to 0096 * attack and the defender is a ennemy neighbour of the attacker */ 0097 virtual QPair< const Country*, const Country* > chooseBelligerant(); 0098 0099 /** 0100 * Chooses the next action. In the current basic setting, chooses at random 0101 * between the three possibilities. For each, chooses randomly the 0102 * parameters.If the randomly chosen parameters end by an impossible 0103 * action, continue with next player. 0104 */ 0105 virtual void chooseAttackMoveArmiesOrNextPlayer(); 0106 0107 /** 0108 * Chooses a country to receive a new army in dotation 0109 */ 0110 virtual Country* chooseReceivingCountry(); 0111 0112 /** 0113 * chooses to continue invasion with a certain amount of armies or to stop it 0114 */ 0115 virtual void chooseInvasionAction(); 0116 0117 /** 0118 * make all what is necessary to prepare and launch an attack 0119 * @return true if was able to prepare an attack ; false otherwise 0120 */ 0121 bool attackAction(); 0122 0123 /** 0124 * makes all what is necessary to prepare and start the moving of armies 0125 */ 0126 virtual bool moveArmiesAction(); 0127 0128 /** 0129 * makes what is necessary to finish my turn 0130 */ 0131 void nextPlayerAction(); 0132 0133 protected: // Private attributes 0134 class MyThread: public QThread 0135 { 0136 protected: 0137 void run () override; 0138 0139 public: 0140 explicit MyThread(AIPlayer& p) : me(p) {} 0141 void setStopMe ( bool value ) { stopMe = value; } 0142 private: 0143 /** indicates to the thread if the run method should return */ 0144 bool stopMe; 0145 AIPlayer& me; 0146 }; 0147 0148 AIPlayerIO* aiPlayerIO(); 0149 0150 /** 0151 * Pointer to the players. Information about them is necessary decide of 0152 * a strategy 0153 */ 0154 PlayersArray& allPlayers; 0155 0156 /** 0157 * Pointer to the World to consult it in order to decide the actions 0158 */ 0159 ONU* m_world; 0160 0161 /** 0162 * a pointer to the game. Necessary to be able to access the number of 0163 * attackers, etc. This solution is not very pretty... but an important 0164 * architectural change should be done to avoid it (@todo). 0165 */ 0166 GameAutomaton* m_game; 0167 0168 /** 0169 * a pointer to the game attribute defenseAuto 0170 * 0171 */ 0172 // GameAutomaton* m_defenseAuto; 0173 0174 /** pointers to the source and target country of an attack */ 0175 const Country* m_src; 0176 const Country* m_dest; 0177 0178 /** number of armies to move during an invasion or an end of turn moving */ 0179 unsigned int m_toMove; 0180 0181 bool m_hasVoted; 0182 bool m_actionWaitingStart; 0183 0184 MyThread m_thread; 0185 0186 private: // Private methods 0187 /** 0188 * chooses whether to defend with one or two armies. Always chooses the maximum possible 0189 */ 0190 void chooseDefenseAction(); 0191 0192 /** 0193 * Takes the decision to recycle armies or not 0194 */ 0195 void chooseWetherToRecycle(); 0196 0197 /** 0198 * chooses a country where to place a new army 0199 */ 0200 void placeArmiesAction(); 0201 0202 /** Makes the choice of nb armies to move during an invasion or an end of turn moving */ 0203 void chooseNbToMoveOrStop(); 0204 0205 /** Starts the timer of this player that will make it "think" all 200 ms. */ 0206 void run(); 0207 0208 void requestAck(); 0209 }; 0210 0211 } // closing namespace GameLogic 0212 } // closing namespace Ksirk 0213 #endif 0214