1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
#ifndef __KTOURBOARD_H
#define __KTOURBOARD_H
#include <cmath>
#include <iomanip>
#include <iostream>
#include <vector>
#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<Pos> getPossiblePosVector();
vector<Pos> 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<Pos> KTourBoard::getPossiblePosVector() {
return getPossiblePosVector(pos);
}
vector<Pos> KTourBoard::getPossiblePosVector(Pos pos) {
vector<Pos> 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<Pos> possible = getPossiblePosVector();
Pos smallestPos;
unsigned int smallest = 8;
for (unsigned int i = 0; i < possible.size(); i++) {
vector<Pos> 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
|