#include "../inc/board.hh" Board::Board() : is_selected_movement(false) { // Czyścimy całą tablicę for(int i=0; isetPosition(target); // Zwracamy prawdę, że się udało return true; } Pawn Board::deletePawn(Vector position) { Pawn deleted_pawn = *board[position.x][position.y]; delete board[position.x][position.y]; board[position.x][position.y] = NULL; return deleted_pawn; } void Board::draw(sf::RenderWindow& window) { // Wymiar X for(int x=0; xdraw(window); } } // Zaznacz kafelki przeznaczone do zaznaczenia for(auto selected_tile: selected_tiles) { // Pobieramy współrzędne int x = selected_tile.x; int y = selected_tile.y; // Tworzymy pojedynczy kafelek o wymiarach TILE_SIZE x TILE_SIZE sf::RectangleShape tile(sf::Vector2f(TILE_SIZE, TILE_SIZE)); // Ustawiamy pozycję na i*TILE_SIZE, j*TILE_SIZE -- czyli np. dla TILE_SIZE = 64: (0,0), (0,64), (0,128), ... tile.setPosition(x*TILE_SIZE, y*TILE_SIZE); // Jeżeli to zwykłe zaznaczenie, ustawiamy kolor wypełnienia co drugiego kafelka na jasny if(!is_selected_movement) tile.setFillColor(((x+y)%2)?sf::Color(200, 124, 50):sf::Color(255, 255, 220)); else tile.setFillColor(((x+y)%2)?sf::Color(167, 200, 50):sf::Color(178, 255, 174)); // Rysujemy kafelki window.draw(tile); // Jeżeli istnieją na danym polu pionki, to je rysujemy if(board[x][y]) board[x][y]->draw(window); } } Pawn* Board::selectPawn(Vector position) { // Jeżeli pionek na tym polu istnieje if(board[position.x][position.y]) { // Odznaczamy wszystkie pionki for(int x = 0; xdeselect(); // Zaznaczamy właściwy board[position.x][position.y]->select(); // Zwracamy zaznaczony return board[position.x][position.y]; } // Zwracamy NULL, bo pionek nie istnieje return NULL; } bool Board::isPossibleBeating(Vector position) { return getPossibleBeatings(position).size(); } bool Board::arePossibleGlobalBeatings(Color color) { return getPossibleGlobalBeatings(color).size(); } std::list Board::getPossibleBeatings(Vector position) { // Tworzymy nowy kontener na pozycje std::list beatings; // Pobieramy wskaźnik do pionka znajdującego się na zadanej pozycji Pawn* position_pawn = getPawn(position); // Jeżeli go tam nie ma, zwracamy pusty kontener if(!position_pawn) return beatings; //// Bicie normalnymi pionkami // Bicie o wektor [-2, -2] if((position.x >= 2 && position.y >= 2) && // Jeżeli bicie nie wyjdzie poza planszę (getPawn(position+Vector(-1, -1))) && // Jeżeli istnieje bity pionek (getPawn(position+Vector(-1, -1))->getColor() != position_pawn->getColor()) && // Jeżeli jest to pionek przeciwnego koloru (!getPawn(position+Vector(-2, -2)))) // Jeżeli pole docelowe jest puste beatings.push_back(Movement(position, position+Vector(-2, -2))); // Dorzuć ruch do listy // Bicie o wektor [-2, 2] if((position.x >= 2 && position.y < TILES_COUNT-2) && // Jeżeli bicie nie wyjdzie poza planszę (getPawn(position+Vector(-1, 1))) && // Jeżeli istnieje bity pionek (getPawn(position+Vector(-1, 1))->getColor() != position_pawn->getColor()) && // Jeżeli jest to pionek przeciwnego koloru (!getPawn(position+Vector(-2, 2)))) // Jeżeli pole docelowe jest puste beatings.push_back(Movement(position, position+Vector(-2, 2))); // Dorzuć ruch do listy // Bicie o wektor [2, 2] if((position.x < TILES_COUNT-2 && position.y < TILES_COUNT-2) && // Jeżeli bicie nie wyjdzie poza planszę (getPawn(position+Vector(1, 1))) && // Jeżeli istnieje bity pionek (getPawn(position+Vector(1, 1))->getColor() != position_pawn->getColor()) && // Jeżeli jest to pionek przeciwnego koloru (!getPawn(position+Vector(2, 2)))) // Jeżeli pole docelowe jest puste beatings.push_back(Movement(position, position+Vector(2, 2))); // Dorzuć ruch do listy // Bicie o wektor [2, -2] if((position.x < TILES_COUNT-2 && position.y >= 2) && // Jeżeli bicie nie wyjdzie poza planszę (getPawn(position+Vector(1, -1))) && // Jeżeli istnieje bity pionek (getPawn(position+Vector(1, -1))->getColor() != position_pawn->getColor()) && // Jeżeli jest to pionek przeciwnego koloru (!getPawn(position+Vector(2, -2)))) // Jeżeli pole docelowe jest puste beatings.push_back(Movement(position, position+Vector(2, -2))); // Dorzuć ruch do listy //// Bicie damkami // Jeżeli pionek jest damką posiada dodatkowe możliwości bicia if(getPawn(position)->isQueen()) { // Bicie o wektor [-2, 0] if((position.x >= 2) && // Jeżeli bicie nie wyjdzie poza planszę (getPawn(position+Vector(-1, 0))) && // Jeżeli istnieje bity pionek (getPawn(position+Vector(-1, 0))->getColor() != position_pawn->getColor()) && // Jeżeli jest to pionek przeciwnego koloru (!getPawn(position+Vector(-2, 0)))) // Jeżeli pole docelowe jest puste beatings.push_back(Movement(position, position+Vector(-2, 0))); // Dorzuć ruch do listy // Bicie o wektor [0, 2] if((position.y < TILES_COUNT-2) && // Jeżeli bicie nie wyjdzie poza planszę (getPawn(position+Vector(0, 1))) && // Jeżeli istnieje bity pionek (getPawn(position+Vector(0, 1))->getColor() != position_pawn->getColor()) && // Jeżeli jest to pionek przeciwnego koloru (!getPawn(position+Vector(0, 2)))) // Jeżeli pole docelowe jest puste beatings.push_back(Movement(position, position+Vector(0, 2))); // Dorzuć ruch do listy // Bicie o wektor [2, 0] if((position.x < TILES_COUNT-2) && // Jeżeli bicie nie wyjdzie poza planszę (getPawn(position+Vector(1, 0))) && // Jeżeli istnieje bity pionek (getPawn(position+Vector(1, 0))->getColor() != position_pawn->getColor()) && // Jeżeli jest to pionek przeciwnego koloru (!getPawn(position+Vector(2, 0)))) // Jeżeli pole docelowe jest puste beatings.push_back(Movement(position, position+Vector(2, 0))); // Dorzuć ruch do listy // Bicie o wektor [0, -2] if((position.y < TILES_COUNT-2) && // Jeżeli bicie nie wyjdzie poza planszę (getPawn(position+Vector(0, -1))) && // Jeżeli istnieje bity pionek (getPawn(position+Vector(0, -1))->getColor() != position_pawn->getColor()) && // Jeżeli jest to pionek przeciwnego koloru (!getPawn(position+Vector(0, -2)))) // Jeżeli pole docelowe jest puste beatings.push_back(Movement(position, position+Vector(0, -2))); // Dorzuć ruch do listy } // Zwracamy kontener return beatings; } std::list Board::getPossibleMovements(Vector position) { // Jeżeli są możliwe bicia, zwróć je if(isPossibleBeating(position)) return getPossibleBeatings(position); std::list movements; // Jeżeli pionek nie istnieje, zwróć pustą listę if(!getPawn(position)) return movements; // Jeżeli pionek jest damką if(getPawn(position)->isQueen()) { // Jeżeli ruch w górę-lewo jest możliwy (jest puste miejsce) dorzuć ruch do listy if(position.x >= 1 && position.y >= 1) if(!getPawn(position+Vector(-1, -1))) movements.push_back(Movement(position, position+Vector(-1, -1))); // Jeżeli ruch w górę-prawo jest możliwy (jest puste miejsce) dorzuć ruch do listy if(position.x < TILES_COUNT-1 && position.y >= 1) if(!getPawn(position+Vector(1, -1))) movements.push_back(Movement(position, position+Vector(1, -1))); // Jeżeli ruch w dół-lewo jest możliwy (jest puste miejsce) dorzuć ruch do listy if(position.x >= 1 && position.y < TILES_COUNT-1) if(!getPawn(position+Vector(-1, 1))) movements.push_back(Movement(position, position+Vector(-1, 1))); // Jeżeli ruch w dół-prawo jest możliwy (jest puste miejsce) dorzuć ruch do listy if(position.x < TILES_COUNT-1 && position.y < TILES_COUNT-1) if(!getPawn(position+Vector(1, 1))) movements.push_back(Movement(position, position+Vector(1, 1))); // TODO zmodyfikowane ruchy // TODO - zrobić, aby damka mogła robić długie ruchy (to samo dla bicia!) // Jeżeli ruch w górę jest możliwy (jest puste miejsce) dorzuć ruch do listy if(position.y >= 1) ;//if(!getPawn(position+Vector(0, -1))) movements.push_back(Movement(position, position+Vector(0, -1))); // Jeżeli ruch w dół jest możliwy (jest puste miejsce) dorzuć ruch do listy if(position.y < TILES_COUNT-1) ;//if(!getPawn(position+Vector(0, 1))) movements.push_back(Movement(position, position+Vector(0, 1))); // Jeżeli ruch w lewo jest możliwy (jest puste miejsce) dorzuć ruch do listy if(position.x >= 1) ;//if(!getPawn(position+Vector(-1, 0))) movements.push_back(Movement(position, position+Vector(-1, 0))); // Jeżeli ruch w prawo jest możliwy (jest puste miejsce) dorzuć ruch do listy if(position.x < TILES_COUNT-1) ;//if(!getPawn(position+Vector(1, 0))) movements.push_back(Movement(position, position+Vector(1, 0))); } // Jeżeli jest to zwykły pionek else { // Jeżeli to ruch białego pionka if(getPawn(position)->getColor() == CL_WHITE) { // Jeżeli ruch w górę-lewo jest możliwy (jest puste miejsce) dorzuć ruch do listy if(position.x >= 1 && position.y >= 1) if(!getPawn(position+Vector(-1, -1))) movements.push_back(Movement(position, position+Vector(-1, -1))); // Jeżeli ruch w górę-prawo jest możliwy (jest puste miejsce) dorzuć ruch do listy if(position.x < TILES_COUNT-1 && position.y >= 1) if(!getPawn(position+Vector(1, -1))) movements.push_back(Movement(position, position+Vector(1, -1))); } // Jeżeli to ruch czarnego pionka else { // Jeżeli ruch w dół-lewo jest możliwy (jest puste miejsce) dorzuć ruch do listy if(position.x >= 1 && position.y < TILES_COUNT-1) if(!getPawn(position+Vector(-1, 1))) movements.push_back(Movement(position, position+Vector(-1, 1))); // Jeżeli ruch w dół-prawo jest możliwy (jest puste miejsce) dorzuć ruch do listy if(position.x < TILES_COUNT-1 && position.y < TILES_COUNT-1) if(!getPawn(position+Vector(1, 1))) movements.push_back(Movement(position, position+Vector(1, 1))); } } return movements; } std::list Board::getPossibleGlobalBeatings(Color color) { std::list movements; // Dla każdych pionków for(int x = 0; x < TILES_COUNT; ++x) for(int y = 0; y < TILES_COUNT; ++y) { // Jeżeli to jest pionek if(board[x][y]) { // Jeżeli jest to pionek o który nam chodzi if(board[x][y]->getColor() == color) // Dodaj wszystkie jego możliwe ruchy do listy ruchów for(auto m: getPossibleBeatings(Vector(x, y))) movements.push_back(m); } } return movements; } std::list Board::getPossibleGlobalMovements(Color color) { std::list movements; // Jeżeli istnieją bicia zwracamy tylko je if(arePossibleGlobalBeatings(color)) return getPossibleGlobalBeatings(color); // Dla każdych pionków for(int x = 0; x < TILES_COUNT; ++x) for(int y = 0; y < TILES_COUNT; ++y) { // Jeżeli to jest pionek if(board[x][y]) { // Jeżeli jest to pionek o który nam chodzi if(board[x][y]->getColor() == color) // Dodaj wszystkie jego możliwe ruchy do listy ruchów for(auto m: getPossibleMovements(Vector(x, y))) movements.push_back(m); } } return movements; } void Board::display() { // Wyświetl poziomą linię for(int i=0; igetColor() == CL_WHITE) std::cout << " O "; else std::cout << " @ "; } else std::cout << " "; } std::cout << "|" << std::endl; // Pozioma linia for(int i=0; igetColor()); // Jeżeli ten pionek jest damką ... if(original.board[x][y]->isQueen()) // ... to promujemy nowoutworzonego pionka na damkę board[x][y]->upgrade(); } } } unsigned int Board::getNumberOfWhitePawns() const { // Inicjujemy licznik unsigned int count = 0; // Przeglądamy calą planszę for(int x = 0; x < TILES_COUNT; ++x) for(int y = 0; y < TILES_COUNT; ++y) // Jeśli znajdziemy biały pionek, zwiększamy licznik o 1 if(board[x][y] && board[x][y]->getColor() == CL_WHITE) ++count; return count; } unsigned int Board::getNumberOfBlackPawns() const { // Inicjujemy licznik unsigned int count = 0; // Przeglądamy calą planszę for(int x = 0; x < TILES_COUNT; ++x) for(int y = 0; y < TILES_COUNT; ++y) // Jeśli znajdziemy czarny pionek, zwiększamy licznik o 1 if(board[x][y] && board[x][y]->getColor() == CL_BLACK) ++count; return count; } void Board::upgrade() { // Dla całej szerokości planszy (czyli całej linii) for(int x = 0; x < TILES_COUNT; ++x) { // Jeśli na górnej linii promocji znajduje się biały pionek, promuj go if(board[x][0] && board[x][0]->getColor() == CL_WHITE) board[x][0]->upgrade(); // Jeśli na dolnej linii promocji znajduje się czarny pionek, promuj go if(board[x][TILES_COUNT-1] && board[x][TILES_COUNT-1]->getColor() == CL_BLACK) board[x][TILES_COUNT-1]->upgrade(); } } void Board::selectMovement(Movement movement) { is_selected_movement = true; selected_tiles.push_back(movement.begin); selected_tiles.push_back(movement.end); }