exercism-solutions/cpp/queen-attack/queen_attack.cpp

82 lines
1.6 KiB
C++

#include "queen_attack.h"
#include <stdexcept>
namespace queen_attack {
namespace {
const int board_width = 8;
const int board_height = 8;
inline int row(const position_t &pos)
{
return pos.first;
}
inline int col(const position_t &pos)
{
return pos.second;
}
}
chess_board::chess_board(position_t white, position_t black)
: white_{std::move(white)}
, black_{std::move(black)}
{
if ( row(white_) < 0 || row(white_) >= board_height
|| col(white_) < 0 || col(white_) >= board_width
|| row(black_) < 0 || row(black_) >= board_height
|| col(black_) < 0 || col(black_) >= board_width) {
throw std::domain_error("invalid queen position");
}
if (white_ == black_)
throw std::domain_error("queen positions must be distinct");
}
const position_t &chess_board::white() const
{
return white_;
}
const position_t &chess_board::black() const
{
return black_;
}
bool chess_board::can_attack() const
{
return col(white_) == col(black_)
|| row(white_) == row(black_)
|| std::abs(col(white_) - col(black_)) == std::abs(row(white_) - row(black_));
}
chess_board::operator std::string() const
{
static const int stride = 2*board_width;
static const int size = stride*board_height;
std::string result(size, ' ');
for (int i = 0; i < size; i += 2) {
result[i] = '_';
}
for (int i = stride - 1; i < size; i += stride) {
result[i] = '\n';
}
result[row(white_)*stride + col(white_)*2] = 'W';
result[row(black_)*stride + col(black_)*2] = 'B';
return result;
}
}