File indexing completed on 2024-11-24 03:43:16
0001 /******************************************************************* 0002 * 0003 * Copyright 2007 Aron Boström <c02ab@efd.lth.se> 0004 * 0005 * Bovo is free software; you can redistribute it and/or modify 0006 * it under the terms of the GNU General Public License as published by 0007 * the Free Software Foundation; either version 2, or (at your option) 0008 * any later version. 0009 * 0010 * Bovo is distributed in the hope that it will be useful, 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0013 * GNU General Public License for more details. 0014 * 0015 * You should have received a copy of the GNU General Public License 0016 * along with Bovo; see the file COPYING. If not, write to 0017 * the Free Software Foundation, 51 Franklin Street, Fifth Floor, 0018 * Boston, MA 02110-1301, USA. 0019 * 0020 ********************************************************************/ 0021 0022 /** 0023 * @file file declaring the class AiBoard, which in fact is the AI 0024 */ 0025 0026 #ifndef BOVO_AIBOARD_H 0027 #define BOVO_AIBOARD_H 0028 0029 #include <KGameDifficulty> 0030 0031 #include "common.h" 0032 0033 using namespace bovo; 0034 0035 /** namespace for game engine */ 0036 namespace bovo 0037 { 0038 class Coord; 0039 class Dimension; 0040 class Move; 0041 } /* namespace bovo */ 0042 0043 /** namespace for AI stuff */ 0044 namespace ai 0045 { 0046 0047 class AiSquare; 0048 0049 /** 0050 * An AI player 0051 * 0052 * This class might be somewhat missnamed. It doesn't just keep track of a 0053 * playing board on the behalf og the AI. It is the entire AI implementation. 0054 * it implements two algorithms to calculate best moves and it selects which 0055 * move to play. It also can tell if a move is a winning move, but it doesn't 0056 * track a history yet (but maybe it should?). 0057 * 0058 * It uses the standard stuff in common.h way to little. 0059 * 0060 * It is supposed to be slaughtered and split up in two, easing the 0061 * implementation of AdaptingAi (the great feature to come! =P ) 0062 * 0063 * Perhaps we want to use Qt4 rather than STL in most of these cases. When we 0064 * implement AdaptingAi we have to depend on Qt4 and/or ThreadWeaver anyways. 0065 * 0066 * @code 0067 * Dimension dimension(width, height); 0068 * AiBoard ai(dimension, Easy); 0069 * Coord move = getMoveFromPlayerEitherByNetworkOrGui(); 0070 * Coord aiMove = ai.move(move); 0071 * doSomethingWithAiMoveLikeDisplayingItInTheGui(aiMove); 0072 * @endcode 0073 */ 0074 class AiBoard 0075 { 0076 public: 0077 /** 0078 * @brief Constructs an AiBoard with width, height and Skill 0079 * @description Constructs a Board object with a specified width, height and 0080 * skill 0081 * @param width the width 0082 * @param height the height 0083 * @param skill the skill (difficulty level) the AI player will be playing with 0084 */ 0085 AiBoard(const usi width, const usi height, KGameDifficultyLevel::StandardLevel skill = KGameDifficultyLevel::Medium, Player player = O); 0086 0087 /** 0088 * @brief Constructs an AiBoard with width, height and Skill 0089 * @description Constructs a Board object with a specified width and height 0090 * specified by a Dimension and a skill 0091 * @param width the width 0092 * @param height the height 0093 * @param skill the skill (difficulty level) the AI player will be playing with 0094 */ 0095 explicit AiBoard(const Dimension &dimension, KGameDifficultyLevel::StandardLevel skill = KGameDifficultyLevel::Medium, Player player = O); 0096 0097 /** 0098 * @brief destructs this AiBoard 0099 * @description destructs this AiBoard object 0100 */ 0101 ~AiBoard(); 0102 0103 /** 0104 * @brief is a Coord empty or set? 0105 * @description tells whether a given Coord is marked as empty or 0106 * marked by a player 0107 * @throw outOfBounds when coord is not on playing board 0108 * @param coord Coord to check 0109 * @return @c true if coord is empty, @c false otherwise 0110 */ 0111 bool empty(const Coord &) const; 0112 0113 /** 0114 * @brief is a Coord empty or set? 0115 * @description tells whether a given Coord is marked as empty or 0116 * marked by a player 0117 * @throw outOfBounds when coord is not on playing board 0118 * @param x X-part of coordinate to check 0119 * @param y X-part of coordinate to check 0120 * @return @c true if coord is empty, @c false otherwise 0121 */ 0122 bool empty(const usi x, const usi y) const; 0123 0124 /** 0125 * @brief height of AiBoard 0126 * @description tells the number of rows in the playing board 0127 * @return the number of rows 0128 */ 0129 usi height() const; 0130 0131 /** 0132 * @brief get move from AI 0133 * @description get the move the AI wants to play 0134 * @return the move the AI wants to play 0135 */ 0136 Coord move(); 0137 0138 /** 0139 * @brief get move from AI 0140 * @description Feed the latest move from the player to the AI and get a 0141 * list of suggested AI moves in return. This should be a QList\<Coord>. 0142 * @param coord the move the player played his latest turn 0143 * @return the moves the AI suggest to play 0144 * @todo Implement! 0145 */ 0146 Coord *moves(); 0147 0148 /** 0149 * @brief the player occupying a Coord 0150 * @description tells which players occupies a certain square in the board 0151 * @param coord the square to check 0152 * @return @c X if player 1, @c O if player 2, @c No if empty 0153 * @throw outOfBounds if coord isn't on the playing board 0154 */ 0155 Player player(const Coord &) const; 0156 0157 /** 0158 * @brief the player occupying a Coord 0159 * @description tells which players occupies a certain square in the board 0160 * @param x the X-part of the Coord to check 0161 * @param y the Y-part of the Coord to check 0162 * @return @c X if player 1, @c O if player 2, @c No if empty 0163 * @throw outOfBounds if coord isn't on the playing board 0164 */ 0165 Player player(const usi x, const usi y) const; 0166 0167 /** 0168 * @brief set the player of a Coord 0169 * @description sets which players should occupy a certain square in the 0170 * playing board. Returns whether the game ends with this move (i.e. it 0171 * was the winning move). 0172 * @param move the Move to place 0173 * @return @c true if this move resulted in a Game Over, 0174 * @c false otherwise 0175 * @throw busy if coord was already occupied 0176 * @throw gameOver if game was already over 0177 * @throw notValidPlayer if player wasn't X or O 0178 */ 0179 bool setPlayer(const Move &move); 0180 0181 /** 0182 * @brief change Skill 0183 * @description changes the Skill (difficulty level) of the AI player 0184 */ 0185 void setSkill(KGameDifficultyLevel::StandardLevel skill); 0186 0187 /** 0188 * @brief width of Board 0189 * @description tells the number of columns in the playing board 0190 * @return the number of columns 0191 */ 0192 usi width() const; 0193 0194 private: 0195 /* Playing board property. */ 0196 AiSquare **m_board; 0197 0198 /* hasn't game really started? */ 0199 bool m_cleanBoard; 0200 0201 /* Dimension property of playing board. */ 0202 Dimension *m_dimension; 0203 0204 /* is Game Over? property */ 0205 bool m_gameover; 0206 0207 /* AI player property */ 0208 Player m_player; 0209 0210 /* AI Level property. */ 0211 KGameDifficultyLevel::StandardLevel m_skill; 0212 0213 /* Return the best-fitting coordinate according to the specs. 0214 * Use this when all the board has been given points. */ 0215 Coord evaluate() const; 0216 0217 /* returns, adds och sets points on a given square. */ 0218 uli points(const Coord &) const; 0219 void addPoints(const Coord &, const uli points); 0220 void setPoints(const Coord &, const uli points); 0221 0222 /* initialize this class */ 0223 void setup(); 0224 0225 /* Do the real calculation of points for a given square. 0226 * Player is the AI player you're optimizing. */ 0227 uli value(const Coord &, const usi player) const; 0228 0229 /* value2 performs a second evaluation in order to make out the tiny 0230 * differences that haven't been spotted yet. 0231 * Only run this when needed. */ 0232 uli value2(const Coord &) const; 0233 0234 /* is this move (coord) a winning move? */ 0235 bool win(const Coord &) const; 0236 0237 /* Marks all neighbour (5 squares in each 0238 * direction) as in need of a recalculation 0239 * of its points. */ 0240 void zero(const Coord &); 0241 }; 0242 0243 } /* namespace ai */ 0244 0245 #endif // BOVO_AIBOARD_H