Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download

CSC112 Spring 2016 Examples

2370 views
1
// Functions for the TrianglePuzzle Class
2
// Revision: $Revision: 1.1 $
3
// Change Log
4
// $Log: trianglePuzzle.cpp,v $
5
// Revision 1.1 2016/03/17 15:59:57 pngwen
6
// Initial revision
7
//
8
9
#include <iostream>
10
#include <unistd.h>
11
#include "tty_functions.h"
12
#include "trianglePuzzle.h"
13
#include "keystream.h"
14
#include "termmanip.h"
15
16
using namespace std;
17
18
19
TrianglePuzzle::TrianglePuzzle(int _x, int _y) : Widget(_x, _y, 27, 9), pegs(5)
20
{
21
int coff = 12;
22
int roff = 0;
23
24
//build the puzzle
25
for(int row=1; row<=5; row++) {
26
for(int col=0; col < row; col++) {
27
pegs[row-1].push_back(new Peg(_x + coff + (col * 6), _y+roff));
28
if(row != 1) {
29
pegs[row-1][col]->place();
30
}
31
}
32
33
//update the offsets
34
roff+=2;
35
coff-=3;
36
}
37
38
//set up the cursor stuff
39
this->cx = this->cy = 0;
40
this->mx = this->my = -1;
41
42
//select the default peg
43
this->pegs[this->cy][this->cx]->select();
44
}
45
46
47
TrianglePuzzle::TrianglePuzzle() : TrianglePuzzle(1, 1)
48
{
49
//put ourselves in the middle of the screen
50
ttySize size = ttyGetSize(STDIN_FILENO);
51
52
//compute the midpoint
53
int mx = size.cols / 2 - 13;
54
int my = size.rows / 2 - 4;
55
56
//set ourselves to the midpoint and then adjust for the offset
57
x(mx);
58
y(my);
59
for(auto ritr=pegs.begin(); ritr!=pegs.end(); ritr++) {
60
for(auto citr=ritr->begin(); citr != ritr->end(); citr++) {
61
(*citr)->x((*citr)->x() + mx);
62
(*citr)->y((*citr)->y() + my);
63
}
64
}
65
}
66
67
68
TrianglePuzzle::~TrianglePuzzle()
69
{
70
//delete all the pegs!
71
for(auto ritr=pegs.begin(); ritr!=pegs.end(); ritr++) {
72
for(auto citr=ritr->begin(); citr != ritr->end(); citr++) {
73
delete *citr;
74
}
75
}
76
}
77
78
void
79
TrianglePuzzle::display()
80
{
81
//display all the pegs
82
for(auto ritr=pegs.begin(); ritr!=pegs.end(); ritr++) {
83
for(auto citr=ritr->begin(); citr != ritr->end(); citr++) {
84
(*citr)->display();
85
}
86
}
87
}
88
89
//select a given peg
90
void
91
TrianglePuzzle::selectPeg(int px, int py)
92
{
93
//unselect the current one
94
pegs[cy][cx]->deselect();
95
96
//correct potential issues in y first
97
if(py < 0) {
98
//torus up!
99
py = pegs.size() - 1;
100
} else if (py >= pegs.size()) {
101
//torus down!
102
py = 0;
103
}
104
105
//correct x
106
if(px < 0) {
107
//torus left!
108
px = pegs[py].size() -1;
109
} else if(px >= pegs[py].size()) {
110
//torus right!
111
px = 0;
112
}
113
114
//select the chosen one and redisplay
115
this->cx = px;
116
this->cy = py;
117
pegs[cy][cx]->select();
118
display();
119
}
120
121
122
//move the selection up a row
123
void
124
TrianglePuzzle::up()
125
{
126
//kick it up a notch
127
selectPeg(cx, cy-1);
128
}
129
130
131
//move the selection down a row
132
void
133
TrianglePuzzle::down()
134
{
135
//bring it on down
136
selectPeg(cx, cy+1);
137
}
138
139
140
//move the selection right a column
141
void
142
TrianglePuzzle::right()
143
{
144
//to the right, the right....
145
selectPeg(cx+1, cy);
146
}
147
148
149
//move the selection left a column
150
void
151
TrianglePuzzle::left()
152
{
153
//to the left, the left...
154
selectPeg(cx-1, cy);
155
}
156
157
158
//perform a part of a move. Returns true if valid, false if invalid
159
bool
160
TrianglePuzzle::move()
161
{
162
int dx, dy;
163
int midx, midy;
164
int sx, sy;
165
166
//handle the first selection
167
if(mx == -1) {
168
//can't select holes, only pegs
169
if(!pegs[cy][cx]->isOccupied()) return false;
170
171
//select the peg!
172
mx = cx;
173
my = cy;
174
pegs[my][mx]->color(red);
175
pegs[my][mx]->display();
176
return true;
177
}
178
179
//ok, so it's the second selection! First, let's turn off the highlighting
180
pegs[my][mx]->color(normal);
181
pegs[my][mx]->display();
182
183
//get the starting point
184
sx = mx;
185
sy = my;
186
187
//reset move state
188
my=mx=-1;
189
190
191
//'now, let's check to see if the user is playing fair
192
if(pegs[cy][cx]->isOccupied()) return false; //this means that it's not a blank square
193
194
//midpoints and distances
195
midx = (cx+sx)/2;
196
midy = (cy+sy)/2;
197
dx = cx - sx;
198
dy = cy - sy;
199
if(dx<0) dx *= -1;
200
if(dy<0) dy *= -1;
201
202
203
//validate same row moves
204
if(dy == 0 && dx != 2) return false;
205
206
//validate different row moves
207
if(dy != 0 && dy != 2) return false;
208
if(dx != 2 && dx != 0) return false;
209
210
//validate that we are skipping a peg
211
if(!pegs[midy][midx]->isOccupied()) return false;
212
213
214
215
//HUZZAH! make the move!
216
pegs[sy][sx]->take();
217
pegs[cy][cx]->place();
218
pegs[midy][midx]->take();
219
220
return true;
221
}
222
223
224
void
225
TrianglePuzzle::reset()
226
{
227
for(int y=0; y<pegs.size(); y++) {
228
for(int x=0; x<pegs[y].size(); x++) {
229
//the first row is empty, all others are taken
230
if(y==0) {
231
pegs[y][x]->take();
232
} else {
233
pegs[y][x]->place();
234
}
235
}
236
}
237
}
238
239