Chessboard.cpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. #include "Chessboard.h"
  2. #include "Figure.h"
  3. #include "Position.h"
  4. #include <iostream>
  5. #include <vector>
  6. #include <algorithm>
  7. #include <math.h>
  8. #include <utility>
  9. #include <stdexcept>
  10. std::ostream& operator <<(std::ostream& out, Chessboard& chess)
  11. {
  12. for (int i = 7; i >= 0; i--) {
  13. for(int j = 0; j < 8; j++) {
  14. out << chess.board[i][j];
  15. }
  16. out << '\n';
  17. }
  18. return out;
  19. }
  20. Cell Chessboard::get_cell(Position p)
  21. {
  22. return get_icell(p.posNum-'0'-1, p.posSym-'A');
  23. }
  24. bool compare_by_angle(std::pair<int, int> pos1, std::pair<int, int> pos2)
  25. {
  26. if (std::atan2(pos1.first, pos1.second) == std::atan2(pos2.first, pos2.second))
  27. return bool(std::abs(pos1.first) < std::abs(pos2.first) or std::abs(pos1.second) < std::abs(pos2.second));
  28. return std::atan2(pos1.first, pos1.second) < std::atan2(pos2.first, pos2.second);
  29. }
  30. vector<Position> Chessboard::get_possible_moves(Figure* fig)
  31. {
  32. vector<Position> moves = fig->get_moves();
  33. // for(int i = 0; i < moves.size(); i++) std::cout << moves[i] << ';';
  34. // std::cout << '\n';
  35. vector<std::pair<int, int>> grouped_moves;
  36. vector<Position> possible_moves;
  37. Position pos = fig->get_position();
  38. // Нормализуем массив
  39. 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));
  40. // Сортируем по углу и удалённости от фигуры
  41. sort(grouped_moves.begin(), grouped_moves.end(), compare_by_angle);
  42. // for(int i = 0; i < grouped_moves.size(); i++) std::cout << char(grouped_moves[i].first+pos.posSym) << char(grouped_moves[i].second+pos.posNum) << ';';
  43. // std::cout << '\n';
  44. bool blockedGroup = false;
  45. Figure* check_cell;
  46. check_cell = board[grouped_moves[0].second+pos.posNum-'0'-1][grouped_moves[0].first+pos.posSym-'A'].get_figure();
  47. if (check_cell != nullptr) {
  48. blockedGroup = true;
  49. 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)));
  50. }
  51. else possible_moves.push_back(Position((char)(grouped_moves[0].first+pos.posSym), (char)(grouped_moves[0].second+pos.posNum)));
  52. for(int i = 1; i < grouped_moves.size(); i++) {
  53. if (std::atan2(grouped_moves[i-1].first, grouped_moves[i-1].second) != std::atan2(grouped_moves[i].first, grouped_moves[i].second)) {
  54. blockedGroup = false;
  55. }
  56. if (blockedGroup == true) continue;
  57. check_cell = board[grouped_moves[i].second+pos.posNum-'0'-1][grouped_moves[i].first+pos.posSym-'A'].get_figure();
  58. if (check_cell != nullptr) {
  59. blockedGroup = true;
  60. 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)));
  61. continue;
  62. }
  63. possible_moves.push_back(Position((char)(grouped_moves[i].first+pos.posSym), (char)(grouped_moves[i].second+pos.posNum)));
  64. }
  65. return possible_moves;
  66. }
  67. Chessboard::Chessboard()
  68. {
  69. board = new Cell*[8];
  70. for(int i = 0; i < 8; i++) board[i] = new Cell[8];
  71. }
  72. Chessboard::Chessboard(vector<Figure*> figures)
  73. {
  74. board = new Cell*[8];
  75. for(int i = 0; i < 8; i++) board[i] = new Cell[8];
  76. Position p;
  77. for(int i = 0; i < figures.size(); i++) {
  78. p = figures[i]->get_position();
  79. board[p.posNum-'0'-1][p.posSym-'A'] = Cell(figures[i]);
  80. }
  81. // vector<Position> grouped_moves;
  82. // for(int j = 0; j < figures.size(); j++) {
  83. // grouped_moves = get_possible_moves(figures[j]);
  84. // std::cout << figures[j]->print() << ' ';
  85. // for(int i = 0; i < grouped_moves.size(); i++) {
  86. // std::cout << grouped_moves[i] << ';';
  87. // }
  88. // std::cout << std::endl;
  89. // }
  90. }
  91. void Chessboard::create_move(Position pos1, Position pos2)
  92. {
  93. Figure* fig = get_cell(pos1).get_figure();
  94. vector<Position> pos_moves = get_possible_moves(fig);
  95. // std::cout << pos1 << ' ' << fig->print() << '\n';
  96. // for(int i = 0; i < pos_moves.size(); i++) std::cout << pos_moves[i] << ";";
  97. // std::cout << '\n';
  98. for(int i = 0; i < pos_moves.size(); i++) {
  99. if (pos_moves[i].posSym == pos2.posSym and pos_moves[i].posNum == pos2.posNum) {
  100. board[pos2.posNum-'0'-1][pos2.posSym-'A'] = Cell(fig);
  101. board[pos1.posNum-'0'-1][pos1.posSym-'A'] = Cell();
  102. return;
  103. }
  104. }
  105. throw std::invalid_argument("Impossible move");
  106. }
  107. Cell Chessboard::get_icell(int index, int jindex)
  108. {
  109. if (not (index >= 0 and index < 8 and jindex >= 0 and jindex < 8))
  110. throw std::invalid_argument("Trying to get figure out of board");
  111. return board[index][jindex];
  112. }