Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download

CSC112 Spring 2016 Examples

2370 views
1
#include "crossFour.h"
2
#include "termmanip.h"
3
#include "keystream.h"
4
#include <unistd.h>
5
#include <iostream>
6
7
using namespace std;
8
9
//constructors and destructors
10
CrossFour::CrossFour() : CrossFour(1,1)
11
{
12
13
}
14
15
CrossFour::CrossFour(int cx, int cy) : Widget(cx, cy, 35, 1), pegs(9)
16
{
17
//build the pegses
18
for(int i=0; i<pegs.size(); i++) {
19
pegs[i] = new Peg(x()+i*4, y());
20
}
21
22
reset();
23
}
24
25
CrossFour::~CrossFour()
26
{
27
for(int i=0; i<pegs.size(); i++) {
28
delete pegs[i];
29
}
30
}
31
32
//display our puzzle
33
void
34
CrossFour::display()
35
{
36
for(int i=0; i<pegs.size(); i++) {
37
pegs[i]->display();
38
}
39
}
40
41
//cursor movements
42
void
43
CrossFour::left()
44
{
45
pegs[cx]->deselect();
46
cx--;
47
if(cx < 0) cx = pegs.size()-1;
48
pegs[cx]->select();
49
}
50
51
52
void
53
CrossFour::right()
54
{
55
pegs[cx]->deselect();
56
cx++;
57
cx %= pegs.size();
58
pegs[cx]->select();
59
}
60
61
62
//perform a move
63
bool
64
CrossFour::move()
65
{
66
//selecting source?
67
if(sx == -1) {
68
//validate our selection
69
if(!pegs[cx]->isOccupied()) return false;
70
71
//source is selected!
72
sx = cx;
73
return true;
74
}
75
76
//select destination and complete the move
77
78
//validate direction
79
if(pegs[sx]->color() == blue and sx >= cx){
80
sx = -1;
81
return false;
82
}
83
if(pegs[sx]->color() == red and sx <= cx) {
84
sx = -1;
85
return false;
86
}
87
88
int d = sx - cx;
89
if(d<0) d*=-1;
90
91
//validate the distance
92
if(d < 1 or d > 2) {
93
sx = -1;
94
return false;
95
}
96
97
if(pegs[cx]->isOccupied()) {
98
sx = -1;
99
return false;
100
}
101
102
//it's valid! Move it!
103
pegs[cx]->color(pegs[sx]->color());
104
pegs[sx]->take();
105
pegs[cx]->place();
106
sx =-1;
107
display();
108
return true;
109
}
110
111
//autosolver
112
void
113
CrossFour::solve()
114
{
115
Solver *solution = new Solver(this);
116
cout << cursorPosition(1,2) << "Thinking...";
117
cout.flush();
118
backtrack(solution);
119
cout << cursorPosition(1,2) << clearLine;
120
cout.flush();
121
122
/* Solver *move = solution;
123
while(move) {
124
displayState(move->state);
125
move = (Solver*) move->after();
126
}
127
*/
128
delete solution;
129
}
130
131
132
//reset the puzzle to starting position
133
void
134
CrossFour::reset()
135
{
136
//blue pegs
137
for(int i=0; i<pegs.size()/2; i++) {
138
pegs[i]->place();
139
pegs[i]->color(blue);
140
}
141
142
//blank peg
143
pegs[pegs.size()/2]->take();
144
145
//red pegs
146
for(int i=pegs.size()/2+1; i<pegs.size(); i++) {
147
pegs[i]->place();
148
pegs[i]->color(red);
149
}
150
151
//select the default peg
152
sx=-1;
153
cx = pegs.size()/2;
154
pegs[cx]->select();
155
display();
156
}
157
158
159
CrossFour::Solver::Solver(CrossFour *puzzle)
160
{
161
//we have made no move!
162
movedPeg=-1;
163
nextTrial = 0;
164
state[0]='B';
165
state[1]='B';
166
state[2]='B';
167
state[3]='B';
168
state[4]=' ';
169
state[5]='R';
170
state[6]='R';
171
state[7]='R';
172
state[8]='R';
173
_before = _after = NULL;
174
this->puzzle = puzzle;
175
}
176
177
178
CrossFour::Solver::Solver(CrossFour *puzzle, char state[], int movedPeg)
179
{
180
this->puzzle = puzzle;
181
this->movedPeg = movedPeg;
182
nextTrial=0;
183
//copy the pegs
184
for(int i=0; i<9; i++) {
185
this->state[i] = state[i];
186
}
187
_before = _after = NULL;
188
}
189
190
191
bool
192
CrossFour::Solver::reject()
193
{
194
if(accept()) return false;
195
196
//iterate
197
for(int i = 0; i < 9; i++) {
198
if(state[i] == 'B' && i != 6) {
199
if(state[i+2] == ' ') {
200
return false;
201
}
202
}
203
if(state[i] == 'B' && i != 7) {
204
if(state[i+1] == ' ') {
205
return false;
206
}
207
}
208
if(state[i] =='R' && i != 0) {
209
if(state[i-1] == ' ') {
210
return false;
211
}
212
}
213
if(state[i] =='R' && i > 1) {
214
if(state[i-2] == ' ') {
215
return false;
216
}
217
}
218
}
219
return true;
220
}
221
222
223
224
bool
225
CrossFour::Solver::accept()
226
{
227
puzzle->displayState(state);
228
//iterate through the state
229
for(int i = 0; i <9; i++) {
230
if(i >= 0 and i <= 3) {
231
if (state[i] != 'R') return false;
232
}
233
if(i == 4) {
234
if (state[i] != ' ') return false;
235
}
236
if(i >= 5 and i <= 8) {
237
if (state[i] != 'B') return false;
238
}
239
}
240
//if we made it this far, everything is correct vibes
241
242
return true;
243
}
244
245
246
MoveState*
247
CrossFour::Solver::next()
248
{
249
Solver *moved = NULL;
250
251
for(nextTrial; !moved and nextTrial <= 8; nextTrial++)
252
{
253
switch(state[nextTrial]){
254
case 'B':
255
if(nextTrial < 8 and state[nextTrial+1] == ' ')
256
{
257
moved = new Solver(puzzle, state, movedPeg);
258
_after = moved;
259
moved->_before = this;
260
moved->state[nextTrial] = ' ';
261
moved->state[nextTrial+1] = 'B';
262
} else if(nextTrial < 7 and state[nextTrial+2] == ' ') {
263
moved = new Solver(puzzle, state, movedPeg);
264
_after = moved;
265
moved->_before = this;
266
moved->state[nextTrial] = ' ';
267
moved->state[nextTrial+2] = 'B';
268
}
269
break;
270
case 'R':
271
if(nextTrial > 0 and state[nextTrial-1] == ' ')
272
{
273
moved = new Solver(puzzle, state, movedPeg);
274
_after = moved;
275
moved->_before = this;
276
moved->state[nextTrial] = ' ';
277
moved->state[nextTrial-1] = 'R';
278
} else if(nextTrial > 1 and state[nextTrial-2] == ' ') {
279
moved = new Solver(puzzle, state, movedPeg);
280
_after = moved;
281
moved->_before = this;
282
moved->state[nextTrial] = ' ';
283
moved->state[nextTrial-2] = 'R';
284
}
285
break;
286
287
default:
288
break;
289
}
290
291
}
292
293
return moved;
294
}
295
296
//move "memory"
297
MoveState*
298
CrossFour::Solver::before()
299
{
300
return _before;
301
}
302
303
304
MoveState*
305
CrossFour::Solver::after()
306
{
307
return _after;
308
}
309
310
//display the current state
311
void CrossFour::displayState(char state[])
312
{
313
for(int i=0; i<9; i++) {
314
pegs[i]->take();
315
switch(state[i]) {
316
case 'B':
317
pegs[i]->color(blue);
318
pegs[i]->place();
319
break;
320
case 'R':
321
pegs[i]->color(red);
322
pegs[i]->place();
323
break;
324
}
325
}
326
display();
327
cout.flush();
328
usleep(250000);
329
}
330