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 *******************************************************************/
25 #include "GameMatrix.h"
27 const int GameMatrix::EmptyPoint
= -1;
29 GameMatrix
*GameMatrix::_instance
= 0;
31 GameMatrix::GameMatrix(int d1
, int d2
, int numPlayers
)
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()
54 GameMatrix
*GameMatrix::create(int d1
, int d2
, int numPlayers
)
56 _instance
= new GameMatrix(d1
, d2
, numPlayers
);
60 void GameMatrix::destroy()
69 GameMatrix
*GameMatrix::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());
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);
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]) {
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()) {
128 extractCC(move
.point(), move
.playerId(), set
);
131 int minX
= _d1
* _d2
;
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
) {
153 int pos
= point
.x() * (_d1
* _d2
) * (_d1
* _d2
) + point
.y() * (_d1
* _d2
) + point
.z();
154 _matrix
[pos
] = EmptyPoint
;
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
;
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
)
189 void GameMatrix::extractCC(Point p
, int id
, QSet
<Point
> &set
)
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));
203 foreach (e
, adjacent
) {
204 if (id
== elementAt(e
) && set
.find(e
) == set
.end()) {
205 extractCC(e
, id
, set
);
211 int GameMatrix::d1() const
216 int GameMatrix::d2() const