-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdrawingShapesGame.cpp
More file actions
343 lines (270 loc) · 8.48 KB
/
drawingShapesGame.cpp
File metadata and controls
343 lines (270 loc) · 8.48 KB
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
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
/* Author: Faiza Khan
* Last modified: 5/9/18
* EZ: Compile with
g++ drawing.cpp -lcurses
more about the NCURSES libary:
http://tldp.org/HOWTO/NCURSES-Programming-HOWTO/helloworld.html#COMPILECURSES
Recall that you can use command man to look up online manual, e.g.,
man mvprintw
*/
#include <iostream>
#include <ncurses.h>
#include <unistd.h>
using namespace std;
char ReadSelection (string optionName,int & dimension);
class Figure{
public:
Figure (int ox, int oy):x(ox),y(oy)
{
}
int get_x()
{
return x;
}
int get_y()
{
return y;
}
/* Move invoking object by the given displacement, erase
current drawing and display it in the new location
*/
void Move(int dx,int dy)
{
Display (true); // the actual figure type's Display function will be called, due to late binding
x = x+dx;
y = y+dy;
Display (false); //the actual figure type's Display() will be called, due to late binding
}
/* Allow user to place invoking object via keyboard (r,l,u,d) */
void Place()
{
// move the invoking object, until the user selects ok
int dim;
char direction;
do
{
direction = ReadSelection ("Direction",dim);
if (direction=='r')
Move(2,0);
else if (direction=='l')
Move(-2,0);
else if (direction=='u')
Move(0,-2);
else if (direction=='d')
Move(0,2);
} while (direction!='o'); //o means ok...
}
virtual void Edit()=0;
//This function is virtual, meaning that compiler needs to defer the binding to runtime, i.e., it waits until running time to decide which version of the function to be called.
virtual void Display(bool)=0;
// This function is virtual, meaning that compiler needs to defer the binding to runtime, i.e., it waits until running time to decide which version of the function should be called.
private:
int x,y; // position of the figure
};
//class Ractangle
//Derived from parent Figure. It knows how to Display and Edit a Rectangle. It implements the ur evirtual functions that were declared in the abstract
//Figure class.
class Rectangle: public Figure{
public:
Rectangle (int x_o,int y_o, int w=2, int h=2, char symbol='*'):Figure(x_o,y_o)
{
width = w;
height = h;
c= symbol;
}
//Edit()
// Rereads the character, height and width of the Rectangle
void Edit()
{
int dim;
c = ReadSelection ("Character",dim);
//Read width and height...
ReadSelection ("height",height);
ReadSelection ("width",width);
}
//Display(bool erase)
// Displays the Rectangle using the character, height and width.
void Display (bool erase=false)
{
char str[256];
int x = get_x();
int y = get_y();
// fill str with a line of character c
// If erase is true, fill str with a line of space character (
// to erase the current drawing).
for (int i=0;i<width;i++)
str[i] = (erase? ' ': c);
// The above statement uses the conditional operator (?:), and is equivalent
// to:
// if (erase)
// str[i] = ' ';
// else
// str[i] = c;
str[width]='\0'; //terminating character
for (int j=0;j<height;j++)
{
move (y+j,x); //move cursor to (x, y+j)
printw (str); //display str in the current pos
}
}
private:
char c;
int width;
int height;
};
// class Triangle
// Derived from parent Figure. It knows how to Display and Edit a Triangle.
// It implements the pure virtual functions that were declared in the abstract Figure class.
class Triangle : public Figure
{
public :
Triangle (int x_o,int y_o, int s = 2, char symbol='*'):Figure(x_o,y_o)
{
s = side_length;
c= symbol;
}
// reads the character and side length
void Edit()
{
int dim;
c = ReadSelection ("Character",dim);
ReadSelection ("side_length",side_length);
}
// Display (bool erase)
// Displays the Triangle using the character and side length
void Display (bool erase=false)
{
char str[256];
int x = get_x();
int y = get_y();
// fill str with a line of character c
// If erase is true, fill str with a line of space character (
// to erase the current drawing).
for(int i = 0; i < side_length; i++)
{
str[i] = (erase? ' ': c);
}
// The above statement uses the conditional operator (?:), and is equivalent
// to:
// if (erase
// str[i] = ' ';
// else
// str[i] = c;
str[side_length]='\0'; //terminating character
for (int j=0;j<side_length;j++)
{
move (y+j, x); //move cursor to (x, y+j)
printw (str); //display str in the current pos
str[side_length-j-1] = '\0';//remove last character after every line in order to create upside down triangle
}
}
private:
char c;
int side_length;
};
/* Display menu for the given option, read user input and return
* user selection (via return value and pass-by-reference parameter
@param optionName: the name of the option
@param dimension: used to return user's integer input (height, width...)
@return value: a character conresponds to user's selection
@postcondition: The menu will be displayed in the center and bottom
of the window.
*/
char ReadSelection (string optionName,int & dimension)
{
int row, col;
char ch;
// Obtain the size of the window
getmaxyx (stdscr, col, row);
// WE are displaying the menu starting at the following position in our window
// ( (row-10)/2, col-4 ): bottom and middle part of the window...
// clear original text in the given position, by display an line of spaces...
mvprintw (col-4, (row-10)/2, " ");
// display menu based upon the menu type
if (optionName=="Direction")
{
mvprintw (col-4, (row-10)/2, "Right (r), Left(l), Up (u), Down (d), Ok (o):");
noecho(); // no echo while we move the figure around
do {
ch = getch();
} while (ch!='r' && ch!='l' && ch!='u' && ch!='d' && ch!='o');
echo(); //turn the echo mode back on...
}
else if (optionName=="Shape")
{
mvprintw (col-4, (row-10)/2, "Rectangle (R), Triangle(T), GoBack (B):");
do {
ch = getch();
} while (ch!='R' && ch!='T' && ch!='B');
}
else if (optionName=="Character")
{
mvprintw (col-4, (row-10)/2, "Character to use: ");
ch = getch();
}
else if (optionName=="width" || optionName=="height" || optionName=="side_length")
{
mvprintw (col-4, (row-10)/2,"Enter %s, press enter:", optionName.c_str());
//c_str is a member function of string class, it returns a
//c string ..
// Turn buffering on, so user can use backspace/delete to modify input until Enter key is pressed
nocbreak();
// When enter is pressed, user input is parsed and read...
do {
scanw ("%d", &dimension); //EZ: scanf input buffer to read an int value into dimension
} while (dimension<0);
//GO back to no buffering mode
cbreak();
}
return ch;
}
/* Redraw list of Figures
@param listFigs: the array of pointers to figure object
@param num: the length of array listFigs
@precondition: listFigs has been filled with the given
number of pointers to different Figure object (including
Rectangle, Triangle, or other)
@postcondition: all figures have been redrawn
*/
void RedrawAll (Figure * listFigs[], int num)
{
for (int i=0;i<num;i++)
listFigs[i]->Display(false);
}
int main()
{
char d;
WINDOW * wnd;
int x,y;
int dim;
char shape;
Figure * listFig[20]; //used to store pointers to up to 20 figures
wnd = initscr();
cbreak(); // do not wait for enter key pressed to process input
for (int i=0;i<20;)
{
x=5; //default position of a figure
y=5;
//add a new figure to the window
shape = ReadSelection("Shape",dim);
if (shape == 'B')
break;
if (shape == 'R')
listFig[i] = new Rectangle (x,y);
else if (shape =='T')
{
//Dynamically allocate a Triangle object and let curFig point to it
// Todo
listFig[i] = new Triangle(x,y);
}
// Configure the figure
listFig[i]->Edit ();
listFig[i]->Display(false);
// move the current figure, until the user selects ok
listFig[i]->Place();
i++;
//redraw all figures ...
RedrawAll (listFig,i);
}
endwin();
}