Updated Glossario.tex
[GoMoku3D.git] / src / core / GameMatrix.cpp
blob260b809fda6fa8b0db351c012da72c960de131d2
1 /********************************************************************
3 * Copyright (C) 2008 Daniele Battaglia
5 * This file is part of GoMoku3D.
7 * GoMoku3D is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
12 * GoMoku3D is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with GoMoku3D. If not, see <http://www.gnu.org/licenses/>.
20 *******************************************************************/
22 #include <QtGlobal>
23 #include <QVector>
25 #include "GameMatrix.h"
27 const int GameMatrix::EmptyPoint = -1;
29 GameMatrix *GameMatrix::_instance = 0;
31 GameMatrix::GameMatrix(int d1, int d2, int numPlayers)
33 _d1 = d1;
34 _d2 = d2;
36 for (int i = 0; i < numPlayers; i++) {
37 _lastRound.append(Point());
40 int matrixSize = (d1 * d2) * (d1 * d2) * (d1 * d2);
41 _matrix = new int[matrixSize];
42 for (int i = 0; i < matrixSize; i++) {
43 _matrix[i] = EmptyPoint;
46 _freeCounter = matrixSize;
49 GameMatrix::~GameMatrix()
51 delete _matrix;
54 GameMatrix *GameMatrix::create(int d1, int d2, int numPlayers)
56 _instance = new GameMatrix(d1, d2, numPlayers);
57 return _instance;
60 void GameMatrix::destroy()
62 if (_instance != 0) {
63 delete _instance;
64 _instance = 0;
66 return;
69 GameMatrix *GameMatrix::instance()
71 return _instance;
74 bool GameMatrix::check(Point point) const
76 return point.isValid() && elementAt(point) == EmptyPoint;
79 bool GameMatrix::add(Move move)
81 _lastRound.removeLast();
82 _lastRound.prepend(move.point());
83 _freeCounter--;
84 int pos = move.point().x() * (_d1 * _d2) * (_d1 * _d2) + move.point().y() * (_d1 * _d2) + move.point().z();
85 _matrix[pos] = move.playerId();
87 for (int j = 0; j < 3; j++) {
88 QVector<int> coeff(3,0);
89 coeff[j] = 1;
90 Point base = move.point();
92 int start = qMax(0, base.x() * coeff[0] + base.y() * coeff[1] + base.z() * coeff[2] - _d1 + 1);
93 bool outOfBounds = false;
95 while (!outOfBounds && start <= base.x() * coeff[0] + base.y() * coeff[1] + base.z() * coeff[2]) {
96 int i = 0;
97 bool valid = true;
98 while (valid && i < _d1) {
99 int p_x = move.point().x() * (coeff[1] + coeff[2]) + coeff[0] * (start + i);
100 int p_y = move.point().y() * (coeff[0] + coeff[2]) + coeff[1] * (start + i);
101 int p_z = move.point().z() * (coeff[0] + coeff[1]) + coeff[2] * (start + i);
102 int id = elementAt(p_x, p_y, p_z);
104 if (id == move.playerId()) {
105 i++;
107 else {
108 valid = false;
109 if (id != -2) {
110 start++;
112 else {
113 outOfBounds = true;
117 if (i == _d1) {
118 return true;
123 if (_d2 != 3) {
124 return false;
127 QSet<Point> set;
128 extractCC(move.point(), move.playerId(), set);
130 Point e;
131 int minX = _d1 * _d2;
132 int maxX = -1;
133 int minY = minX;
134 int maxY = maxX;
135 int minZ = minX;
136 int maxZ = maxX;
138 foreach (e, set) {
139 minX = qMin(minX, e.x());
140 minY = qMin(minY, e.y());
141 minZ = qMin(minZ, e.z());
142 maxX = qMax(maxX, e.x());
143 maxY = qMax(maxY, e.y());
144 maxZ = qMax(maxZ, e.z());
146 return (minX == 0 && maxX == _d1 * _d2 -1) || (minY == 0 && maxY == _d1 * _d2 -1) || (minZ == 0 && maxZ == _d1 * _d2 -1);
149 void GameMatrix::clear(Point point)
151 if (elementAt(point) != EmptyPoint) {
152 _freeCounter++;
153 int pos = point.x() * (_d1 * _d2) * (_d1 * _d2) + point.y() * (_d1 * _d2) + point.z();
154 _matrix[pos] = EmptyPoint;
156 return;
159 int GameMatrix::elementAt(int x, int y, int z) const
161 if (Point(x, y, z).isValid()) {
162 int pos = x * (_d1 * _d2) * (_d1 * _d2) + y * (_d1 * _d2) + z;
163 return _matrix[pos];
165 return -2;
168 int GameMatrix::elementAt(Point point) const
170 return elementAt(point.x(), point.y(), point.z());
173 bool GameMatrix::isFull() const
175 return _freeCounter == 0;
178 int GameMatrix::numberOfPlayers() const
180 return _lastRound.size();
183 void GameMatrix::setLastRound(QList<Point> round)
185 _lastRound = round;
186 return;
189 void GameMatrix::extractCC(Point p, int id, QSet<Point> &set)
191 set.insert(p);
193 QList<Point> adjacent;
194 adjacent.append(Point(p.x() - 1, p.y(), p.z()));
195 adjacent.append(Point(p.x() + 1, p.y(), p.z()));
196 adjacent.append(Point(p.x(), p.y() - 1, p.z()));
197 adjacent.append(Point(p.x(), p.y() + 1, p.z()));
198 adjacent.append(Point(p.x(), p.y(), p.z() - 1));
199 adjacent.append(Point(p.x(), p.y(), p.z() + 1));
201 Point e;
203 foreach (e, adjacent) {
204 if (id == elementAt(e) && set.find(e) == set.end()) {
205 extractCC(e, id, set);
208 return;
211 int GameMatrix::d1() const
213 return _d1;
216 int GameMatrix::d2() const
218 return _d2;