#ifndef __KTOURBOARD_H #define __KTOURBOARD_H #include #include #include #include #include "pos.h" using namespace std; class KTourBoard { int width, height; int *cells; Pos pos; public: KTourBoard(int, int); void solve(); void setPos(Pos); friend ostream &operator<<(ostream &, KTourBoard &); private: Pos getNextPos(); vector getPossiblePosVector(); vector getPossiblePosVector(Pos); bool isAvailablePos(Pos); bool isValidPos(Pos); int pos2int(Pos); }; KTourBoard::KTourBoard(int width, int height) { this->width = width; this->height = height; cells = new int[width * height]; for (int i = 0; i < width * height; i++) { cells[i] = 0; } } void KTourBoard::solve() { int i = 1; cells[pos2int(pos)] = i++; while (i <= width * height) { pos = getNextPos(); cells[pos2int(pos)] = i++; } } int KTourBoard::pos2int(Pos pos) { return pos.getx() + width * pos.gety(); } bool KTourBoard::isValidPos(Pos pos) { return pos.getx() >= 0 && pos.gety() >= 0 && pos.getx() < width && pos.gety() < height; } bool KTourBoard::isAvailablePos(Pos pos) { return isValidPos(pos) && !cells[pos2int(pos)]; } vector KTourBoard::getPossiblePosVector() { return getPossiblePosVector(pos); } vector KTourBoard::getPossiblePosVector(Pos pos) { vector possible; if (isAvailablePos(pos + Pos(1, 2))) possible.push_back(pos + Pos(1, 2)); if (isAvailablePos(pos + Pos(2, 1))) possible.push_back(pos + Pos(2, 1)); if (isAvailablePos(pos + Pos(1, -2))) possible.push_back(pos + Pos(1, -2)); if (isAvailablePos(pos + Pos(-2, 1))) possible.push_back(pos + Pos(-2, 1)); if (isAvailablePos(pos + Pos(-1, 2))) possible.push_back(pos + Pos(-1, 2)); if (isAvailablePos(pos + Pos(2, -1))) possible.push_back(pos + Pos(2, -1)); if (isAvailablePos(pos + Pos(-1, -2))) possible.push_back(pos + Pos(-1, -2)); if (isAvailablePos(pos + Pos(-2, -1))) possible.push_back(pos + Pos(-2, -1)); return possible; } Pos KTourBoard::getNextPos() { vector possible = getPossiblePosVector(); Pos smallestPos; unsigned int smallest = 8; for (unsigned int i = 0; i < possible.size(); i++) { vector next = getPossiblePosVector(possible[i]); if (next.size() < smallest) { smallest = next.size(); smallestPos = possible[i]; } } return smallestPos; } void KTourBoard::setPos(Pos pos) { this->pos = pos; } ostream &operator<<(ostream &stream, KTourBoard &board) { int i, j, width = log(board.width * board.height) / log(10) + 1; for (i = 0; i < board.height; i++) { for (j = 0; j < board.width; j++) { stream << setw(width) << board.cells[i * board.width + j] << " "; } stream << endl; } return stream; } #endif