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 Threat::Threat(ThreatSearchAI
*ai
)
28 _mat
= GameMatrix::instance();
31 _priority
= new Node
*[_d1
- 1];
32 for (int i
= 0; i
< _d1
- 1; i
++) {
39 for (int i
= 0; i
< _d1
- 1; i
++) {
45 void Threat::insert(Point point
)
47 for (int i
= 0; i
< _d1
; i
++) {
48 evalInsert(point
, i
, DIR_X
);
49 evalInsert(point
, i
, DIR_Y
);
50 evalInsert(point
, i
, DIR_Z
);
54 void Threat::scanFromMatrix()
57 for (int x
= 0; x
< dim
; x
++) {
58 for (int y
= 0; y
< dim
; y
++) {
59 for (int z
= 0; z
< dim
; z
++) {
60 Point key
= Point(x
, y
, z
);
62 int pri
= evalPriority(key
, DIR_X
);
64 QMap
<Point
, Node
*>::iterator it
= _x
.insert(key
, new Node(pri
, key
, DIR_X
));
65 insertInPriority(*it
);
68 pri
= evalPriority(key
, DIR_Y
);
70 QMap
<Point
, Node
*>::iterator it
= _y
.insert(key
, new Node(pri
, key
, DIR_Y
));
71 insertInPriority(*it
);
74 pri
= evalPriority(key
, DIR_Z
);
76 QMap
<Point
, Node
*>::iterator it
= _z
.insert(key
, new Node(pri
, key
, DIR_Z
));
77 insertInPriority(*it
);
86 void Threat::insertHook(Point p
)
90 void Threat::scanFromMatrixHook()
94 void Threat::evalInsert(Point p
, int index
, Direction dir
)
96 QMap
<Point
, Node
*> *map
= 0;
97 QVector
<int> coeff(3,0);
114 int start
= coeff
[0] * p
.x() + coeff
[1] * p
.y() + coeff
[2] * p
.z() - index
; //calcolo dove inizia il pattern
118 Point
key(p
.x() - coeff
[0] * index
, p
.y() - coeff
[0] * index
, p
.z() - coeff
[0] * index
);
119 QMap
<Point
, Node
*>::iterator it
= map
->find(key
);
120 int pri
= evalPriority(key
, dir
);
122 if (it
== map
->end()) {
124 //inserisco nella struttura
125 it
= map
->insert(key
, new Node(pri
, key
, dir
));
126 //aggiungo alla list priority corretta
127 insertInPriority(*it
);
131 //tolgo dalla lista priority
132 removeFromPriority(*it
);
134 //tolgo dalla struttura
139 //aggiorno la priorità nel nodo
141 //e lo inserisco nuovamente nella lista
142 insertInPriority(*it
);
147 int Threat::evalPriority(Point p
, Direction dir
) const
149 QVector
<int> coeff(3,0);
163 //controllo che il pattern sia nei limiti della matrice
164 int start
= p
.x() * coeff
[0] + p
.y() * coeff
[1] + p
.z() * coeff
[2];
165 if (start
< 0 || start
+ _d1
> _d1
*_d2
) {
172 for (int j
= 0; j
< _d1
&& valid
; j
++) {
173 int piece
= _mat
->elementAt(p
.x() + coeff
[0] * j
, p
.y() + coeff
[0] * j
, p
.z() + coeff
[0] * j
);
174 if (piece
== _ai
->playerId()) {
178 if (piece
!= GameMatrix::EmptyPoint
) {
190 void Threat::insertInPriority(Node
*it
)
193 if (pri
>= 0 && pri
< _d1
- 1) {
194 it
->next
= _priority
[pri
];
195 it
->par
= &(_priority
[pri
]);
196 if (_priority
[pri
]) {
197 _priority
[pri
]->par
= &(it
->next
);
203 void Threat::removeFromPriority(Node
*it
)
205 *(it
->par
) = it
->next
;
207 it
->next
->par
= it
->par
;
213 QList
<Point
> Threat::findEmptyPoints(Node
*node
)
217 QVector
<int> coeff(3,0);
231 for (int i
= 0; i
< _d1
; i
++) {
232 Point
key(node
->point
.x() + i
* coeff
[0], node
->point
.y() + i
* coeff
[1], node
->point
.z() + i
* coeff
[2]);
233 if (_mat
->elementAt(key
) == GameMatrix::EmptyPoint
) {
240 Threat::Node::Node(int val
, Point p
, Direction dir
)
249 Threat::Node::~Node()