File indexing completed on 2024-05-19 07:52:01
0001 /* 0002 SPDX-FileCopyrightText: 2012 Ian Wadham <iandw.au@gmail.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #ifndef AI_BOX_H 0008 #define AI_BOX_H 0009 0010 #include "ai_globals.h" // Include Player enum. 0011 0012 #include <QObject> 0013 #include <QList> 0014 0015 /** 0016 * Class AI_Box 0017 * 0018 * @short The Box AI algorithms 0019 */ 0020 0021 // Minimum and maximum size of cube box. Must be consistent with settings.ui. 0022 const int minSide = 3; 0023 const int maxSide = 15; 0024 0025 class AI_Box : public QObject 0026 { 0027 Q_OBJECT 0028 public: 0029 /** 0030 * The KJumpingCube AI_Box constructor. 0031 */ 0032 explicit AI_Box (QObject * parent = nullptr, int side = 5); 0033 ~AI_Box() override; 0034 0035 int side() const { return m_side; } 0036 Player owner (int index) const 0037 { return (((index >= 0) && (index < m_nCubes)) ? 0038 m_owners [index] : Nobody); } 0039 int value (int index) const 0040 { return (((index >= 0) && (index < m_nCubes)) ? 0041 m_values [index] : 1); } 0042 int maxValue (int index) const 0043 { return (((index >= 0) && (index < m_nCubes)) ? 0044 m_maxValues [index] : 4); } 0045 0046 // For performance, avoid setOwner() and setValue() in the game engine (AI). 0047 // However, they are good to use when loading a saved game, for example. 0048 void setOwner (int index, Player owner) 0049 { if ((index >= 0) && (index < m_nCubes) && 0050 (owner >= Nobody) && (owner <= Two)) { 0051 if (owner != m_owners [index]) { 0052 m_cubesToWin [m_owners [index]] ++; 0053 m_cubesToWin [owner] --; 0054 } 0055 m_owners [index] = owner; 0056 } 0057 } 0058 void setValue (int index, int value) 0059 { if ((index >= 0) && (index < m_nCubes) && 0060 (value >= 1)) { 0061 m_values [index] = value; 0062 } 0063 } 0064 0065 // This struct is passed to doMove() and is used to store 0066 // everything that is needed by undoMove() to actually undo it. 0067 struct MoveUndodata { 0068 Player oldPlayer; // The player previously to move in the position 0069 int oldCubesToWin[3]; 0070 quint16 changedCubes[maxSide * maxSide]; // 8 bits index, 4 bits owner and 4 bits value 0071 // end with 0xffff 0072 }; 0073 0074 bool doMove (Player player, int index, 0075 MoveUndodata * undodata = nullptr, QList<int> * steps = nullptr); 0076 void undoMove (MoveUndodata * undodata); 0077 #if AILog > 0 0078 void printBox(); 0079 #endif 0080 0081 void copyPosition (Player player, bool isAI, int index); 0082 bool undoPosition (Player & player, bool & isAI, int & index); 0083 bool undoPosition (Player & player); 0084 bool redoPosition (Player & player, bool & isAI, int & index); 0085 void initPosition (const AI_Box * box, Player player, bool isAI); 0086 0087 void clear(); 0088 0089 protected: 0090 int m_side; 0091 int m_nCubes; 0092 Player * m_owners; 0093 int * m_values; 0094 int * m_maxValues; 0095 int * m_neighbors; 0096 0097 void resizeBox (int side); 0098 0099 private: 0100 typedef struct { 0101 Player player; 0102 bool isAI; 0103 int index; 0104 int nCubes; 0105 Player * owners; 0106 int * values; 0107 } Position; 0108 0109 int m_cubesToWin [3]; 0110 int * m_stack; 0111 int m_stackPtr; 0112 0113 QList<Position *> m_undoList; 0114 int m_undoIndex; 0115 int m_redoLimit; 0116 0117 void indexNeighbors(); 0118 0119 void save (Position * position, Player player, bool isAI); 0120 void restore (Position * position); 0121 void discard (Position * position); 0122 Position * emptyPosition (int nCubes); 0123 void createBox (int side); 0124 void destroyBox(); 0125 0126 QObject * m_parent; // IDW test. 0127 }; 0128 0129 #endif // AI_BOX_H