330 lines
12 KiB
C++
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());
|
|
}
|