Nantes Université

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

Conversion en modèle objet (non fonctionnel)

parent 2994b446
Aucune branche associée trouvée
Aucune étiquette associée trouvée
Aucune requête de fusion associée trouvée
#include "CMap.h"
#include <iostream>
#include "Cell.h"
//Ce constructeur est lanc deux fois ?
//Dans le constructeur, nbNeighbors et taille du vecteur de neighbors corrects
//Plus tard dans le code (FindConnexComponents) nbNeigbors 347523255662 et neighbors.size() 0
CMap::CMap(const SMap* map)
{
nbRegions = 0;
nbCells = map->nbCells;
cells.resize(map->nbCells);
for (unsigned int i = 0; i < map->nbCells; i++) {
Cell newCell(map->cells[i].infos.id, map->cells[i].infos.owner, map->cells[i].nbNeighbors, map->cells[i].infos.nbDices);
newCell.neighbors.resize(newCell.nbNeighbors);
std::cout << "Cell" << i << ": " << newCell.nbNeighbors << std::endl;
std::cout << newCell.neighbors.size() << std::endl;
for (unsigned int j = 0; j < map->cells[i].nbNeighbors; j++) {
newCell.neighbors[j] = cells[map->cells[i].neighbors[j]->infos.id];
}
cells[i] = &newCell;
}
}
std::vector<std::vector<Cell*>> CMap::FindConnexComponent(int idPlayer)
{
int* MarkedCells = new int[nbCells];
for (unsigned int i = 0; i < nbCells; i++) MarkedCells[i] = 0;
std::vector<std::vector<Cell*>> ComponentVec; //Vecteur de composantes connexes
for (unsigned int i = 0; i < nbCells; i++) {
if (cells[i]->owner == idPlayer && MarkedCells[i] == 0) {
//On a trouv une cellule nous et on calcule sa composante connexe associe
std::vector<Cell*> Component;
std::function<void(Cell*)> CalculComponent;
CalculComponent = [this, &MarkedCells, &Component, &CalculComponent, idPlayer](Cell* cell) {
Component.push_back(cells[cell->id]);
MarkedCells[cell->id] = 1;
for (unsigned int j = 0; j < cell->nbNeighbors; j++) {
if (cell->neighbors[j]->owner == idPlayer && MarkedCells[cell->neighbors[j]->id] == 0) {
CalculComponent(cell->neighbors[j]);
}
}
};
CalculComponent(cells[i]);
ComponentVec.push_back(Component);
}
}
std::sort(ComponentVec.begin(), ComponentVec.end(), [](std::vector<Cell*> vec1, std::vector<Cell*> vec2) {return (vec1.size() > vec2.size()); });
return(ComponentVec);
}
std::pair<std::vector<Cell*>, int> CMap::DijkstraAlgo(Cell* cell_depart, Cell* cell_arrivee)
{
int id_player = cell_depart->owner;
const int nbDices_depart = cell_depart->nbDices;
int sum_nbDices = 0;
for (unsigned int i = 1; i < cell_depart->nbDices; i++) { sum_nbDices += i; };
auto cmp = [](std::pair<Cell*, std::pair<std::vector<Cell*>, int>> cell1, std::pair<Cell*, std::pair<std::vector<Cell*>, int>> cell2) {
return (cell1.second.second < cell2.second.second);
};
//Queue contenant les cellules et leurs distances associes
std::priority_queue<std::pair<Cell*, std::pair<std::vector<Cell*>, int>>, std::vector<std::pair<Cell*, std::pair<std::vector<Cell*>, int>>>, decltype(cmp)> queue(cmp);
//Pour checker si on a dj trait la cellule
std::vector<Cell*> visited_cells;
std::pair<Cell*, std::pair<std::vector<Cell*>, int>> initial_cell, current_cell;
std::vector<Cell*> path;
std::pair<std::vector<Cell*>, 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;
//cell return en cas d'chec de la fonction
std::vector<Cell*> return_vector;
std::pair<std::vector<Cell*>, int> return_cell({ return_vector, -1 });
while (!queue.empty())
{
compteur++;
//On rcupre 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);
//std::cout << "Taille de queue : " << queue.size() << std::endl;
//std::cout << "Taille de vecteur de cells visites : " << visited_cells.size() << std::endl;
if (current_cell.first->id == cell_arrivee->id) {
return current_cell.second;
}
//Si le nombre de ds affronter au long du chemin est suprieur au nombre
//de ds de notre case de dpart, on ne prend plus en compte ce chemin
//Ou bien si le chemin considr 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]->owner != id_player || current_cell.first->neighbors[i] == cell_arrivee) {
//On push chaque voisin qui ne nous appartient pas dans la queue
std::vector<Cell*> path(current_cell.second.first);
std::pair<std::vector<Cell*>, int> cell_pair = std::make_pair(path, 9 - nbDices_depart);
distance = current_cell.second.second + current_cell.first->neighbors[i]->nbDices;
queue.push(std::make_pair(current_cell.first->neighbors[i], cell_pair));
}
}
}
return return_cell;
}
\ No newline at end of file
#pragma once
#include <vector>
#include <functional>
#include <algorithm>
#include <queue>
#include "../../Commun/IStrategyLib.h"
#include "Cell.h"
class Region;
class CMap
{
public:
unsigned int nbCells;
unsigned int nbRegions;
std::vector<Region*> regions;
std::vector <Cell*> cells;
//CMap()=delete;
CMap(const SMap*);
~CMap()=default;
CMap(const CMap&) = delete;
CMap(CMap&&) = default;
CMap& operator=(const CMap&) = delete;
CMap& operator=(CMap&&)=default;
std::vector<std::vector<Cell*>> FindConnexComponent(int);
std::pair<std::vector<Cell*>, int> DijkstraAlgo(Cell*, Cell*);
};
\ No newline at end of file
#pragma once
class Cell
{
public:
unsigned int id;
unsigned int owner;
unsigned int nbNeighbors;
unsigned int nbDices;
std::vector<Cell*> neighbors;
Cell()=default;
~Cell()=default;
Cell(const int id_cell, const int id_player, const int nbvoisins, const int nbdes) :
id(id_cell), owner(id_player), nbNeighbors(nbvoisins), nbDices(nbdes) {};
Cell(const Cell&)=delete;
Cell(Cell&&) = delete;
Cell& operator=(const Cell&) = delete;
Cell& operator=(Cell&&) = delete;
};
\ No newline at end of file
#pragma once
#pragma once
#include "StrategyBase.h"
#include <iostream>
#include <functional>
#include <fstream>
#include <algorithm>
#include <queue>
//FindConnexComponents dans Map
//Dijkstra dans Map surchargée pour région et cell
StrategyBase::StrategyBase(unsigned int id, unsigned int nbPlayer, const SMap* map) :
Id(id),
NbPlayer(nbPlayer)
NbPlayer(nbPlayer),
Map(CMap(map))
{
std::cout << "Notre id est : " << Id << std::endl;
// faire une copie entière de la structure map localement dans l'objet Map
Map.nbCells = map->nbCells;
Map.cells = new SCell [map->nbCells];
int shift = map->cells - Map.cells;
for (unsigned int i = 0; i < map->nbCells; i++) {
SCell newCell = *new(struct SCell);
newCell.infos = *new struct SCellInfo;
newCell.infos.id = map->cells[i].infos.id;
newCell.infos.owner = map->cells[i].infos.owner;
newCell.infos.nbDices = map->cells[i].infos.nbDices;
newCell.neighbors = new SCell * [map->cells[i].nbNeighbors];
for (unsigned int j = 0; j < map->cells[i].nbNeighbors; j++) {
newCell.neighbors[j] = &Map.cells[map->cells[i].neighbors[j]->infos.id];
}
newCell.nbNeighbors = map->cells[i].nbNeighbors;
Map.cells[i] = newCell;
}
// 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()
......@@ -45,117 +18,6 @@ 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];
for (unsigned int i = 0; i < Map.nbCells; i++) MarkedCells[i] = 0;
std::vector<std::vector<SCell*>> ComponentVec; //Vecteur de composantes connexes
for (unsigned int i = 0; i < Map.nbCells; i++) {
if (Map.cells[i].infos.owner == Id && MarkedCells[i] == 0) {
//On a trouvé une cellule à nous et on calcule sa composante connexe associée
std::vector<SCell*> Component;
std::function<void(SCell*)> CalculComponent;
CalculComponent = [this, &MarkedCells, &Component, &CalculComponent](SCell* cell) {
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]);
}
}
};
CalculComponent(&Map.cells[i]);
ComponentVec.push_back(Component);
}
}
std::sort(ComponentVec.begin(), ComponentVec.end(), [](std::vector<SCell*> vec1, std::vector<SCell*> vec2) {return (vec1.size() > vec2.size()); });
return(ComponentVec);
}
void StrategyBase::updateOwnedCells() {
// mise à jour du vecteur des cellules alliées triées par nombre de voisins alliés
......@@ -163,32 +25,37 @@ void StrategyBase::updateOwnedCells() {
ownedCells.clear();
for (unsigned int i = 0; i < Map.nbCells; i++) {
if (Map.cells[i].infos.owner == Id) {
ownedCells.push_back(&Map.cells[i]);
if (Map.cells[i]->owner == Id) {
ownedCells.push_back(Map.cells[i]);
}
}
std::sort(ownedCells.begin(), ownedCells.end(), [this](SCell* c1, SCell* c2) {
std::sort(ownedCells.begin(), ownedCells.end(), [this](Cell* c1, Cell* c2) {
int n1 = 0, n2 = 0;
for (unsigned int i = 0; i < c1->nbNeighbors; i++) if (c1->neighbors[i]->infos.owner == Id) n1++;
for (unsigned int j = 0; j < c2->nbNeighbors; j++) if (c2->neighbors[j]->infos.owner == Id) n2++;
for (unsigned int i = 0; i < c1->nbNeighbors; i++) if (c1->neighbors[i]->owner == Id) n1++;
for (unsigned int j = 0; j < c2->nbNeighbors; j++) if (c2->neighbors[j]->owner == Id) n2++;
return n1 > n2;
});
}
bool StrategyBase::PlayTurn(unsigned int gameTurn, const SGameState* state, STurn* turn)
{
//Recopie de l'état de la map et maj du nb de cellules possédées
for (unsigned int i = 0; i < state->nbCells; i++) {
// inutile d'update les id
Map.cells[i].infos.id = state->cells[i].id;
Map.cells[i].infos.owner = state->cells[i].owner;
Map.cells[i].infos.nbDices = state->cells[i].nbDices;
Map.cells[i]->id = state->cells[i].id;
Map.cells[i]->owner = state->cells[i].owner;
Map.cells[i]->nbDices = state->cells[i].nbDices;
}
for (unsigned int i = 0; i < Map.nbCells; i++)
{
std::cout << Map.cells[i]->nbNeighbors << std::endl;
std::cout << Map.cells[i]->neighbors.size() << std::endl;
std::cout << Map.cells[i]->id << std::endl;
}
std::vector<std::vector<SCell*>> Components = FindConnexComponent();
std::vector<std::vector<Cell*>> Components = Map.FindConnexComponent(Id);
/*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
......@@ -196,11 +63,11 @@ bool StrategyBase::PlayTurn(unsigned int gameTurn, const SGameState* state, STur
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]);
std::pair<std::vector<Cell*>, int> best_path = Map.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]);
std::pair<std::vector<Cell*>, int> new_path1 = Map.DijkstraAlgo(Components[0][i], Components[1][j]);
std::pair<std::vector<Cell*>, int> new_path2 = Map.DijkstraAlgo(Components[1][j], Components[0][i]);
if (new_path1.second < best_path.second) {
best_path = new_path1;
}
......@@ -214,8 +81,8 @@ bool StrategyBase::PlayTurn(unsigned int gameTurn, const SGameState* state, STur
if (!best_path.first.empty())
{
turn->cellFrom = best_path.first[0]->infos.id;
turn->cellTo = best_path.first[1]->infos.id;
turn->cellFrom = best_path.first[0]->id;
turn->cellTo = best_path.first[1]->id;
std::cout << "StratConnex" << std::endl;
std::cout << "cellFrom" << turn->cellFrom << std::endl;
std::cout << "cellTo" << turn->cellTo << std::endl;
......@@ -235,12 +102,12 @@ bool StrategyBase::PlayTurn(unsigned int gameTurn, const SGameState* state, STur
// }
//}
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) {
if (Map.cells[numCell]->owner == Id) {
for (unsigned int numNeighbor = 0; numNeighbor < Map.cells[numCell]->nbNeighbors; numNeighbor++) {
if (Map.cells[numCell]->nbDices > Map.cells[numCell]->neighbors[numNeighbor]->nbDices and Map.cells[numCell]->neighbors[numNeighbor]->owner != Id) {
std::cout << "StratBase" << std::endl;
turn->cellFrom = numCell;
turn->cellTo = Map.cells[numCell].neighbors[numNeighbor]->infos.id;
turn->cellTo = Map.cells[numCell]->neighbors[numNeighbor]->id;
return(true);
}
}
......
......@@ -2,6 +2,7 @@
#include "../../Commun/IStrategyLib.h"
#include <vector>
#include "CMap.h"
class StrategyBase
{
......@@ -15,13 +16,12 @@ 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;
SMap Map;
CMap Map;
std::vector<SCell*> ownedCells;
std::vector<Cell*> ownedCells;
};
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