-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathGameBoard.cs
247 lines (194 loc) · 6.63 KB
/
GameBoard.cs
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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
using static System.Console;
namespace NETnogram;
internal class GameBoard {
// Public variables
public Board PlayerBoard;
// Private variables
private Board _board;
private readonly string[] _boardStatsCol;
private readonly string[] _boardStatsRow;
private readonly Config _config;
private readonly Random _rng = new();
// Properties
public bool this[Point x] => _board[x];
/// <summary>
/// If only a Config is specified, the Board class generates the board by itself
/// </summary>
public GameBoard(Config config) {
_config = config;
// Initialize the boards and the check counts
_board = new Board(_config);
PlayerBoard = new Board(_config);
_boardStatsCol = new string[_config.Width];
// Generate the board and count it's checks
GenerateBoard();
_boardStatsRow = CountHorizontalChecks();
_boardStatsCol = CountVerticalChecks();
}
/// <summary>
/// If a board is specified, the Board class only manages the interaction with
/// and numbering of the specified board
/// </summary>
public GameBoard(Config config, Board board) {
_config = config;
_board = board;
// Initialize the player's board and the check counts
PlayerBoard = new Board(_config);
_boardStatsCol = new string[_config.Width];
// Count the checks
_boardStatsRow = CountHorizontalChecks();
_boardStatsCol = CountVerticalChecks();
}
/// <summary>
/// Checks if _board and CheckedBoard are equal
/// to tell if the player has solved the nonogram
/// </summary>
public bool CheckBoardFinished() {
for (var y = 0; y < _config.Height; y++) {
for (var x = 0; x < _config.Width; x++) {
if (_board[y, x] != PlayerBoard[y, x]) return false;
}
}
return true;
}
/// <summary>
/// Randomly sets _config.Checked many tiles in _board to true
/// </summary>
private void GenerateBoard() {
// Place random checks
for (var i = 0; i < _config.TilesChecked; i++) {
bool repeat;
Point p;
// Places exactly TilesChecked checks on the board
// Will fill the entire board if TilesChecked = Width * Height
do {
p = new Point(
_rng.Next(_config.Height),
_rng.Next(_config.Width));
repeat = _board[p];
} while (repeat);
_board[p] = true;
}
}
/// <summary>
/// Unholy method to count how many checks there are in each row
/// </summary>
private string[] CountHorizontalChecks() {
string[] horiArr = new string[_config.Height];
// Horizontal
for (var y = 0; y < _config.Height; y++) {
var rowStr = "";
var i = 0;
for (var x = 0; x < _config.Width; x++) {
if (_board[y, x]) {
i++;
} else {
rowStr += i > 0 ? i + " " : "";
i = 0;
}
if (x == _config.Width) {
rowStr += i;
}
}
rowStr += i > 0 ? i : "";
horiArr[y] = rowStr;
}
// Get how long the longest string in the array is
var lastLen = 0;
foreach (var horiStr in horiArr) {
lastLen = Math.Max(lastLen, horiStr.Length);
}
// Add whitespaces to make all strings equally long
for (var i = 0; i < horiArr.Length; i++) {
if (horiArr[i].Length < lastLen) {
var lenDiff = lastLen - horiArr[i].Length;
for (int j = 0; j < lenDiff; j++) {
horiArr[i] += " ";
}
}
}
return horiArr;
}
/// <summary>
/// Unholy method to count how many checks there are in each row
/// </summary>
private string[] CountVerticalChecks() {
string[] vertArr = new string[_config.Width];
for (var x = 0; x < _config.Width; x++) {
var colStr = "";
var i = 0;
for (var y = 0; y < _config.Height; ++y) {
if (_board[y, x]) {
i++;
} else {
colStr += i > 0 ? i : "";
i = 0;
continue;
}
}
colStr += i > 0 ? i : "";
vertArr[x] = colStr;
}
// Get how long the longest string in the array is
var lastLen = 0;
foreach (var horiStr in vertArr) {
lastLen = Math.Max(lastLen, horiStr.Length);
}
// Add whitespaces to make all strings equally long
for (var i = 0; i < vertArr.Length; i++) {
if (vertArr[i].Length < lastLen) {
var lenDiff = lastLen - vertArr[i].Length;
for (int j = 0; j < lenDiff; j++) {
vertArr[i] += " ";
}
}
}
return vertArr;
}
/// <summary>
/// Iterates through CheckedBoard,
/// prints how many checks are in each row and column,
/// prints every false as " - "
/// and every true as " O "
/// </summary>
public void PrintBoard() {
// Prints how many checks there are in each column
for (var y = 0; y < _boardStatsCol[0].Length; y++) {
var colStr = new string(' ', _boardStatsRow[0].Length + 2);
for (var x = 0; x < _config.Width; x++) {
colStr += $" {_boardStatsCol[x][y]}";
}
WriteLine(colStr);
}
WriteLine("");
// Prints which tiles of PlayerBoard are checked and how many checks there are in each row
for (var y = 0; y < _config.Height; y++) {
Write(_boardStatsRow[y] + " ");
for (var x = 0; x < _config.Width; x++) {
if (PlayerBoard[y, x]) {
Write(" O");
continue;
}
Write(" -");
}
Write("\n");
}
}
/// <summary>
/// Iterates through _board,
/// prints every false (unchecked) as " - "
/// and every true (checked) as " O "
/// </summary>
public void PrintSolvedBoard() {
for (var y = 0; y < _config.Height; y++) {
for (var x = 0; x < _config.Width; x++) {
if (_board[y, x]) {
Write(" O ");
continue;
}
Write(" - ");
}
Write("\n");
}
}
}