This assignment consists of two parts, but this time, the second part is optional. The main part is dedicated to designing a small object-oriented system for generating pseudo-graphics in the terminal's window. This assignment covers basics of object-oriented design, polymorphism, abstract classes, handling pointers/references, and, possibly, some templates. This assignment is considerably more open-ended than the previous ones.
When people start learning object-oriented programming, they inadvertently encounter example classes representing shapes, such as rectangles or circles. We are going to implement a few such classes. However, in order not to bother with setting up and learning any advanced graphics libraries, such as OpenGL, you are provided with a small graphics subsystem screen.h that allows "drawing" a few simple geometric pseudo-shapes in the terminal's window, using colored characters as "pixels". (If you are proficient with curses or any its analogue, feel free to use it instead of screen.h.)
Prior to describing how to use screen, we agree on the coordinate system: it is Cartesian, with horizontal x axis and vertical y axis pointing from the origin at the top left corner of the terminal's window. All coordinates are integer.
The top left corner's coordinates are (0, 0). A single unit along each axis is of the size of a single character, i.e., characters are our "pixels". Thus, the size of the terminal window is measured in the number of lines (y axis) and the number of columns (x axis), where intersection of a line and a column contains a character. The exact number of lines and columns in a terminal window vary (by default, the terminal window' size may be around 80 columns by 40 rows, but it may be different on your system, and does not matter anyway).
Your main tool for drawing in the terminal's window is class screen provided in screen.h (it is both declared and defined there, just to keep everything in one file). First of all, screen is an instantiable class, that is, it is not stateless, and, in order to use it, one needs to create an object of type screen. It, however, does not require anything in order to be constructed, i.e., the default constructor works.
screen represents a buffer of characters, one character for each position in the terminal's window. We can ask screen to "draw" some shape on the screen. In response, it will just update its buffer. This way, we can submit multiple requests to screen and, then, call its method render(), which will actually produce the characters from the buffer to the terminal's window. Here is a short summary of screen's methods:
And here is a short example of how one can use screen:
// g++ -g3 -O0 -Wall screen-example.cpp -o screen-example #include <iostream> #include "screen.h" int main() { using namespace tui; screen scr; scr.clear(); // color codes are defined here; 9 is the code for the default color point ptred('@', 1, 3, false); point ptblue('#', 4, 0, true); scr.set_rect(0, 0, scr.ncols() - 1, scr.nrows() - 1, ptred); scr.set_circle(30, 15, 10, ptblue); scr.render(); return 0; }
As you can see, screen is not very nice (e.g., it uses some cryptic color codes and it is not very object-oriented overall). Thus, your goal is to write a few classes that would hide ugliness of screen and provide a neat interface for drawing in terminal. You are expected to implement the following classes (or you can built your own system of classes, but it should not be simpler than the one proposed below):
Declarations of your classes should be put in header file tui.h, while the implementations — in file tui.cpp. All your classes should live in namespace tui like class screen does.
To better understand how your system should be able to function, take a look at the code in main.cpp. You implementation should be such that this code compiles and produces something close to the following (the picture may vary depending on the size of your terminal's window):
Even though some requirements for classes have been set, their role is primarily to give you an understanding of the scope of what is expected from you. If you know how to design a better system or how to make it more interesting, feel free to do so! Just make sure that your code is not trivial and covers the announced topics, and also it compiles and produces the result at least as beautiful as on the picture above :)
This part is optional (i.e., no effect on the grade for PA5); approach it only if you are already done with the first part, and just want to have some extra fun.
In the first part of the assignment, canvas (or whatever class you are using for storing shapes) maintains a list of shapes (pairs of shapes and pens to be used to draw them, if more precisely). If you have followed my advice, then most likely you are using standard vector and pair classes. Consider implementing both these classes yourself (only the functionality you need from them) and then using your implementations instead of the standard classes in your drawing code.
Submit tui.h, tui.cpp, and, possibly, some additional files (if you decided to do the second part of the assignment or do something extraordinary for the first part). Do not forget to write your names in the header of each file you submit. As usually, log in to csil.cs.ucsb.edu and run
turnin pa5@cs32 ./tui.h ./tui.cpp {possibly_other_files}and follow instructions. You can submit your work multiple times. Submissions are not accepted after the deadline.