#include "Chessboard.h" #include "Figure.h" #include "Position.h" #include #include #include #include #include #include Cell Chessboard::get_cell(Position p) { return get_icell(p.posNum-'0'-1, p.posSym-'A'); } bool compare_by_angle(std::pair pos1, std::pair pos2) { if (std::atan2(pos1.first, pos1.second) == std::atan2(pos2.first, pos2.second)) return bool(std::abs(pos1.first) < std::abs(pos2.first) or std::abs(pos1.second) < std::abs(pos2.second)); return std::atan2(pos1.first, pos1.second) < std::atan2(pos2.first, pos2.second); } vector Chessboard::get_possible_moves(Figure* fig) { // std::cout << "\n\n\n1111111111\n\n\n"; vector moves = fig->get_moves(); vector> grouped_moves; vector possible_moves; Position pos = fig->get_position(); // Нормализуем массив for(int i = 0; i < moves.size(); i++) grouped_moves.push_back(std::pair(moves[i].posSym-pos.posSym, moves[i].posNum-pos.posNum)); // Сортируем по углу и удалённости от фигуры sort(grouped_moves.begin(), grouped_moves.end(), compare_by_angle); bool blockedGroup = false; // Проверяем первую фигуру Figure* check_cell; check_cell = board[grouped_moves[0].second+pos.posNum-'0'-1][grouped_moves[0].first+pos.posSym-'A'].get_figure(); if (check_cell != nullptr) { blockedGroup = true; if (check_cell->get_color() != fig->get_color()) possible_moves.push_back(Position(grouped_moves[0].first+pos.posSym, (char)(grouped_moves[0].second+pos.posNum))); } else possible_moves.push_back(Position((char)(grouped_moves[0].first+pos.posSym), (char)(grouped_moves[0].second+pos.posNum))); // Проверяем остальные for(int i = 1; i < grouped_moves.size(); i++) { // Разделение на разные группы по углу относ фигуры if (std::atan2(grouped_moves[i-1].first, grouped_moves[i-1].second) != std::atan2(grouped_moves[i].first, grouped_moves[i].second)) { blockedGroup = false; } // Пропускаем позиции перед которыми препядствие if (blockedGroup == true) continue; check_cell = board[grouped_moves[i].second+pos.posNum-'0'-1][grouped_moves[i].first+pos.posSym-'A'].get_figure(); // Добавление if (check_cell != nullptr) { blockedGroup = true; if (check_cell->get_color() != fig->get_color()) possible_moves.push_back(Position(grouped_moves[i].first+pos.posSym, (char)(grouped_moves[i].second+pos.posNum))); continue; } possible_moves.push_back(Position((char)(grouped_moves[i].first+pos.posSym), (char)(grouped_moves[i].second+pos.posNum))); } if (fig->print()[2] == "♟"[2] or fig->print()[2] == "♙"[2]) { // std::cout << "pawn\n"; // std::cout << (char)(possible_moves[0].posSym+1) << (char)(possible_moves[0].posNum) << '\n'; try { // std::cout << possible_moves[0].posSym+1 << possible_moves[0].posNum << '\n'; if (possible_moves.size() > 0 and get_cell(Position(possible_moves[0].posSym+1, possible_moves[0].posNum)).get_figure() != nullptr and get_cell(Position(possible_moves[0].posSym+1, possible_moves[0].posNum)).get_figure()->get_color() != fig->get_color()) possible_moves.push_back(Position(possible_moves[0].posSym+1, possible_moves[0].posNum)); } catch( std::invalid_argument ) {} // std::cout << (char)(possible_moves[0].posSym+1) << (char)(possible_moves[0].posNum) << '\n'; try { // std::cout << possible_moves[0].posSym+1 << possible_moves[0].posNum << '\n'; if (possible_moves.size() > 0 and get_cell(Position(possible_moves[0].posSym-1, possible_moves[0].posNum)).get_figure() != nullptr and get_cell(Position(possible_moves[0].posSym-1, possible_moves[0].posNum)).get_figure()->get_color() != fig->get_color()) possible_moves.push_back(Position(possible_moves[0].posSym-1, possible_moves[0].posNum)); } catch( std::invalid_argument ) {} if (possible_moves.size() > 0 and get_cell(possible_moves[0]).get_figure() != nullptr ) { vector possible_swap; for(int i = 1; i < possible_moves.size(); i++) { possible_swap.push_back(possible_moves[i]); } possible_moves = possible_swap; } } return possible_moves; } Chessboard::Chessboard() { board = new Cell*[8]; for(int i = 0; i < 8; i++) board[i] = new Cell[8]; } Chessboard::Chessboard(vector figures) { board = new Cell*[8]; for(int i = 0; i < 8; i++) board[i] = new Cell[8]; Position p; for(int i = 0; i < figures.size(); i++) { p = figures[i]->get_position(); board[p.posNum-'0'-1][p.posSym-'A'] = Cell(figures[i]); } } Chessboard Chessboard::copy() { vector my_figures; for(int i = 0; i < 8; i++) { for(int j = 0; j < 8; j++) { if (get_icell(i,j).get_figure() != nullptr) my_figures.push_back(get_icell(i,j).get_figure()->copy()); } } return Chessboard(my_figures); } void Chessboard::create_move(Position pos1, Position pos2) { Figure* fig = get_cell(pos1).get_figure(); vector pos_moves = get_possible_moves(fig); // std::cout << pos1 << ' ' << fig->print() << '\n'; // for(int i = 0; i < pos_moves.size(); i++) std::cout << pos_moves[i] << ";"; // std::cout << '\n'; for(int i = 0; i < pos_moves.size(); i++) { if (pos_moves[i].posSym == pos2.posSym and pos_moves[i].posNum == pos2.posNum) { fig->set_position(Position((char)pos2.posSym, pos2.posNum)); board[pos2.posNum-'0'-1][pos2.posSym-'A'] = Cell(fig); board[pos1.posNum-'0'-1][pos1.posSym-'A'] = Cell(); return; } } throw std::invalid_argument("Impossible move"); } Cell Chessboard::get_icell(int index, int jindex) { if (not (index >= 0 and index < 8 and jindex >= 0 and jindex < 8)) throw std::invalid_argument("Trying to get figure out of board"); return board[index][jindex]; } std::ostream& operator <<(std::ostream& out, Chessboard& chess) { vector figures; for (int i = 7; i >= 0; i--) { for(int j = 0; j < 8; j++) { out << chess.board[i][j]; if (chess.board[i][j].get_figure() != nullptr) { figures.push_back(chess.board[i][j].get_figure()); } } out << '\n'; } // Дебаг ходов // vector grouped_moves; // for(int j = 0; j < figures.size(); j++) { // grouped_moves = chess.get_possible_moves(figures[j]); // std::cout << figures[j]->print() << ' ' << figures[j]->get_position().posSym << figures[j]->get_position().posNum << ' '; // for(int i = 0; i < grouped_moves.size(); i++) { // std::cout << grouped_moves[i] << ';'; // } // std::cout << std::endl; // } return out; }