#include <iostream>
#include <vector>

struct Point {
	int x, y;
	Point(int x, int y) : x(x), y(y) {}
};

class Chess {
public:
	Chess() {
		// Инициализация доски
		board.resize(8, std::vector<int>(8, 0));

		// Установка начальных позиций фигур
		// 1 - пешка, 2 - ладья, 3 - конь, 4 - слон, 5 - королева, 6 - король
		for (int i = 0; i < 8; i++) {
			board[1][i] = 1; // Пешки на 2 строке
			board[6][i] = -1; // Пешки на 7 строке
		}
		board[0][0] = 2; board[0][7] = 2; // Ладьи на 1 строке
		board[7][0] = -2; board[7][7] = -2; // Ладьи на 8 строке
		board[0][1] = 3; board[0][6] = 3; // Кони на 1 строке
		board[7][1] = -3; board[7][6] = -3; // Кони на 8 строке
		board[0][2] = 4; board[0][5] = 4; // Слоны на 1 строке
		board[7][2] = -4; board[7][5] = -4; // Слоны на 8 строке
		board[0][3] = 5; // Королева на 1 строке
		board[7][3] = -5; // Королева на 8 строке
		board[0][4] = 6; // Король на 1 строке
		board[7][4] = -6; // Король на 8 строке
	}

	// Возвращает все возможные ходы для данной фигуры на данной позиции
	std::vector<Point> getPossibleMoves(int x, int y) {
		int piece = board[x][y];
		std::vector<Point> possibleMoves;

		if (piece == 1 || piece == -1) { // Пешка
			if (validPosition(x + piece, y) && board[x + piece][y] == 0) {
				possibleMoves.push_back(Point(x + piece, y));
			}
			if (x == 1 || x == 6) { // Пешка на начальной позиции
				if (validPosition(x + 2 * piece, y) && board[x + 2 * piece][y] == 0) {
					possibleMoves.push_back(Point(x + 2 * piece, y));
				}
			}
			if (validPosition(x + piece, y - 1) && board[x + piece][y - 1] * piece < 0) {
				possibleMoves.push_back(Point(x + piece, y - 1));
			}
			if (validPosition(x + piece, y + 1) && board[x + piece][y + 1] * piece < 0) {
				possibleMoves.push_back(Point(x + piece, y + 1));
			}
		}
		else if (piece == 2 || piece == -2) { // Ладья
			for (int i = 1; i < 8; i++) {
				if (validPosition(x + i, y) && board[x + i][y] == 0) {
					possibleMoves.push_back(Point(x + i, y));
				}
				else if (validPosition(x + i, y) && board[x + i][y] * piece < 0) {
					possibleMoves.push_back(Point(x + i, y));
					break;
				}
				else {
					break;
				}
			}
			for (int i = 1; i < 8; i++) {
				if (validPosition(x - i, y) && board[x - i][y] == 0) {
					possibleMoves.push_back(Point(x - i, y));
				}
				else if (validPosition(x - i, y) && board[x - i][y] * piece < 0) {
					possibleMoves.push_back(Point(x - i, y));
					break;
				}
				else {
					break;
				}
			}
			for (int i = 1; i < 8; i++) {
				if (validPosition(x, y + i) && board[x][y + i] == 0) {
					possibleMoves.push_back(Point(x, y + i));
				}
				else if (validPosition(x, y + i) && board[x][y + i] * piece < 0) {
					possibleMoves.push_back(Point(x, y + i));
					break;
				}
				else {
					break;
				}
			}
			for (int i = 1; i < 8; i++) {
				if (validPosition(x, y - i) && board[x][y - i] == 0) {
					possibleMoves.push_back(Point(x, y - i));
				}
				else if (validPosition(x, y - i) && board[x][y - i] * piece < 0) {
					possibleMoves.push_back(Point(x, y - i));
					break;
				}
				else {
					break;
				}
			}
		}
		else if (piece == 3 || piece == -3) { // Конь
			std::vector<Point> knightMoves;
			knightMoves.push_back(Point(x + 2, y + 1));
			knightMoves.push_back(Point(x + 2, y - 1));
			knightMoves.push_back(Point(x - 2, y + 1));
			knightMoves.push_back(Point(x - 2, y - 1));
			knightMoves.push_back(Point(x + 1, y + 2));
			knightMoves.push_back(Point(x + 1, y - 2));
			knightMoves.push_back(Point(x - 1, y + 2));
			knightMoves.push_back(Point(x - 1, y - 2));

			for (const auto& move : knightMoves) {
				if (validPosition(move.x, move.y) && (board[move.x][move.y] == 0 || board[move.x][move.y] * piece < 0)) {
					possibleMoves.push_back(move);
				}
			}
		}
		else if (piece == 4 || piece == -4) { // Слон
			for (int i = 1; i < 8; i++) {
				if (validPosition(x + i, y + i) && board[x + i][y + i] == 0) {
					possibleMoves.push_back(Point(x + i, y + i));
				}
				else if (validPosition(x + i, y + i) && board[x + i][y + i] * piece < 0) {
					possibleMoves.push_back(Point(x + i, y + i));
					break;
				}
				else {
					break;
				}
			}
			for (int i = 1; i < 8; i++) {
				if (validPosition(x + i, y - i) && board[x + i][y - i] == 0) {
					possibleMoves.push_back(Point(x + i, y - i));
				}
				else if (validPosition(x + i, y - i) && board[x + i][y - i] * piece < 0) {
					possibleMoves.push_back(Point(x + i, y - i));
					break;
				}
				else {
					break;
				}
			}
			for (int i = 1; i < 8; i++) {
				if (validPosition(x - i, y + i) && board[x - i][y + i] == 0) {
					possibleMoves.push_back(Point(x - i, y + i));
				}
				else if (validPosition(x - i, y + i) && board[x - i][y + i] * piece < 0) {
					possibleMoves.push_back(Point(x - i, y + i));
					break;
				}
				else {
					break;
				}
			}
			for (int i = 1; i < 8; i++) {
				if (validPosition(x - i, y - i) && board[x - i][y - i] == 0) {
					possibleMoves.push_back(Point(x - i, y - i));
				}
				else if (validPosition(x - i, y - i) && board[x - i][y - i] * piece < 0) {
					possibleMoves.push_back(Point(x - i, y - i));
					break;
				}
				else {
					break;
				}
			}
		}
		else if (piece == 5 || piece == -5) { // Королева
			for (int i = 1; i < 8; i++) {
				if (validPosition(x + i, y) && board[x + i][y] == 0) {
					possibleMoves.push_back(Point(x + i, y));
				}
				else if (validPosition(x + i, y) && board[x + i][y] * piece < 0) {
					possibleMoves.push_back(Point(x + i, y));
					break;
				}
				else {
					break;
				}
			}
			for (int i = 1; i < 8; i++) {
				if (validPosition(x - i, y) && board[x - i][y] == 0) {
					possibleMoves.push_back(Point(x - i, y));
				}
				else if (validPosition(x - i, y) && board[x - i][y] * piece < 0) {
					possibleMoves.push_back(Point(x - i, y));
					break;
				}
				else {
					break;
				}
			}
			for (int i = 1; i < 8; i++) {
				if (validPosition(x, y + i) && board[x][y + i] == 0) {
					possibleMoves.push_back(Point(x, y + i));
				}
				else if (validPosition(x, y + i) && board[x][y + i] * piece < 0) {
					possibleMoves.push_back(Point(x, y + i));
					break;
				}
				else {
					break;
				}
			}
			for (int i = 1; i < 8; i++) {
				if (validPosition(x, y - i) && board[x][y - i] == 0) {
					possibleMoves.push_back(Point(x, y - i));
				}
				else if (validPosition(x, y - i) && board[x][y - i] * piece < 0) {
					possibleMoves.push_back(Point(x, y - i));
					break;
				}
				else {
					break;
				}
			}
			for (int i = 1; i < 8; i++) {
				if (validPosition(x + i, y + i) && board[x + i][y + i] == 0) {
					possibleMoves.push_back(Point(x + i, y + i));
				}
				else if (validPosition(x + i, y + i) && board[x + i][y + i] * piece < 0) {
					possibleMoves.push_back(Point(x + i, y + i));
					break;
				}
				else {
					break;
				}
			}
			for (int i = 1; i < 8; i++) {
				if (validPosition(x + i, y - i) && board[x + i][y - i] == 0) {
					possibleMoves.push_back(Point(x + i, y - i));
				}
				else if (validPosition(x + i, y - i) && board[x + i][y - i] * piece < 0) {
					possibleMoves.push_back(Point(x + i, y - i));
					break;
				}
				else {
					break;
				}
			}
			for (int i = 1; i < 8; i++) {
				if (validPosition(x - i, y + i) && board[x - i][y + i] == 0) {
					possibleMoves.push_back(Point(x - i, y + i));
				}
				else if (validPosition(x - i, y + i) && board[x - i][y + i] * piece < 0) {
					possibleMoves.push_back(Point(x - i, y + i));
					break;
				}
				else {
					break;
				}
			}
			for (int i = 1; i < 8; i++) {
				if (validPosition(x - i, y - i) && board[x - i][y - i] == 0) {
					possibleMoves.push_back(Point(x - i, y - i));
				}
				else if (validPosition(x - i, y - i) && board[x - i][y - i] * piece < 0) {
					possibleMoves.push_back(Point(x - i, y - i));
					break;
				}
				else {
					break;
				}
			}
		}
		else if (piece == 6 || piece == -6) { // Король
			std::vector<Point> kingMoves;
			kingMoves.push_back(Point(x + 1, y));
			kingMoves.push_back(Point(x - 1, y));
			kingMoves.push_back(Point(x, y + 1));
			kingMoves.push_back(Point(x, y - 1));
			kingMoves.push_back(Point(x + 1, y - 1));
			kingMoves.push_back(Point(x + 1, y + 1));
			kingMoves.push_back(Point(x - 1, y - 1));
			kingMoves.push_back(Point(x - 1, y + 1));

			for (const auto& move : kingMoves) {
				if (validPosition(move.x, move.y) && (board[move.x][move.y] == 0 || board[move.x][move.y] * piece < 0)) {
					possibleMoves.push_back(move);
				}
			}
		}

		return possibleMoves;
	}

	// Проверяет, находится ли точка на доске
	bool validPosition(int x, int y) {
		return x >= 0 && x < 8 && y >= 0 && y < 8;
	}

	// Выводит все возможные ходы для всех фигур
	void printPossibleMoves() {
		for (int i = 0; i < 8; i++) {
			for (int j = 0; j < 8; j++) {
				std::cout << "Possible moves for piece at position (" << i << ", " << j << "): ";
				std::vector<Point> possibleMoves = getPossibleMoves(i, j);
				for (const auto& move : possibleMoves) {
					std::cout << "(" << move.x << ", " << move.y << ") ";
				}
				std::cout << std::endl;
			}
		}
	}

private:
	std::vector<std::vector<int>> board;
};

int main() {
	Chess chess;
	chess.printPossibleMoves();
	
	return 0;
}