TurboSchach/ChessPieces/ChessPiecePosition.cpp
2025-01-07 16:27:31 +01:00

330 lines
12 KiB
C++

#include "../ChessPieces/ChessPiecePosition.hpp"
/**
* Creates a new chess piece position.
* @param position The chess piece position as string.
*/
ChessPiecePosition::ChessPiecePosition(std::string position) {
if (position.length() != 2) {
throw std::invalid_argument("invalid position");
} else {
this->SetFile(position[0]);
this->SetRank(position[1] - '0');
}
}
/**
* Creates a new chess piece position.
* @param file The file part of the chess piece position.
* @param rank The rank part of the chess piece position.
*/
ChessPiecePosition::ChessPiecePosition(char file, int rank) {
this->SetFile(file);
this->SetRank(rank);
}
/**
* Compares the current chess piece position with another chess piece position.
* @param position The other chess piece position to be checked with the current chess piece position.
*/
bool ChessPiecePosition::operator< (ChessPiecePosition const position) const {
if (this->_file == position._file) {
return this->_rank < position._rank;
} else {
return this->_file < position._file;
}
}
/**
* Compares the current chess piece position with another chess piece position.
* @param position The other chess piece position to be checked with the current chess piece position.
*/
bool ChessPiecePosition::operator== (ChessPiecePosition const position) const {
return this->_file == position._file && this->_rank == position._rank;
}
/**
* Gets the moves to reach the target chess piece position from the starting chess piece position.
* @param fromPosition The starting chess piece position.
* @param toPosition The target chess piece position.
* @return A string with the moves to reach the target chess piece position from the starting chess piece position.
* An empty string if the starting chess piece position is the same as the target chess piece position.
*/
std::string ChessPiecePosition::GetDifference(ChessPiecePosition fromPosition, ChessPiecePosition toPosition) {
if (fromPosition == toPosition) {
return "";
} else {
std::string difference;
if (toPosition.GetFile() < fromPosition.GetFile()) {
difference.append(std::string(1, ChessPiecePosition::_MOVE_LEFT) + std::to_string(fromPosition.GetFile() - toPosition.GetFile()));
} else if (toPosition.GetFile() > fromPosition.GetFile()) {
difference.append(std::string(1, ChessPiecePosition::_MOVE_RIGHT) + std::to_string(toPosition.GetFile() - fromPosition.GetFile()));
}
if (toPosition.GetRank() < fromPosition.GetRank()) {
difference.append(std::string(1, ChessPiecePosition::_MOVE_BOTTOM) + std::to_string(fromPosition.GetRank() - toPosition.GetRank()));
} else if (toPosition.GetRank() > fromPosition.GetRank()) {
difference.append(std::string(1, ChessPiecePosition::_MOVE_TOP) + std::to_string(toPosition.GetRank() - fromPosition.GetRank()));
}
return difference;
}
}
/**
* Gets the file part of the chess piece position.
* @return char The file part of the chess piece position.
*/
char ChessPiecePosition::GetFile() {
return this->_file;
}
/**
* Gets the rank part of the chess piece position.
* @return int The rank part of the chess piece position.
*/
int ChessPiecePosition::GetRank() {
return this->_rank;
}
/**
* Gets the step to reach the target chess piece position from the starting chess piece position.
* The amount of steps to reach the target chess piece position is not known but the target chess piece position is reachable.
* @param fromPosition The starting chess piece position.
* @param toPosition The target chess piece position.
* @return A string with the step to reach the target chess piece position from the starting chess piece position.
* An empty string if the starting chess piece position is the same as the target chess piece position
* or the target chess piece position is not reachable directly (vertical, horizontal, diagonal).
*/
std::string ChessPiecePosition::GetStep(ChessPiecePosition fromPosition, ChessPiecePosition toPosition) {
if (fromPosition == toPosition) {
return "";
} else {
if (fromPosition.GetRank() == toPosition.GetRank()) {
if (fromPosition.GetFile() > toPosition.GetFile()) {
return std::string(1, ChessPiecePosition::_MOVE_LEFT) + std::string(1, '1');
} else if (fromPosition.GetFile() < toPosition.GetFile()) {
return std::string(1, ChessPiecePosition::_MOVE_RIGHT) + std::string(1, '1');
} else {
return "";
}
} else if (fromPosition.GetFile() == toPosition.GetFile()) {
if (fromPosition.GetRank() > toPosition.GetRank()) {
return std::string(1, ChessPiecePosition::_MOVE_BOTTOM) + std::string(1, '1');
} else if (fromPosition.GetRank() < toPosition.GetRank()) {
return std::string(1, ChessPiecePosition::_MOVE_TOP) + std::string(1, '1');
} else {
return "";
}
} else {
int rankDifference = fromPosition.GetRank() - toPosition.GetRank();
int fileDifference = fromPosition.GetFile() - toPosition.GetFile();
if (std::abs(rankDifference) != std::abs(fileDifference)) {
return "";
} else {
if (rankDifference < 0) {
if (fileDifference < 0) {
return std::string(1, ChessPiecePosition::_MOVE_TOP) + std::string(1, '1') + std::string(1, ChessPiecePosition::_MOVE_RIGHT) + std::string(1, '1');
} else {
return std::string(1, ChessPiecePosition::_MOVE_TOP) + std::string(1, '1') + std::string(1, ChessPiecePosition::_MOVE_LEFT) + std::string(1, '1');
}
} else {
if (fileDifference < 0) {
return std::string(1, ChessPiecePosition::_MOVE_BOTTOM) + std::string(1, '1') + std::string(1, ChessPiecePosition::_MOVE_RIGHT) + std::string(1, '1');
} else {
return std::string(1, ChessPiecePosition::_MOVE_BOTTOM) + std::string(1, '1') + std::string(1, ChessPiecePosition::_MOVE_LEFT) + std::string(1, '1');
}
}
}
}
}
}
/**
* Gets the next chess piece position below the current chess piece position.
* @return A pointer to the chess piece position below the current chess piece position.
* Returns a null pointer if the chess piece position is not available.
*/
ChessPiecePosition* ChessPiecePosition::NextBottom() {
try {
return new ChessPiecePosition(this->GetFile(), this->GetRank() - 1);
} catch (const std::out_of_range e) {
return nullptr;
}
}
/**
* Gets the next chess piece position below to the left of the current chess piece position.
* @return A pointer to the chess piece position below to the left of the current chess piece position.
* Returns a null pointer if the chess piece position is not available.
*/
ChessPiecePosition* ChessPiecePosition::NextBottomLeft() {
try {
return new ChessPiecePosition(this->GetFile() - 1, this->GetRank() - 1);
} catch (const std::out_of_range e) {
return nullptr;
}
}
/**
* Gets the next chess piece position below to the right of the current chess piece position.
* @return A pointer to the chess piece position below to the right of the current chess piece position.
* Returns a null pointer if the chess piece position is not available.
*/
ChessPiecePosition* ChessPiecePosition::NextBottomRight() {
try {
return new ChessPiecePosition(this->GetFile() + 1, this->GetRank() - 1);
} catch (const std::out_of_range e) {
return nullptr;
}
}
/**
* Gets the next chess piece position based on the current chess piece position and specified steps.
* @param steps The steps to be added to the current chess piece position.
* @return A pointer to the chess piece position based on the current chess piece position and specified steps.
* Returns a null pointer if the chess piece position is not available.
*/
ChessPiecePosition* ChessPiecePosition::NextFromString(std::string steps) {
if (steps.length() % 2 != 0) return nullptr;
char nextFile = this->GetFile();
int nextRank = this->GetRank();
for (int step = 0; step < steps.length() / 2; step++) {
char direction = steps[0 + (step * 2)];
int moves = steps[1 + (step * 2)] - '0';
if (!(moves >= 1 && moves <= 8)) {
return nullptr;
}
switch (direction) {
case ChessPiecePosition::_MOVE_BOTTOM:
nextRank -= moves;
break;
case ChessPiecePosition::_MOVE_LEFT:
nextFile -= moves;
break;
case ChessPiecePosition::_MOVE_RIGHT:
nextFile += moves;
break;
case ChessPiecePosition::_MOVE_TOP:
nextRank += moves;
break;
default:
return nullptr;
}
}
try {
return new ChessPiecePosition(nextFile, nextRank);
} catch (const std::out_of_range e) {
return nullptr;
}
}
/**
* Gets the next chess piece position left of the current chess piece position.
* @return A pointer to the chess piece position left of the current chess piece position.
* Returns a null pointer if the chess piece position is not available.
*/
ChessPiecePosition* ChessPiecePosition::NextLeft() {
try {
return new ChessPiecePosition(this->GetFile() - 1, this->GetRank());
} catch (const std::out_of_range e) {
return nullptr;
}
}
/**
* Gets the next chess piece position right of the current chess piece position.
* @return A pointer to the chess piece position right of the current chess piece position.
* Returns a null pointer if the chess piece position is not available.
*/
ChessPiecePosition* ChessPiecePosition::NextRight() {
try {
return new ChessPiecePosition(this->GetFile() + 1, this->GetRank());
} catch (const std::out_of_range e) {
return nullptr;
}
}
/**
* Gets the next chess piece position above the current chess piece position.
* @return A pointer to the chess piece position above the current chess piece position.
* Returns a null pointer if the chess piece position is not available.
*/
ChessPiecePosition* ChessPiecePosition::NextTop() {
try {
return new ChessPiecePosition(this->GetFile(), this->GetRank() + 1);
} catch (const std::out_of_range e) {
return nullptr;
}
}
/**
* Gets the next chess piece position above to the left of the current chess piece position.
* @return A pointer to the chess piece position above to the left of the current chess piece position.
* Returns a null pointer if the chess piece position is not available.
*/
ChessPiecePosition* ChessPiecePosition::NextTopLeft() {
try {
return new ChessPiecePosition(this->GetFile() - 1, this->GetRank() + 1);
} catch (const std::out_of_range e) {
return nullptr;
}
}
/**
* Gets the next chess piece position above to the right of the current chess piece position.
* @return A pointer to the chess piece position above to the right of the current chess piece position.
* Returns a null pointer if the chess piece position is not available.
*/
ChessPiecePosition* ChessPiecePosition::NextTopRight() {
try {
return new ChessPiecePosition(this->GetFile() + 1, this->GetRank() + 1);
} catch (const std::out_of_range e) {
return nullptr;
}
}
/**
* Sets the file part of the chess piece position.
* @param file The file part of the chess piece position.
*/
void ChessPiecePosition::SetFile(char file) {
if (file >= 'a' && file <= 'h') {
file = char(std::toupper(file));
}
if (file >= 'A' && file <= 'H') {
this->_file = file;
} else {
throw std::out_of_range("file is out of range");
}
}
/**
* Sets the rank part of the chess piece position.
* @param rank The rank part of the chess piece position.
*/
void ChessPiecePosition::SetRank(int rank) {
if (rank >= 1 && rank <= 8) {
this->_rank = rank;
} else {
throw std::out_of_range("rank is out of range");
}
}
/**
* Gets the current chess piece position as string.
* @return The current chess piece position as string.
*/
std::string ChessPiecePosition::ToString() {
return std::string(1, this->GetFile()) + std::to_string(this->GetRank());
}