Hello tout le monde,
Je suis actuellement entrain de faire un pathfinding pour mon bot. Je me heurte a un petit problème que je ne comprends pas:
en effet, j'ai tout vérifié et mon code semble bon.
Lors de tests quand je tente d'aller depuis la cellule 297 à 452 voici le chemin que j'obtiens (voir image fleche rouge), tandis que d'apres mes tests voici ce que le client fait (fleche bleue)
J'ai tout vérifié et mon code semble correcte. Voici mes sources:
la classe "Cellule"
Cliquez pour révéler
Cliquez pour masquer
#include "Cells.h"
Cells::Cells(QList<int> const &closedList, int cell)
{
m_closedList = closedList;
m_cell = cell;
m_parent = NULL;
m_YCoords = NULL;
m_XCoords = NULL;
m_cellFWeight = NULL;
m_cellHWeight = NULL;
m_cellGWeight = NULL;
m_adjacentCells;
}
Cells::Cells(int cell)
{
m_cell = cell;
m_YCoords = NULL;
m_XCoords = NULL;
m_parent = NULL;
m_cellFWeight = NULL;
m_cellHWeight = NULL;
m_cellGWeight = NULL;
}
Cells::Cells(int cell, int parent)
{
m_cell = cell;
m_parent = parent;
m_YCoords = NULL;
m_XCoords = NULL;
m_cellFWeight = NULL;
m_cellHWeight = NULL;
m_cellGWeight = NULL;
}
bool Cells::operator==(const Cells& cell2)
{
if (m_cell == cell2.m_cell)
return true;
return false;
}
void Cells::adjacentCells(Cells cell, QList<int> closedList)
{
cell.coordsCalculations(cell);
int _cell = cell.m_cell;
cell.m_adjacentCells.clear();
Cells adjacentCell1 = Cells(-1);
Cells adjacentCell2 = Cells(-1);
Cells adjacentCell3 = Cells(-1);
Cells adjacentCell4 = Cells(-1);
Cells adjacentCell5 = Cells(-1);
Cells adjacentCell6 = Cells(-1);
Cells adjacentCell7 = Cells(-1);
Cells adjacentCell8 = Cells(-1);
if ((cell.getYCoords(cell) % 2) == 0) {
adjacentCell1.m_cell = (_cell - 1);
adjacentCell2.m_cell = (_cell - 15);
adjacentCell3.m_cell = (_cell - 28);
adjacentCell4.m_cell = (_cell + 13);
adjacentCell5.m_cell = (_cell - 14);
adjacentCell6.m_cell = (_cell + 28);
adjacentCell7.m_cell = (_cell + 14);
adjacentCell8.m_cell = (_cell + 1);
if (!closedList.contains(m_cell - 1))
cell.m_adjacentCells.append(adjacentCell1.getCellId(adjacentCell1));
if (!closedList.contains(m_cell - 15))
cell.m_adjacentCells.append(adjacentCell2.getCellId(adjacentCell2));
if (!closedList.contains(m_cell - 28))
cell.m_adjacentCells.append(adjacentCell3.getCellId(adjacentCell3));
if (!closedList.contains(m_cell + 13))
cell.m_adjacentCells.append(adjacentCell4.getCellId(adjacentCell4));
if (!closedList.contains(m_cell - 14))
cell.m_adjacentCells.append(adjacentCell5.getCellId(adjacentCell5));
if (!closedList.contains(m_cell + 28))
cell.m_adjacentCells.append(adjacentCell6.getCellId(adjacentCell6));
if (!closedList.contains(m_cell + 14))
cell.m_adjacentCells.append(adjacentCell7.getCellId(adjacentCell7));
if (!closedList.contains(m_cell + 1))
cell.m_adjacentCells.append(adjacentCell8.getCellId(adjacentCell8));
}
if ((cell.getYCoords(cell) % 2) != 0) {
adjacentCell1.m_cell = (_cell - 1);
adjacentCell2.m_cell = (_cell - 14);
adjacentCell3.m_cell = (_cell - 28);
adjacentCell4.m_cell = (_cell + 14);
adjacentCell5.m_cell = (_cell - 13);
adjacentCell6.m_cell = (_cell + 28);
adjacentCell7.m_cell = (_cell + 15);
adjacentCell8.m_cell = (_cell + 1);
if (!closedList.contains(m_cell - 1))
cell.m_adjacentCells.append(adjacentCell1.getCellId(adjacentCell1));
if (!closedList.contains(m_cell - 14))
cell.m_adjacentCells.append(adjacentCell2.getCellId(adjacentCell2));
if (!closedList.contains(m_cell - 28))
cell.m_adjacentCells.append(adjacentCell3.getCellId(adjacentCell3));
if (!closedList.contains(m_cell + 14))
cell.m_adjacentCells.append(adjacentCell4.getCellId(adjacentCell4));
if (!closedList.contains(m_cell - 13))
cell.m_adjacentCells.append(adjacentCell5.getCellId(adjacentCell5));
if (!closedList.contains(m_cell + 28))
cell.m_adjacentCells.append(adjacentCell6.getCellId(adjacentCell6));
if (!closedList.contains(m_cell + 15))
cell.m_adjacentCells.append(adjacentCell7.getCellId(adjacentCell7));
if (!closedList.contains(m_cell + 1))
cell.m_adjacentCells.append(adjacentCell8.getCellId(adjacentCell8));
}
if ((cell.getXCoords(cell) == 1 || cell.getXCoords(cell) == 0) && (cell.getYCoords(cell) % 2 == 0)) {
cell.m_adjacentCells.removeOne(adjacentCell1.getCellId(adjacentCell1));
cell.m_adjacentCells.removeOne(adjacentCell2.getCellId(adjacentCell2));
cell.m_adjacentCells.removeOne(adjacentCell4.getCellId(adjacentCell4));
}
if (cell.getYCoords(cell) == 0) {
cell.m_adjacentCells.removeOne(adjacentCell2.getCellId(adjacentCell2));
cell.m_adjacentCells.removeOne(adjacentCell3.getCellId(adjacentCell3));
cell.m_adjacentCells.removeOne(adjacentCell5.getCellId(adjacentCell5));
}
if (cell.getYCoords(cell) == 1) {
cell.m_adjacentCells.removeOne(adjacentCell3.getCellId(adjacentCell3));
}
if (cell.getXCoords(cell) == 27) {
cell.m_adjacentCells.removeOne(adjacentCell5.getCellId(adjacentCell5));
cell.m_adjacentCells.removeOne(adjacentCell7.getCellId(adjacentCell7));
cell.m_adjacentCells.removeOne(adjacentCell8.getCellId(adjacentCell8));
}
if (cell.getYCoords(cell) == 39) {
cell.m_adjacentCells.removeOne(adjacentCell4.getCellId(adjacentCell4));
cell.m_adjacentCells.removeOne(adjacentCell6.getCellId(adjacentCell6));
cell.m_adjacentCells.removeOne(adjacentCell7.getCellId(adjacentCell7));
}
if ((cell.getXCoords(cell) == 0 || cell.getXCoords(cell) == 1) && (cell.getYCoords(cell) % 2 != 0)) {
cell.m_adjacentCells.removeOne(adjacentCell1.getCellId(adjacentCell1));
}
m_adjacentCells = cell.m_adjacentCells;
}
int Cells::processGWeight(Cells startCell, Cells endCell, int weight)
{
startCell.coordsCalculations(startCell);
endCell.coordsCalculations(endCell);
int b = 0;
if (endCell.getYCoords(endCell) % 2 == 0)
if (startCell.getYCoords(startCell) % 2 != 0)
b = 10;
else
b = 14;
if (endCell.getYCoords(endCell) % 2 != 0)
if (startCell.getYCoords(startCell) % 2 == 0)
b = 10;
else
b = 14;
b += weight;
return b;
}
int Cells::processHWeight(Cells startCell, Cells endCell)
{
startCell.coordsCalculations(startCell);
endCell.coordsCalculations(endCell);
int a;
int b;
int c;
a = abs((endCell.getXCoords(endCell) - startCell.getXCoords(startCell)));
b = abs((endCell.getYCoords(endCell) - startCell.getYCoords(startCell)));
c = (10 * (a + b));
return c;
}
void Cells::cellWeight(Cells startCell, Cells currentCell, Cells endCell, int weight)
{
currentCell.m_cellFWeight = 0;
currentCell.m_cellHWeight = 0;
currentCell.m_cellGWeight = 0;
currentCell.m_cellHWeight = processHWeight(endCell, currentCell);
currentCell.m_cellGWeight = processGWeight(currentCell, startCell, weight);
currentCell.m_cellFWeight = currentCell.m_cellGWeight + currentCell.m_cellHWeight;
m_cellFWeight = currentCell.m_cellFWeight;
m_cellGWeight = currentCell.m_cellGWeight;
m_cellHWeight = currentCell.m_cellHWeight;
}
void Cells::coordsCalculations(Cells &cell)
{
cell.m_YCoords = floor((cell.m_cell / 14));
if (cell.m_YCoords < 0)
cell.m_YCoords = 0;
if (cell.m_YCoords && 1)
cell.m_XCoords = (cell.m_cell - cell.m_YCoords * 14) * 2 +1;
else
cell.m_XCoords = (cell.m_cell - cell.m_YCoords * 14) * 2;
m_XCoords = cell.m_XCoords;
m_YCoords = cell.m_YCoords;
}
QList<int> Cells::cellsToInt(QList<Cells> cellList)
{
QList<int> intList;
for (int i = 0; i < cellList.size(); i++)
intList.append(cellList.m_cell);
return intList;
}
int Cells::getXCoords(Cells cell) const
{
return cell.m_XCoords;
}
int Cells::getYCoords(Cells cell) const
{
return cell.m_YCoords;
}
int Cells::getCellId(Cells cell) const
{
return cell.m_cell;
}
QList<int> Cells::getAdjacentCells(Cells cell) const
{
return cell.m_adjacentCells;
}
float Cells::getCellFWeight(Cells cell) const
{
return cell.m_cellFWeight;
}
float Cells::getCellHWeight(Cells cell) const
{
return cell.m_cellHWeight;
}
float Cells::getCellGWeight(Cells cell) const
{
return cell.m_cellGWeight;
}
int Cells::getParent(Cells cell) const
{
return cell.m_parent;
}
void Cells::setOpenList(Cells cell, QList<int> openList)
{
cell.m_openList = openList;
}
void Cells::setParent(int parentCell)
{
m_parent = parentCell;
}
void Cells::setCellId(int cellId)
{
m_cell = cellId;
}
void Cells::setFWeight(int weight)
{
m_cellFWeight = weight;
}
void Cells::setHWeight(int weight)
{
m_cellHWeight = weight;
}
void Cells::setGWeight(int weight)
{
m_cellGWeight = weight;
}
void Cells::setCloseList(QList<int> list)
{
m_closedList = list;
}
La classe Pathfinder:
Cliquez pour révéler
Cliquez pour masquer
#include "Pathfinding.h"
Pathfinding::Pathfinding()
{
}
QList<int> Pathfinding::findPath(int _startCell, int _endCell, QList<int> _closedList)
{
Cells startCell = Cells(_startCell);
Cells endCell = Cells(_endCell);
Cells currentCell = Cells(_closedList, _startCell);
currentCell.setGWeight(0);
QList<int> temp1;
QList<Cells> temp2;
QList<Cells> openList;
QList<Cells> closeList;
for (int i = 0; i < _closedList.size(); i++) {
Cells _cell = Cells(_closedList);
closeList.append(_cell); }
for (int i = 0; i < closeList.size(); i++)
openList.removeOne(closeList);
closeList.append(startCell);
currentCell.setCellId(_startCell);
currentCell.setGWeight(0);
while ((openList.size() != (560 - closeList.size())) && (!closeList.contains(endCell))) {
currentCell.adjacentCells(currentCell, Cells::cellsToInt(closeList));
temp1 = currentCell.getAdjacentCells(currentCell);
for (int i = 0; i < temp1.size(); i++) {
Cells _cell = Cells(temp1);
temp2.append(_cell);
if (!closeList.contains(temp2.last())) {
temp2.last().cellWeight(currentCell, temp2.last(), endCell, currentCell.getCellGWeight(currentCell));
temp2.last().setParent(currentCell.getCellId(currentCell));
}
else
temp2.removeLast();
}
for (int i = 0; i < temp2.size(); i++) {
if (openList.contains(temp2)) {
if (openList.getCellGWeight(currentCell) > openList.processGWeight(currentCell, openList, currentCell.getCellGWeight(currentCell))) {
openList.setParent(currentCell.getCellId(currentCell));
openList.setFWeight(openList.getCellHWeight(openList) + openList.processGWeight(currentCell, openList, currentCell.getCellGWeight(currentCell)));
openList.setGWeight(openList.processGWeight(currentCell, openList, currentCell.getCellGWeight(currentCell)));
}
}
if (!openList.contains(temp2)) {
openList.append(temp2);
openList.last().cellWeight(currentCell, openList.last(), endCell, currentCell.getCellGWeight(currentCell));
openList.last().setParent(currentCell.getCellId(currentCell));
}
}
int minFWeight = 99999;
int minGWeight = 99999;
int optimisedCell = -1;
int optimisedParent = -1;
for (int i = 0; i < openList.size(); i++) {
if (openList.getCellFWeight(openList) < minFWeight) {
qDebug()<<"Cell:"<<openList.getCellId(openList)<<"F:"<<openList.getCellFWeight(openList)<<"H:"<<openList.getCellHWeight(openList)<<"G:"<<openList.getCellGWeight(openList);
minFWeight = openList.getCellFWeight(openList);
minGWeight = openList.getCellGWeight(openList);
optimisedCell = openList.getCellId(openList);
optimisedParent = openList.getParent(openList);
}
if ((openList.getCellFWeight(openList) == minFWeight) && (openList.getCellGWeight(openList) < minGWeight)) {
qDebug()<<"Cell:"<<openList.getCellId(openList)<<"F:"<<openList.getCellFWeight(openList)<<"H:"<<openList.getCellHWeight(openList)<<"G:"<<openList.getCellGWeight(openList);
minFWeight = openList.getCellFWeight(openList);
minGWeight = openList.getCellGWeight(openList);
optimisedCell = openList.getCellId(openList);
optimisedParent = openList.getParent(openList);
}
}
qDebug()<<"Chose Cell"<<optimisedCell;
Cells activeCell = Cells(optimisedCell, optimisedParent);
closeList.append(activeCell);
openList.removeOne(activeCell);
currentCell.setCellId(optimisedCell);
currentCell.setParent(optimisedParent);
currentCell.setGWeight(minGWeight);
temp1.clear();
temp2.clear();
}
int _cell = closeList.last().getCellId(closeList.last());
while (_cell != startCell.getCellId(startCell)) {
m_path.prepend(_cell);
_cell = traceBack(closeList.indexOf(_cell), closeList);
}
m_path.insert(0, startCell.getCellId(startCell));
return m_path;
}
int Pathfinding::traceBack(int pos, QList<Cells> closeList)
{
return closeList[pos].getParent(closeList[pos]);
}