Nantes Université

Skip to content
Extraits de code Groupes Projets
Valider 2994b446 rédigé par Florian Dargère's avatar Florian Dargère
Parcourir les fichiers

Fusion connex_components sur strategy

parents debcf97f 9f44ee8d
Aucune branche associée trouvée
Aucune étiquette associée trouvée
Aucune requête de fusion associée trouvée
......@@ -3,6 +3,7 @@
#include <functional>
#include <fstream>
#include <algorithm>
#include <queue>
StrategyBase::StrategyBase(unsigned int id, unsigned int nbPlayer, const SMap* map) :
Id(id),
......@@ -36,6 +37,7 @@ StrategyBase::StrategyBase(unsigned int id, unsigned int nbPlayer, const SMap* m
// nbdice pas initialisé juste parce que ici c'est uniquement la copie de la map
// (structure) et les dés arrivent après (sgameturn)
}
StrategyBase::~StrategyBase()
......@@ -43,6 +45,84 @@ StrategyBase::~StrategyBase()
// détruire proprement la structure Map
}
std::pair<std::vector<SCell*>, int> StrategyBase::DijkstraAlgo(SCell* cell_depart, SCell* cell_arrivee)
{
const int nbDices_depart = cell_depart->infos.nbDices;
int sum_nbDices = 0;
for (unsigned int i = 1; i < cell_depart->infos.nbDices; i++) { sum_nbDices += i; };
auto cmp = [](std::pair<SCell*,std::pair<std::vector<SCell*>,int>> cell1, std::pair<SCell*, std::pair<std::vector<SCell*>, int>> cell2) {
return (cell1.second.second < cell2.second.second);
};
//Queue contenant les cellules et leurs distances associées
std::priority_queue<std::pair<SCell*, std::pair<std::vector<SCell*>, int>>, std::vector<std::pair<SCell*, std::pair<std::vector<SCell*>, int>>>, decltype(cmp)> queue(cmp);
//Pour checker si on a déjà traité la cellule
std::vector<SCell*> visited_cells;
std::pair<SCell*, std::pair<std::vector<SCell*>, int>> initial_cell, current_cell;
std::vector<SCell*> path;
std::pair<std::vector<SCell*>, int> initial_cell_pair = std::make_pair(path, 9 - nbDices_depart);
initial_cell = std::make_pair(cell_depart, initial_cell_pair);
queue.push(initial_cell);
int compteur = 0;
std::vector<SCell*> return_vector;
std::pair<std::vector<SCell*>, int> return_cell = std::make_pair(return_vector, -1);
while (!queue.empty())
{
compteur++;
//On récupère la cell avec la meilleure distance
current_cell = queue.top();
queue.pop();
if (std::find(visited_cells.begin(), visited_cells.end(), current_cell.first) != visited_cells.end())
{
continue;
}
visited_cells.push_back(current_cell.first);
current_cell.second.first.push_back(current_cell.first);
/*On limite le nombre d'itérations pour ne pas rester bloqué sur les cas où
il n'y a aucun chemin disponible (celulle isolée)
Non hardcodé pour s'adapter en fonction de la taille de la map*/
//if (compteur > Map.nbCells * Map.nbCells) {
// std::cout << "Trop d'itérations" << std::endl;
// return return_cell;
//}
//std::cout << "Taille de queue : " << queue.size() << std::endl;
//std::cout << "Taille de vecteur de cells visitées : " << visited_cells.size() << std::endl;
if (current_cell.first->infos.id == cell_arrivee->infos.id) {
return current_cell.second;
}
//Si le nombre de dés à affronter au long du chemin est supérieur au nombre
//de dés de notre case de départ, on ne prend plus en compte ce chemin
//Ou bien si le chemin considéré est trop long
if (sum_nbDices < current_cell.second.second - 9 + nbDices_depart || current_cell.second.first.size() - 1 > nbDices_depart) {
continue;
}
int distance;
for (unsigned int i = 0; i < current_cell.first->nbNeighbors; i++) {
if (current_cell.first->neighbors[i]->infos.owner != Id || current_cell.first->neighbors[i] == cell_arrivee) {
//On push chaque voisin qui ne nous appartient pas dans la queue
std::vector<SCell*> path(current_cell.second.first);
std::pair<std::vector<SCell*>, int> cell_pair = std::make_pair(path, 9 - nbDices_depart);
distance = current_cell.second.second + current_cell.first->neighbors[i]->infos.nbDices;
queue.push(std::make_pair(current_cell.first->neighbors[i], cell_pair));
}
}
}
return return_cell;
}
std::vector<std::vector<SCell*>> StrategyBase::FindConnexComponent()
{
int* MarkedCells = new int [Map.nbCells];
......@@ -60,7 +140,6 @@ std::vector<std::vector<SCell*>> StrategyBase::FindConnexComponent()
Component.push_back(&Map.cells[cell->infos.id]);
MarkedCells[cell->infos.id] = 1;
//
for (unsigned int j = 0; j < cell->nbNeighbors; j++) {
if (cell->neighbors[j]->infos.owner == Id && MarkedCells[cell->neighbors[j]->infos.id] == 0) {
CalculComponent(cell->neighbors[j]);
......@@ -109,32 +188,64 @@ bool StrategyBase::PlayTurn(unsigned int gameTurn, const SGameState* state, STur
Map.cells[i].infos.nbDices = state->cells[i].nbDices;
}
//FindConnexComponent();
updateOwnedCells();
for (SCell* cell : ownedCells) {
for (unsigned int numNeighbor = 0; numNeighbor < cell->nbNeighbors; numNeighbor++) {
if (cell->infos.nbDices > cell->neighbors[numNeighbor]->infos.nbDices and cell->neighbors[numNeighbor]->infos.owner != Id) {
turn->cellFrom = cell->infos.id;
turn->cellTo = cell->neighbors[numNeighbor]->infos.id;
return(true);
std::vector<std::vector<SCell*>> Components = FindConnexComponent();
/*On calcule le meilleur couple de cellules entre notre plus grande composante
connexe et notre deuxième plus grande, et on détermine le chemin pour rejoindre
ces deux cellules*/
if (Components.size() >= 2)
{
std::cout << "Plus de 2 composantes" << std::endl;
std::pair<std::vector<SCell*>, int> best_path = DijkstraAlgo(Components[0][0], Components[1][0]);
for (unsigned int i = 0; i < Components[0].size(); i++) {
for (unsigned int j = 0; j < Components[1].size(); j++) {
std::pair<std::vector<SCell*>, int> new_path1 = DijkstraAlgo(Components[0][i], Components[1][j]);
std::pair<std::vector<SCell*>, int> new_path2 = DijkstraAlgo(Components[1][j], Components[0][i]);
if (new_path1.second < best_path.second) {
best_path = new_path1;
}
if (new_path2.second < best_path.second) {
best_path = new_path2;
}
}
}
std::cout << "Longueur du path : " << best_path.first.size() << std::endl;
std::cout << "Distance du path : " << best_path.second << std::endl;
if (!best_path.first.empty())
{
turn->cellFrom = best_path.first[0]->infos.id;
turn->cellTo = best_path.first[1]->infos.id;
std::cout << "StratConnex" << std::endl;
std::cout << "cellFrom" << turn->cellFrom << std::endl;
std::cout << "cellTo" << turn->cellTo << std::endl;
return(true);
}
}
//updateOwnedCells();
//for (unsigned int numCell = 0; numCell < Map.nbCells; numCell++) {
// if (Map.cells[numCell].infos.owner == Id) {
// for (unsigned int numNeighbor = 0; numNeighbor < Map.cells[numCell].nbNeighbors; numNeighbor++) {
// if (Map.cells[numCell].infos.nbDices > Map.cells[numCell].neighbors[numNeighbor]->infos.nbDices and Map.cells[numCell].neighbors[numNeighbor]->infos.owner != Id) {
// turn->cellFrom = numCell;
// turn->cellTo = Map.cells[numCell].neighbors[numNeighbor]->infos.id;
// return(true);
// }
//for (SCell* cell : ownedCells) {
// for (unsigned int numNeighbor = 0; numNeighbor < cell->nbNeighbors; numNeighbor++) {
// if (cell->infos.nbDices > cell->neighbors[numNeighbor]->infos.nbDices and cell->neighbors[numNeighbor]->infos.owner != Id) {
// turn->cellFrom = cell->infos.id;
// turn->cellTo = cell->neighbors[numNeighbor]->infos.id;
// return(true);
// }
// }
//}
for (unsigned int numCell = 0; numCell < Map.nbCells; numCell++) {
if (Map.cells[numCell].infos.owner == Id) {
for (unsigned int numNeighbor = 0; numNeighbor < Map.cells[numCell].nbNeighbors; numNeighbor++) {
if (Map.cells[numCell].infos.nbDices > Map.cells[numCell].neighbors[numNeighbor]->infos.nbDices and Map.cells[numCell].neighbors[numNeighbor]->infos.owner != Id) {
std::cout << "StratBase" << std::endl;
turn->cellFrom = numCell;
turn->cellTo = Map.cells[numCell].neighbors[numNeighbor]->infos.id;
return(true);
}
}
}
}
return(false);
}
\ No newline at end of file
......@@ -16,8 +16,8 @@ public:
bool PlayTurn(unsigned int gameTurn, const SGameState *state, STurn *turn);
std::vector<std::vector<SCell*>> FindConnexComponent();
std::pair<std::vector<SCell*>, int> DijkstraAlgo(SCell*, SCell*);
void updateOwnedCells();
protected:
const unsigned int Id;
const unsigned int NbPlayer;
......
0% Chargement en cours ou .
You are about to add 0 people to the discussion. Proceed with caution.
Terminez d'abord l'édition de ce message.
Veuillez vous inscrire ou vous pour commenter