1/* ****************************************************************************
2 Copyright 2012 Ian Wadham <iandw.au@gmail.com>
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (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
12 GNU 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 Foundation, Inc.,
16 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17**************************************************************************** */
18#ifndef AI_BOX_H
19#define AI_BOX_H
20
21#include "ai_globals.h" // Include Player enum.
22
23#include <QObject>
24#include <QList>
25
26/**
27* Class AI_Box
28*
29* @short The Box AI algorithms
30*/
31
32// Minimum and maximum size of cube box. Must be consistent with settings.ui.
33const int minSide = 3;
34const int maxSide = 15;
35
36class AI_Box : public QObject
37{
38 Q_OBJECT
39public:
40 /**
41 * The KJumpingCube AI_Box constructor.
42 */
43 AI_Box (QObject * parent = 0, int side = 5);
44 virtual ~AI_Box();
45
46 int side() const { return m_side; }
47 Player owner (int index) const
48 { return (((index >= 0) && (index < m_nCubes)) ?
49 m_owners [index] : Nobody); }
50 int value (int index) const
51 { return (((index >= 0) && (index < m_nCubes)) ?
52 m_values [index] : 1); }
53 int maxValue (int index) const
54 { return (((index >= 0) && (index < m_nCubes)) ?
55 m_maxValues [index] : 4); }
56
57 // For performance, avoid setOwner() and setValue() in the game engine (AI).
58 // However, they are good to use when loading a saved game, for example.
59 void setOwner (int index, Player owner)
60 { if ((index >= 0) && (index < m_nCubes) &&
61 (owner >= Nobody) && (owner <= Two)) {
62 if (owner != m_owners [index]) {
63 m_cubesToWin [m_owners [index]] ++;
64 m_cubesToWin [owner] --;
65 }
66 m_owners [index] = owner;
67 }
68 }
69 void setValue (int index, int value)
70 { if ((index >= 0) && (index < m_nCubes) &&
71 (value >= 1)) {
72 m_values [index] = value;
73 }
74 }
75
76 // This struct is passed to doMove() and is used to store
77 // everything that is needed by undoMove() to actually undo it.
78 struct MoveUndodata {
79 Player oldPlayer; // The player previously to move in the position
80 int oldCubesToWin[3];
81 quint16 changedCubes[maxSide * maxSide]; // 8 bits index, 4 bits owner and 4 bits value
82 // end with 0xffff
83 };
84
85 bool doMove (Player player, int index,
86 MoveUndodata * undodata = 0, QList<int> * steps = 0);
87 void undoMove (MoveUndodata * undodata);
88#if AILog > 0
89 void printBox();
90#endif
91
92 void copyPosition (Player player, bool isAI, int index);
93 bool undoPosition (Player & player, bool & isAI, int & index);
94 bool undoPosition (Player & player);
95 bool redoPosition (Player & player, bool & isAI, int & index);
96 void initPosition (const AI_Box * box, Player player, bool isAI);
97
98 void clear();
99
100protected:
101 int m_side;
102 int m_nCubes;
103 Player * m_owners;
104 int * m_values;
105 int * m_maxValues;
106 int * m_neighbors;
107
108 void resizeBox (int side);
109
110private:
111 typedef struct {
112 Player player;
113 bool isAI;
114 int index;
115 int nCubes;
116 Player * owners;
117 int * values;
118 } Position;
119
120 int m_cubesToWin [3];
121 int * m_stack;
122 int m_stackPtr;
123
124 QList<Position *> m_undoList;
125 int m_undoIndex;
126 int m_redoLimit;
127
128 void indexNeighbors();
129
130 void save (Position * position, Player player, bool isAI);
131 void restore (Position * position);
132 void discard (Position * position);
133 Position * emptyPosition (int nCubes);
134 void createBox (int side);
135 void destroyBox();
136
137 QObject * m_parent; // IDW test.
138};
139
140#endif // AI_BOX_H
141