123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182 |
- #include "Chessboard.h"
- #include "Figure.h"
- #include "Position.h"
- #include <iostream>
- #include <vector>
- #include <algorithm>
- #include <math.h>
- #include <utility>
- #include <stdexcept>
- Cell Chessboard::get_cell(Position p)
- {
- return get_icell(p.posNum-'0'-1, p.posSym-'A');
- }
- bool compare_by_angle(std::pair<int, int> pos1, std::pair<int, int> 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<Position> Chessboard::get_possible_moves(Figure* fig)
- {
- // std::cout << "\n\n\n1111111111\n\n\n";
- vector<Position> moves = fig->get_moves();
- vector<std::pair<int, int>> grouped_moves;
- vector<Position> possible_moves;
- Position pos = fig->get_position();
- // Нормализуем массив
- for(int i = 0; i < moves.size(); i++) grouped_moves.push_back(std::pair<int, int>(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<Position> 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<Figure*> 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<Figure*> 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<Position> 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<Figure*> 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<Position> 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;
- }
|