-
Notifications
You must be signed in to change notification settings - Fork 0
/
board.hpp
141 lines (121 loc) · 4.82 KB
/
board.hpp
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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
/////////////////////////////////////////////////////////////////////////////////////
// Robert Wagner
// CISC 3410 Assignment #2
// 2016-10-02
// board.hpp
/////////////////////////////////////////////////////////////////////////////////////
#ifndef __SUDOKU_BOARD_HPP__
#define __SUDOKU_BOARD_HPP__
#include <string>
#include <map>
#include <deque>
#include <vector>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <climits>
#include <algorithm>
#include <bitset>
namespace Sudoku {
using std::string;
using std::vector;
using std::deque;
using std::map;
using std::bitset;
using std::pair;
const string fmtHLine = "+-------+-------+-------+\n";
const int BLOCKSIZE = 3;
const int DIM = BLOCKSIZE * BLOCKSIZE;
const int SIZE = DIM * DIM;
using DataType = char; // generates warnings but is faster than int
using Constraint = pair<DataType, DataType>;
using DomainSet = bitset<DIM>;
using SolvedSet = bitset<SIZE>;
using ValueVec = vector<DataType>;
const DomainSet ONES = DomainSet(0).flip();
const DomainSet SINGLES[DIM] = { DomainSet(1),
DomainSet(1 << 1),
DomainSet(1 << 2),
DomainSet(1 << 3),
DomainSet(1 << 4),
DomainSet(1 << 5),
DomainSet(1 << 6),
DomainSet(1 << 7),
DomainSet(1 << 8) };
class Neighbors {
ValueVec n[SIZE];
ValueVec getNeighbors(const DataType x);
public:
Neighbors() {
for (auto i = 0; i < SIZE; i++)
n[i] = getNeighbors(i);
}
const ValueVec & operator()(const DataType x) const { return n[x]; }
};
static Neighbors neighbors;
class Board {
private:
DomainSet domains[SIZE];
deque<Constraint> constraints;
SolvedSet unsolved;
DataType values[SIZE];
DataType degrees[SIZE];
bool reviseDomain(const DataType x, const DataType y);
public:
DataType chooseUnassigned() const;
bool operator()(const DataType index, const DataType val);
void buildAllConstraints();
void buildConstraints(const DataType from);
bool clearSolved();
bool trimDomains();
const ValueVec getOrderedDomain(const DataType index) const;
Board();
Board(const Board & other);
~Board() {}
DataType distance() const { return unsolved.count(); }
bool isSolved() const { return unsolved.none(); }
bool performAC3();
bool isValid() const {
for (auto const &d : domains)
if (d.none()) return false;
return true;
}
friend std::ostream& operator<<(std::ostream& out, const Board &b);
}; // class Board
// ostream formatting tokens to display game board
std::ostream& pretty(std::ostream& out);
std::ostream& plain (std::ostream& out);
std::ostream& count (std::ostream& out);
const int PRETTY = 0x100;
const int PLAIN = 0x200;
const int TIME = 0x300;
const int COUNT = 0x400;
const DataType BlkOf[81] = { 0,0,0,1,1,1,2,2,2,
0,0,0,1,1,1,2,2,2,
0,0,0,1,1,1,2,2,2,
3,3,3,4,4,4,5,5,5,
3,3,3,4,4,4,5,5,5,
3,3,3,4,4,4,5,5,5,
6,6,6,7,7,7,8,8,8,
6,6,6,7,7,7,8,8,8,
6,6,6,7,7,7,8,8,8 };
const DataType RowOf[81] = { 0,0,0,0,0,0,0,0,0,
1,1,1,1,1,1,1,1,1,
2,2,2,2,2,2,2,2,2,
3,3,3,3,3,3,3,3,3,
4,4,4,4,4,4,4,4,4,
5,5,5,5,5,5,5,5,5,
6,6,6,6,6,6,6,6,6,
7,7,7,7,7,7,7,7,7,
8,8,8,8,8,8,8,8,8 };
const DataType ColOf[81] = { 0,1,2,3,4,5,6,7,8,
0,1,2,3,4,5,6,7,8,
0,1,2,3,4,5,6,7,8,
0,1,2,3,4,5,6,7,8,
0,1,2,3,4,5,6,7,8,
0,1,2,3,4,5,6,7,8,
0,1,2,3,4,5,6,7,8,
0,1,2,3,4,5,6,7,8,
0,1,2,3,4,5,6,7,8 };
} // namespace Sudoku
#endif