-
Notifications
You must be signed in to change notification settings - Fork 0
/
types.h
125 lines (98 loc) · 2.95 KB
/
types.h
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
116
117
118
119
120
121
122
123
124
125
#ifndef SUDOK_NO_TYPES_H
#define SUDOK_NO_TYPES_H
#include <cstddef>
#include <array>
#include <cassert>
#include <set>
using Col = size_t;
using Row = size_t;
struct Location {
Col col = 0;
Row row = 0;
bool operator==(const Location& other) const {
return other.row == row && other.col == col;
}
};
struct Block {
size_t id = 0;
constexpr std::array<Location, 9> locations() {
assert(id >= 1 && id <= 9);
// TODO: Learn more about matrix math or do something smarter here.
Row firstRow = (((id - 1) / 3) * 3) + 1;
Col firstCol = (((id - 1) % 3) * 3) + 1;
return {
Location{firstCol + 0, firstRow + 0},
Location{firstCol + 1, firstRow + 0},
Location{firstCol + 2, firstRow + 0},
Location{firstCol + 0, firstRow + 1},
Location{firstCol + 1, firstRow + 1},
Location{firstCol + 2, firstRow + 1},
Location{firstCol + 0, firstRow + 2},
Location{firstCol + 1, firstRow + 2},
Location{firstCol + 2, firstRow + 2},
};
}
};
class square {
public:
void set(int8_t value) {
solved_value = value;
solved = true;
}
Row row() const { return _loc.row; }
Col col() const { return _loc.col; }
Location location() const { return _loc; }
const std::set<int8_t>& candidates() const { return _candidates; }
Block block() const { return _block; }
void setLocation(Location loc) {
_loc = loc;
_block = Block{((_loc.col + 2) / 3) + (((_loc.row + 2) / 3) - 1) * 3};
}
bool is_solved() const { return solved; }
bool could_be(int8_t value) const {
if (solved) {
return solved_value == value;
} else {
return _candidates.count(value) > 0;
};
}
int value() const {
return static_cast<int>(solved_value);
}
std::string stringDisplay() const {
if (is_solved()) {
return std::to_string(value());
} else {
std::string out;
size_t ctr = 0;
for (auto const& e : _candidates) {
out += std::to_string(e);
ctr++;
if (ctr % 3 == 0 && ctr != _candidates.size()) {
out += "\n";
} else {
out += " ";
}
}
return out;
}
}
bool operator==(square& other) {
return other._loc == _loc;
}
void removeCandidate(int8_t value) {
_candidates.erase(value);
if (_candidates.size() == 1) {
solved = true;
for (auto& c : _candidates)
solved_value = c;
}
}
private:
std::set<int8_t> _candidates = {1, 2, 3, 4, 5, 6, 7, 8, 9};
bool solved = false;
int8_t solved_value = 0;
Location _loc = {0, 0};
Block _block = {0};
};
#endif //SUDOK_NO_TYPES_H