代码求调
查看原帖
代码求调
1058102
HSAS_SP楼主2024/10/23 18:36

代码求调

#include <bits/stdc++.h>
namespace Problem {
	int q;
	class Board {
		public:
			struct Gird {
				enum Chess {
					None, Captain, Guard, Elephant, Horse, Car, Duck, Soldier
				} piece;
				enum Camp {
					Blank, Blue, Red
				} camp;
				friend std::ostream& operator << (std::ostream& out, Gird gird) {
					switch (gird.camp) {
						case Gird::Blank: {
							out << "NA";
							return out;
						}
						case Gird::Blue: {
							out << "blue";
							break;
						}
						case Gird::Red: {
							out << "red";
							break;
						}
					} 
					out << " ";
					switch (gird.piece) {
						case Gird::Captain: {
							out << "captain";
							break;
						}
						case Gird::Guard: {
							out << "guard";
							break;
						}
						case Gird::Elephant: {
							out << "elephant";
							break;
						}
						case Gird::Horse: {
							out << "horse";
							break;
						}
						case Gird::Car: {
							out << "car";
							break;
						}
						case Gird::Duck: {
							out << "duck";
							break;
						}
						case Gird::Soldier: {
							out << "soldier";
							break;
						}
						case Gird::None: {
							out << "None";
							break;
						}
					}
					return out;
				}
			};
			struct Point {
				int x, y;
			};
			struct Result {
				Gird from, to;
				bool success, checkmate, end;
				friend std::ostream& operator << (std::ostream &out, Result result) {
					if (result.success) {
						out << result.from << ";" << result.to << ";" << (result.checkmate ? "yes" : "no") << ";" << (result.end ? "yes" : "no");
					} else {
						out << "Invalid command";
					}
					return out;
				}
			};
		private:
			Gird gird[10][9] = {
				{{Gird::Car, Gird::Red}, {Gird::Horse, Gird::Red}, {Gird::Elephant, Gird::Red}, {Gird::Guard, Gird::Red}, {Gird::Captain, Gird::Red}, {Gird::Guard, Gird::Red}, {Gird::Elephant, Gird::Red}, {Gird::Horse, Gird::Red}, {Gird::Car, Gird::Red}},
				{{Gird::None, Gird::Blank}, {Gird::None, Gird::Blank}, {Gird::None, Gird::Blank}, {Gird::None, Gird::Blank}, {Gird::None, Gird::Blank}, {Gird::None, Gird::Blank}, {Gird::None, Gird::Blank}, {Gird::None, Gird::Blank}, {Gird::None, Gird::Blank}},
				{{Gird::Duck, Gird::Red}, {Gird::None, Gird::Blank}, {Gird::None, Gird::Blank}, {Gird::None, Gird::Blank}, {Gird::None, Gird::Blank}, {Gird::None, Gird::Blank}, {Gird::None, Gird::Blank}, {Gird::None, Gird::Blank}, {Gird::Duck, Gird::Red}},
				{{Gird::Soldier, Gird::Red}, {Gird::None, Gird::Blank}, {Gird::Soldier, Gird::Red}, {Gird::None, Gird::Blank}, {Gird::Soldier, Gird::Red}, {Gird::None, Gird::Blank}, {Gird::Soldier, Gird::Red}, {Gird::None, Gird::Blank}, {Gird::Soldier, Gird::Red}},
				{{Gird::None, Gird::Blank}, {Gird::None, Gird::Blank}, {Gird::None, Gird::Blank}, {Gird::None, Gird::Blank}, {Gird::None, Gird::Blank}, {Gird::None, Gird::Blank}, {Gird::None, Gird::Blank}, {Gird::None, Gird::Blank}, {Gird::None, Gird::Blank}},
				{{Gird::None, Gird::Blank}, {Gird::None, Gird::Blank}, {Gird::None, Gird::Blank}, {Gird::None, Gird::Blank}, {Gird::None, Gird::Blank}, {Gird::None, Gird::Blank}, {Gird::None, Gird::Blank}, {Gird::None, Gird::Blank}, {Gird::None, Gird::Blank}},
				{{Gird::Soldier, Gird::Blue}, {Gird::None, Gird::Blank}, {Gird::Soldier, Gird::Blue}, {Gird::None, Gird::Blank}, {Gird::Soldier, Gird::Blue}, {Gird::None, Gird::Blank}, {Gird::Soldier, Gird::Blue}, {Gird::None, Gird::Blank}, {Gird::Soldier, Gird::Blue}},
				{{Gird::Duck, Gird::Blue}, {Gird::None, Gird::Blank}, {Gird::None, Gird::Blank}, {Gird::None, Gird::Blank}, {Gird::None, Gird::Blank}, {Gird::None, Gird::Blank}, {Gird::None, Gird::Blank}, {Gird::None, Gird::Blank}, {Gird::Duck, Gird::Blue}},
				{{Gird::None, Gird::Blank}, {Gird::None, Gird::Blank}, {Gird::None, Gird::Blank}, {Gird::None, Gird::Blank}, {Gird::None, Gird::Blank}, {Gird::None, Gird::Blank}, {Gird::None, Gird::Blank}, {Gird::None, Gird::Blank}, {Gird::None, Gird::Blank}},
				{{Gird::Car, Gird::Blue}, {Gird::Horse, Gird::Blue}, {Gird::Elephant, Gird::Blue}, {Gird::Guard, Gird::Blue}, {Gird::Captain, Gird::Blue}, {Gird::Guard, Gird::Blue}, {Gird::Elephant, Gird::Blue}, {Gird::Horse, Gird::Blue}, {Gird::Car, Gird::Blue}},
			};
			Point red_captain = {0, 4}, blue_captain = {8, 4};
			bool is_end = false;
			bool can_move_captain(const Point from, const Point to) {
				return !this->same_camp(from, to) && std::abs(from.x - to.x) + std::abs(from.y - to.y) == 1;
			}
			bool can_move_guard(const Point from, const Point to) {
				return !this->same_camp(from, to) && std::abs(from.x - to.x) == 1 && std::abs(from.y - to.y) == 1;
			}
			bool can_move_elephant(const Point from, const Point to) {
				return !this->same_camp(from, to) && std::abs(from.x - to.x) == 2 && std::abs(from.y - to.y) == 2 && this->get_gird({from.x + to.x >> 1, from.y + to.y >> 1}).piece == Gird::None;
			}
			bool can_move_horse(const Point from, const Point to) {
				return !this->same_camp(from, to) && (
					(from.x + 2 == to.x && from.y + 1 == to.y && this->get_gird({from.x + 1, from.y}).piece == Gird::None) ||
					(from.x + 2 == to.x && from.y - 1 == to.y && this->get_gird({from.x + 1, from.y}).piece == Gird::None) ||
					(from.x + 1 == to.x && from.y + 2 == to.y && this->get_gird({from.x, from.y + 1}).piece == Gird::None) ||
					(from.x + 1 == to.x && from.y - 2 == to.y && this->get_gird({from.x, from.y - 1}).piece == Gird::None) ||
					(from.x - 2 == to.x && from.y + 1 == to.y && this->get_gird({from.x - 1, from.y}).piece == Gird::None) ||
					(from.x - 2 == to.x && from.y - 1 == to.y && this->get_gird({from.x - 1, from.y}).piece == Gird::None) ||
					(from.x - 1 == to.x && from.y + 2 == to.y && this->get_gird({from.x, from.y + 1}).piece == Gird::None) ||
					(from.x - 1 == to.x && from.y - 2 == to.y && this->get_gird({from.x, from.y - 1}).piece == Gird::None)
				);
			}
			bool can_move_car(const Point from, const Point to) {
				if (this->same_camp(from, to)) {
					return false;
				}
				if (from.x == to.x) {
					if (from.y < to.y) {
						for (int y = from.y + 1; y < to.y; y++) {
							if (this->get_gird({from.x, y}).piece != Gird::None) {
								return false;
							}
						}
					} else {
						for (int y = from.y - 1; y > to.y; y--) {
							if (this->get_gird({from.x, y}).piece != Gird::None) {
								return false;
							}
						}
					}
					return true;
				} else if (from.y == to.y) {
					if (from.x < to.x) {
						for (int x = from.x + 1; x < to.x; x++){
							if (this->get_gird({x, from.y}).piece != Gird::None) {
								return false;
							}
						}
					} else {
						for (int x = from.x - 1; x > to.x; x--){
							if (this->get_gird({x, from.y}).piece != Gird::None) {
								return false;
							}
						}
					}
					return true;
				} else {
					return false;
				}
			}
			bool can_move_duck(const Point from, const Point to) {
				return !this->same_camp(from, to) && (
					(from.x + 3 == to.x && from.y + 2 == to.y && this->get_gird({from.x + 1, from.y}).piece == Gird::None && this->get_gird({from.x + 2, from.y + 1}).piece == Gird::None) ||
					(from.x + 3 == to.x && from.y - 2 == to.y && this->get_gird({from.x + 1, from.y}).piece == Gird::None && this->get_gird({from.x + 2, from.y - 1}).piece == Gird::None) ||
					(from.x + 2 == to.x && from.y + 3 == to.y && this->get_gird({from.x, from.y + 1}).piece == Gird::None && this->get_gird({from.x + 1, from.y + 2}).piece == Gird::None) ||
					(from.x + 2 == to.x && from.y - 3 == to.y && this->get_gird({from.x, from.y - 1}).piece == Gird::None && this->get_gird({from.x + 1, from.y - 2}).piece == Gird::None) ||
					(from.x - 3 == to.x && from.y + 2 == to.y && this->get_gird({from.x - 1, from.y}).piece == Gird::None && this->get_gird({from.x - 2, from.y + 1}).piece == Gird::None) ||
					(from.x - 3 == to.x && from.y - 2 == to.y && this->get_gird({from.x - 1, from.y}).piece == Gird::None && this->get_gird({from.x - 2, from.y - 1}).piece == Gird::None) ||
					(from.x - 2 == to.x && from.y + 3 == to.y && this->get_gird({from.x, from.y + 1}).piece == Gird::None && this->get_gird({from.x - 1, from.y + 2}).piece == Gird::None) ||
					(from.x - 2 == to.x && from.y - 3 == to.y && this->get_gird({from.x, from.y - 1}).piece == Gird::None && this->get_gird({from.x - 1, from.y - 2}).piece == Gird::None)
				);
			}
			bool can_move_soldier(const Point from, const Point to) {
				const int xd = std::abs(from.x - to.x), yd = std::abs(from.y - to.y);
				return !this->same_camp(from, to) && (xd == 0 || xd == 1) && (yd == 0 || yd == 1);
			}
		public:
			Board() {}
			Gird get_gird(const Point point) {
				if (point.x >= 0 && point.x < 10 && point.y >= 0 && point.y < 9) {
					return this->gird[point.x][point.y];
				} else {
					return {Gird::None, Gird::Blank};
				}
			}
			void set_gird(const Point point, const Gird gird) {
				if (point.x >= 0 && point.x < 10 && point.y >= 0 && point.y < 9) {
					this->gird[point.x][point.y] = gird;
				}
			}
			bool same_camp(const Point a, const Point b) {
				const Gird::Camp camp = this->get_gird(a).camp;
				return camp != Gird::Blank && camp == this->get_gird(b).camp;
			}
			bool can_move_chess(Point from, Point to) {
				Gird gird = this->get_gird(from);
				switch (gird.piece) {
					case Gird::None: {
						return false;
					}
					case Gird::Captain: {
						return can_move_captain(from, to);
					}
					case Gird::Guard: {
						return can_move_guard(from, to);
					}
					case Gird::Elephant: {
						return can_move_elephant(from, to);
					}
					case Gird::Horse: {
						return can_move_horse(from, to);
					}
					case Gird::Car: {
						return can_move_car(from, to);
					}
					case Gird::Duck: {
						return can_move_duck(from, to);
					}
					case Gird::Soldier: {
						return can_move_soldier(from, to);
					}
				}
			}
			bool move_chess(Point from, Point to) {
				if (can_move_chess(from, to) && !this->is_end) {
					const Gird from_piece = this->get_gird(from), to_piece = this->get_gird(to);
					if (to_piece.piece == Gird::Captain) {
						this->is_end = true;
					}
					if (from_piece.piece == Gird::Captain) {
						if (from_piece.camp == Gird::Red) {
							this->red_captain = to;
						} else {
							this->blue_captain = to;
						}
					}
					this->set_gird(to, from_piece);
					this->set_gird(from, {Gird::None, Gird::Blank});
					return true;
				} else {
					return false;
				}
			}
			bool is_checkmate(Gird::Camp camp) {
				if (camp == Gird::Red) {
					const Gird captain_gird = this->get_gird(this->red_captain);
					if (captain_gird.piece != Gird::Captain || captain_gird.camp != Gird::Red) {
						return false;
					}
					for (int x = 0; x < 10; x++) {
						for (int y = 0; y < 9; y++) {
							if (can_move_chess({x, y}, this->red_captain)) {
								return true;
							}
						}
					}
				} else if (camp == Gird::Blue) {
					const Gird captain_gird = this->get_gird(this->blue_captain);
					if (captain_gird.piece != Gird::Captain || captain_gird.camp != Gird::Blue) {
						return false;
					}
					for (int x = 0; x < 10; x++) {
						for (int y = 0; y < 9; y++) {
							if (can_move_chess({x, y}, this->blue_captain)) {
								return true;
							}
						}
					}
				}
				return false;
			}
			Point get_red_captain_point() {
				return this->red_captain;
			}
			Point get_blue_captain_point() {
				return this->blue_captain;
			}
			Result update(Gird::Camp camp, Point from, Point to) {
				Result result = {get_gird(from), get_gird(to), false, false, false};
				if (this->is_end || this->get_gird(from).camp != camp || !this->move_chess(from, to)) {
					return result;
				}
				result.success = true;
				result.checkmate = this->is_checkmate(camp) || this->is_checkmate(camp == Gird::Red ? Gird::Blue : Gird::Red);
				result.end = this->is_end;
				return result;
			} 
			friend std::ostream& operator << (std::ostream &out, Board board) {
				out << "pieces on the board:\n";
				for (int i = 9; i >= 0; i--) {
					for (int j = 0; j < 9; j++) {
						out << "[" << std::setw(16) << board.get_gird({i, j}) << "]";
					}
					out << "\n";
				}
				return out;
			}
	} board;
	Board::Gird::Camp recent = Board::Gird::Red;
	int main() {
//		std::ios::sync_with_stdio(false);
//		std::cin.tie(nullptr);
//		std::cout.tie(nullptr);
		std::cin >> q;
		for (int i = 0, x1, y1, x2, y2; i < q; i++) {
			std::cin >> x1 >> y1 >> x2 >> y2;
			Board::Result result = board.update(recent, {x1, y1}, {x2, y2});
			std::cout << result << '\n';
			if (result.success) {
				if (recent == Board::Gird::Red) {
					recent = Board::Gird::Blue;
				} else {
					recent = Board::Gird::Red;
				}
//				std::cout << board;
			}
		}
		return 0;
	}
}
int main() {
	return Problem::main();
}
2024/10/23 18:36
加载中...