#include "../includes/Plateau.hpp" #include "../includes/Ecran.hpp" Plateau::Plateau(const int t) : plateau(new Piece **[t]), taille(t) { // Création du plateau vide for (int i = 0; i < t; i++) { plateau[i] = new Piece *[t]; for (int j = 0; j < t; j++) { plateau[i][j] = nullptr; } } selection = nullptr; } Plateau::~Plateau() { for (int i = 0; i < taille; i++) { delete[] plateau[i]; } delete[] plateau; } std::ostream &operator<<(std::ostream &out, const Plateau &data) { data.afficherPlateau(out, false); return out; } void Plateau::afficherPlateau(std::ostream &out, const bool d) const { const float tailleCellule = static_cast(Ecran::largeur()) / taille; const float decalagePiece = tailleCellule / 6; // Cellule sf::RectangleShape cell(sf::Vector2f(tailleCellule, tailleCellule)); // Pièce sf::CircleShape piece(tailleCellule / 3); piece.setOutlineThickness(2.); for (int i = 0; i < taille; i++) { for (int j = 0; j < taille; j++) { const float x = i * tailleCellule; const float y = j * tailleCellule; // Position de la cellule et de la pièce cell.setPosition(x, y); piece.setPosition(x + decalagePiece, y + decalagePiece); if (d) { out << "(" << x << ", " << y; } // Alternation des couleurs if ((i + j) % 2 == 0) { cell.setFillColor(sf::Color::White); piece.setOutlineColor(sf::Color::Black); if (d) { out << ", B), "; } } else { cell.setFillColor(sf::Color::Black); piece.setOutlineColor(sf::Color::White); if (d) { out << ", N), "; } } // Dessine la cellule Ecran::window.draw(cell); // Dessine la pièce Piece *p = plateau[i][j]; if (p != nullptr) { if (p->isSelectionnee()) { piece.setOutlineColor(sf::Color::Green); } // TODO(Idée): Au lieu de demander une couleur on pourait demander // directement une forme/texture à la pièce // Avantage : A la place d'une forme on pourrait mettre une image, pour // Safari par exemple // Inconvénient : Ca va potentiellement créer plusieurs fois la même // chose en mémoire pour rien du tout // // A méditer piece.setFillColor(p->getScreenColor()); Ecran::window.draw(piece); } } if (d) { out << "\n"; } } if (d) { out << "---\n"; } } void Plateau::modifierPlateau(const int x, const int y, Piece *piece) const { if (x >= 0 && x < taille && y >= 0 && y < taille) { if (piece == nullptr) { delete plateau[x][y]; } plateau[x][y] = piece; } else { throw std::invalid_argument("Coordonnées invalides"); } } Piece *Plateau::getPiece(const int x, const int y) const { if (x >= 0 && x < taille && y >= 0 && y < taille) { return plateau[x][y]; } else { throw std::invalid_argument("Coordonnées invalides"); } } std::pair Plateau::trouveCoordonnees(const int x, const int y) const { const float tailleCellule = static_cast(Ecran::largeur()) / taille; int xPlateau = static_cast(x / tailleCellule); int yPlateau = static_cast(y / tailleCellule); return std::make_pair(xPlateau, yPlateau); } int Plateau::getTaille() const { return taille; } void Plateau::modifierSelection(const int x, const int y) { Piece *p = getPiece(x, y); if (p == nullptr) { // Si rien est selectionné on ne fait rien return; } if (selection) { // Déselectionne l'ancienne sélection selection->changeSelection(); } if (p != selection) { // Si la sélection à changer alors changer l'état de la nouvelle pièce p->changeSelection(); selection = p; } else { // Si c'était la même alors on ne sélectionne plus rien selection = nullptr; } } std::pair Plateau::moveSelection(const int x, const int y) { if (selection == nullptr) { // Ne fais rien si on a rien a bouger return std::make_pair(-1, -1); } // Récupère les coordonnées std::pair ancienneCoordonnees = std::make_pair(selection->x, selection->y); // Retire la pièce de là où elle est pour le plateau plateau[ancienneCoordonnees.first][ancienneCoordonnees.second] = nullptr; // Déplace la pièce sur le plateau modifierPlateau(x, y, selection); // Met à jour les coordonnées de la pièce selection->moveTo(x, y); // Déselectionne la pièce modifierSelection(x, y); return ancienneCoordonnees; }