Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

E CS 40 -- Below is my code, please help finish (hw 2 code already included) Filling a rectangular domain with random shapes Description This

ECS40 -- Below is my code, please help finish (hw 2 code already included)

Filling a rectangular domain with random shapes

Description

This assignment builds on the Shape class designed in HW2. In this assignment (HW3), you will modify the implementation of the Shape class that was developed in HW2, and implement a class Domain representing a rectangular area in the x-y plane, with functions that draw a visual representation of the domain as a scalable vector graphics (svg) file. The svg file can be visualized using a browser such as Firefox, Safari, Chrome or Internet Explorer.

The domain is a rectangular array of cells that can be occupied by shapes. The goal of the assignment is to implement a program that places randomly selected shapes at random positions on an arbitrary rectangular domain until the domain is full, and creates a graphical representation of the domain.

Figure 1: Rendering of an svg file obtained with a 10x12 filled domain

HW3 Assignment

In HW3, you are given the files fill.cpp (which contains the main function) and the files Shape.h and Domain.h. You should not modify these files. Your task is to implement the class Domain by writing the file Domain.cpp and by writing a new file Shape.cpp that implements the additional specifications given in HW3. Note that the file Shape.h is different from the one given in HW2.

All source files should compile without warning. You should provide a Makefile in order to be able to build the executable fill using the command

$ make

Input

Input for the fill program is provided on the command line. It does not read input from any file. The command line arguments of the fill program are: size_x size_y seed size_x: size of the domain (number of cells) in the x direction

size_y: size of the domain (number of cells) in the y direction seed: an integer used as a seed for the random number generator rand() used in fill.cpp The program is run, for example, using the following command line:

$ ./fill 12 10 1234 > output.svg  

The fill program will be tested with various sizes in the range [1,15], and various seed values. It is not necessary to test for incorrect values in the command line arguments. You can use the fill executable with specific command line arguments, and compare your svg output with svg output test files provided on the web site to check the functionality of your classes. Note: the random numbers generated on different computers may differ even if the same seed is used. Make sure to generate and compare your output on the CSIF computers. Make sure that your program reproduces the test output exactly. Use the diff command to compare your files with the example files. Other command line arguments will also be used when grading your implementation. The example files are generated using the following naming convention. For example:

$ ./fill 12 10 2 > test_12_10_2.svg  

Modifications of the Shape class

The Shape class should have the following features in addition to the ones defined in HW2 (see the file Shape.h)

Additional public members of the Shape class

virtual const char* color(void) const = 0 A pure virtual member function returning a C-style string (such as e.g. red or blue) that defines the color of the shape. The strings returned by the function should be as follows:

O cyan I yellow L purple S blue X orange U red

int getX(int i) const Returns the x coordinate of cell i of the shape. It is assumed that the value of the argument is valid.

int getY(int i) const Returns the y coordinate of cell i of the shape. It is assumed that the value of the argument is valid.

void draw(void) const A function that prints on stdout a sequence of statements that represent the shape in the scalable vector graphics (svg) format. The output should consist of multiple lines, each line representing one of the cells of the shape. Each cell should be drawn as a square of side 40 pixels, filled with the shapes color. For example the draw() function called by a S shape

located at position (4,2) should output the following four lines:

Specification of the Domain class

The Domain class is responsible for managing the shapes added to the domain. It has a member function addShape which adds a shape to the domain after checking that the new shape fits inside the domain area and does not overlap with any of the previously added shapes.

public members of the Domain class

Domain(int size_x, int size_y)  

Constructor taking as arguments the horizontal and vertical size of the domain, expressed as the number of cells in each direction.

void addShape(char type, int x, int y) Creates a shape of appropriate type according to the type argument, and adds it to the domain. The function should first test if the new shape fits within the domain, i.e. that all cells of the shape are within the domain. If it doesnt, the function should simply return and do nothing else. Care must be taken to free any resources allocated until then. The function should then test if the shape overlaps with any shape already present in the domain. If there is overlap, the function should return and do nothing else. Care must be taken to free any resources allocated until then.

bool fits(const Shape &s) const A function that returns true if the shape s fits inside the the boundaries of the domain. (i.e. the coordinates of all its cells satisfy x >= 0, x=0, yfalse otherwise.

bool full(void) const A function that returns true if the domain is full, (i.e. the sum of the sizes of all shapes present in the domain is equal to the total number of cells), and false otherwise.

void draw(void) const  

This function draws the current state of the domain by printing a complete svg document on stdout. It should first print the following svg header:

Note that this header is fixed, i.e. it is independent of the domain size.

It should then draw a frame with white background defining the domain area. For example, for a

domain of 8x5 cells, the frame is drawn by printing

Note that the width and height attributes depend on the size of the domain.

It should then draw each shape on the domain by calling the shapes draw functions.

Finally it should print the following svg trailer:

The resulting svg file can be visualized by opening it with a browser such as Firefox, Safari, Chrome or Internet Explorer.

private members of the Domain class

const int size_x, size_y  

The dimensions of the domain measured in number of cells in each direction.

vector sList  

A vector of base pointers to store pointers to the shapes added to the domain.

Submission

Create a tar file named hw3.tar containing the files fill.cpp Shape.h Shape.cpp Domain.h Domain.cpp and Makefile. Do not compress the tar file. The Makefile should include the necessary definitions to compile C++ files with the Wall option.

--------

// // Domain.h //

#ifndef DOMAIN_H #define DOMAIN_H #include "Shape.h" #include class Domain { public: Domain(int sx, int sy); void addShape(char type, int x, int y); bool fits(const Shape &s) const; void draw(void) const; bool full(void) const; private: const int size_x, size_y; std::vector sList; }; #endif

-------

#include "Domain.h" #include #include using namespace std;

Domain::Domain(int sx, int sy) : size_x(sx), size_y(sy) { cout << "In domain constructor." << std::endl; //To avoid an error for not using these cout << "Domain dimensions: " << size_x << "by " << size_y << std::endl;

}

void Domain::addShape(char type, int x, int y) { //Create the appropriate type of shape const Shape *myShape; //why does this need to be a const? myShape = Shape::makeShape(type, x, y); //The function should first test if the Shape fits in the domain cout << myShape << std::endl; //to avoid error of unused variable if(fits(*myShape)) { cout << "yay"; } else { cout << "oh noes"; } //test for overlap if true return }

bool Domain::fits(const Shape &s) const { Domain full(void); int x = 0; //fix this later int y = 0; //fix this later if (x >= 0 && x < size_x && y >= 0 && y < size_y) { std::cout << "hey it works."; return true; } else { return false; } }

void Domain::draw(void) const { std::cout << " "; //draw frame with white background defining domain area i.e 8x5 would be width: 8*40 height: 5*40 //call each shapes draw function std::cout << "" <" <

bool Domain::full(void) const { int area = 0; for(int i = 0; i < (int)sList.size(); i++) { area += sList[i]->size(); } return area >= (size_x * size_y); }

----

#include "Shape.h" #include Shape::~Shape() { delete x; delete y; }

void Shape::print(void) const { std::cout << name() << " at"; for (int i = 0; i < size(); i++) { std::cout << " (" << x[i] << "," << y[i] << ")"; } std::cout << std::endl; }

void Shape::move(int dx, int dy) { for(int i = 0; i < size(); i++) { x[i] += dx; y[i] += dy; } }

void Shape::draw(void) const { for (int i = 0; i < (sizeof(x) / sizeof(x[0])); i++) { std::cout << "" << std::endl; } }

int Shape::getX(int i) const { return x[i]; }

int Shape::getY(int i) const { return y[i]; } bool Shape::overlap(const Shape& s) const { bool overlapped = false; for(int i = 0; i < size() && !overlapped; i++) { for(int j = 0; j < s.size(); j++) { if(x[i] == s.x[j] && y[i] == s.y[j]) { overlapped = true; } } } return overlapped; }

Shape* Shape::makeShape(char ch, int x, int y) { Shape* newShape = NULL; if(ch == 'X') { newShape = new X(x, y); } else if(ch == 'I') { newShape = new I(x, y); } else if(ch == 'O') { newShape = new O(x, y); } else if(ch =='S') { newShape = new S(x, y); } else if(ch == 'U') { newShape = new U(x, y); } else if(ch == 'L') { newShape = new L(x, y); } else { std::cout << "invalid type: " << ch << " " << x << " " << y << std::endl; exit(1); } return newShape; }

I::I(int posx, int posy) { x = new int[2]; x[0] = x[1] = posx; y = new int[2]; y[0] = posy; y[1] = y[0] + 1; }

char I::name() const { return 'I'; }

const char* I::color() const { return "yellow"; }

int I::size() const { return 2; }

X::X(int posx, int posy) { x = new int[5]; y = new int[5]; x[0] = x[2] = x[4] = posx; x[1] = posx - 1; x[3] = posx + 1; y[0] = posy; y[1] = y[2] = y[3] = posy+1; y[4] = posy + 2; }

char X::name() const { return 'X'; }

const char* X::color() const { return "orange"; }

int X::size() const { return 5; }

O::O(int posx, int posy) { x = new int[1]; y = new int[1]; x[0] = posx; y[0] = posy; }

char O::name() const { return 'O'; }

const char* O::color() const { return "cyan"; }

int O::size() const { return 1; }

L::L(int posx, int posy) { x = new int[3]; y = new int[3]; x[0] = x[2] = posx; x[1] = posx +1; y[0] = y[1] = posy; y[2] = posy+1; }

char L::name() const { return 'L'; }

const char* L::color() const { return "purple"; }

int L::size() const { return 3; }

S::S(int posx, int posy) { x = new int[4]; y = new int[4]; x[0] = posx; x[1] = x[2] = posx +1; x[3] = posx+ 2; y[0] = y[1] = posy; y[2] = y[3] = posy + 1; }

char S::name() const { return 'S'; }

const char* S::color() const { return "blue"; } int S::size() const { return 4; }

U::U(int posx, int posy) { x = new int[7]; y = new int[7]; x[0] = x[3] = x[5] = posx; x[1] = posx +1; x[2] = x[4] = x[6] = posx + 2; y[0] = y[1] = y[2] = posy; y[3] = y[4] = posy + 1; y[5] = y[6] = posy + 2; }

char U::name() const { return 'U'; }

const char* U::color() const { return "red"; }

int U::size() const { return 7; }

----

// // Shape.h //

#ifndef SHAPE_H #define SHAPE_H class Shape { public: virtual ~Shape(void); virtual char name(void) const = 0; virtual int size(void) const = 0; virtual const char* color(void) const = 0; int getX(int i) const; int getY(int i) const; void print(void) const; void draw(void) const; void move (int dx, int dy); bool overlap(const Shape &t) const; static Shape *makeShape(char ch,int posx,int posy); protected: int *x, *y; };

class O: public Shape { public: O(int posx, int posy); virtual char name(void) const; virtual int size(void) const; virtual const char* color(void) const; };

class I: public Shape { public: I(int posx, int posy); virtual char name(void) const; virtual int size(void) const; virtual const char* color(void) const; };

class L: public Shape { public: L(int posx, int posy); virtual char name(void) const; virtual int size(void) const; virtual const char* color(void) const; };

class S: public Shape { public: S(int posx, int posy); virtual char name(void) const; virtual int size(void) const; virtual const char* color(void) const; };

class X: public Shape { public: X(int posx, int posy); virtual char name(void) const; virtual int size(void) const; virtual const char* color(void) const; };

class U: public Shape { public: U(int posx, int posy); virtual char name(void) const; virtual int size(void) const; virtual const char* color(void) const; }; #endif

---

// // fill.cpp //

#include "Shape.h" #include "Domain.h" #include

int main(int argc, char **argv) { // use: fill size_x size_y seed

// domain size int size_x = atoi(argv[1]); int size_y = atoi(argv[2]); // seed for random number generator int seed = atoi(argv[3]); srand((unsigned) seed);

// create the domain Domain domain(size_x,size_y);

char type[] = { 'O', 'I', 'L', 'S', 'X', 'U' };

while ( !domain.full() ) { // try to insert a random shape // draw a random number in [0,5] // to select a random letter among 'O','I','L','S','X','U' int itype = rand() % 6; // generate a random position in [0,size_x), [0,size_y) int x = rand() % size_x; int y = rand() % size_y; domain.addShape(type[itype],x,y); }

// draw the domain domain.draw(); }

---

Make file

---

all: fill

CXXFLAGS=-g -Wall

Shape.o: Shape.cpp Shape.h Domain.o: Domain.cpp Domain.h fill.o: fill.cpp Shape.h Domain.h

fill: fill.o Shape.o Domain.o $(CXX) -o $@ $^ $(LDFLAGS)

clean: rm -f *.o fill

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image

Step: 3

blur-text-image

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Recommended Textbook for

Microsoft Office 365 For Beginners 2022 8 In 1

Authors: James Holler

1st Edition

B0B2WRC1RX, 979-8833565759

More Books

Students also viewed these Databases questions