I just wrote a program that the user will input three numbers x y and a seed num
ID: 3864377 • Letter: I
Question
I just wrote a program that the user will input three numbers x y and a seed number for a random number.
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.
It will then produce a grid of cells that are Xby Y. so if I had the input
4_7_33 > input.svg
you would get
Here are all of the files I have. The only ones that can be modified are Domain.cpp and Shape.cpp
I have been spending hours on this, and I can't get it right.
Thanks.
#include "Shape.h"
#include "Domain.h"
#include <string>
#include <iostream>
using namespace std;
Domain::Domain(int sx, int sy):size_x(sx), size_y(sy)
{}
void Domain::addShape(char type, int x, int y)
{
Shape *s = Shape::makeShape(type, x, y);
if(fits(*s))
{
sList.push_back(s);
}
}
bool Domain::fits(const Shape &s) const
{
int sz = s.size();
for(int i = 0 ; i < sz ; i++)
{
if( !(s.getX(i) >= 0 && s.getX(i) < size_x) || !(s.getY(i) >= 0 && s.getY(i) < size_y) )
return false;
}
return true;
}
string tostring(int val)
{
string ret = "";
while(val > 0)
{
int x = val%10;
ret = (char)(x+'0')+ret;
val /= 10;
}
if(ret == "")
ret = "0";
return ret;
}
void Domain::draw(void) const
{
int j, sz;
string x_str, y_str, output;
string header = "";
header = "<?xml version="1.0" encoding="utf-8" standalone="no"?> ";
header += "<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> ";
header += "<svg width="670" height="670" viewBox="0 0 650 650" ";
header += "xmlns="http://www.w3.org/2000/svg" ";
header += "xmlns:xlink="http://www.w3.org/1999/xlink" > ";
header += "<g transform="matrix(1,0,0,-1,50,650)">";
cout<<header<<endl;
header = "";
header = "<rect fill="white" stroke="black" x="0" y="0" width=""+tostring(size_x*40)+"" height=""+tostring(size_y*40)+""/>";
cout<<header<<endl;
for(size_t i = 0 ; i < sList.size() ; i++)
{
sz = sList[i]->size();
for(j = 0 ; j < sz ; j++)
{
x_str = tostring((sList[i]->getX(j))*40);
y_str = tostring((sList[i]->getY(j))*40);
output = "<rect fill="";
string clr(sList[i]->color());
output+= clr+"" stroke="black" x="";
output = output+x_str+"" y=""+y_str+"" width="40" height="40"/>";
cout<<output<<endl;
}
}
header = "</g> </svg> ";
cout<<header;
}
bool Domain::full(void) const
{
int x, y;
bool fill[size_x][size_y];
for(int i = 0 ; i < size_x ; i++)
{
for(int j = 0 ; j < size_y ; j++)
fill[i][j] = false;
}
for(size_t i = 0 ; i < sList.size() ; i++)
{
int sz = sList[i]->size();
for(int j = 0 ; j < sz ; j++)
{
x = sList[i]->getX(j);
y = sList[i]->getY(j);
fill[x][y] = true;
}
}
for(int i = 0 ; i < size_x ; i++)
{
for(int j = 0 ; j < size_y ; j++)
if(fill[i][j] == false)
return false;
}
return true;
}
//
// Domain.h
//
#ifndef DOMAIN_H
#define DOMAIN_H
#include "Shape.h"
#include<vector>
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<Shape*> sList;
};
#endif
//
// fill.cpp
//DO NOT MODIFY
#include "Shape.h"
#include "Domain.h"
#include <cstdlib>
#include <iostream>
using namespace std;
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' };
int cnt = 0;
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);
cnt++;
}
// draw the domain
domain.draw();
}
//MAKEFILE
all: fill
CXXFLAGS=-g -Wall
Shape.o: Shape.cpp Shape.h
Domain.o: Domain.cpp Domain.h Shape.h
fill.o: fill.cpp Domain.h Shape.h
fill: fill.o Domain.o Shape.o
$(CXX) -o $@ $^ $(LDFLAGS)
clean:
rm -f *.o fill
//Shape.cpp
#ifndef SHAPE_CPP
#define SHAPE_CPP
#include "Shape.h"
#include <set>
#include <iostream>
using namespace std;
// Constructor for O
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';
}
int O::size() const
{
return 1;
}
const char* O::color(void) const
{
const char *c = "cyan";
return c;
}
// Constructor for I
I::I(int posx, int posy)
{
x = new int[2];
y = new int[2];
x[0] = x[1] = posx;
y[0] = posy;
y[1] = posy+1;
}
char I::name() const
{
return 'I';
}
int I::size() const
{
return 2;
}
const char* I::color(void) const
{
const char *c = "yello";
return c;
}
// Constructor for L
L::L(int posx, int posy)
{
x = new int[3];
y = new int[3];
x[0] = x[2] = posx;
y[0] = y[1] = posy;
x[1] = posx+1;
y[2] = posy+1;
}
char L::name() const
{
return 'L';
}
int L::size() const
{
return 3;
}
const char* L::color(void) const
{
const char *c = "purple";
return c;
}
// Constructor for S
S::S(int posx, int posy)
{
x = new int[4];
y = new int[4];
x[0] = posx;
x[1] = posx+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';
}
int S::size() const
{
return 4;
}
const char* S::color(void) const
{
const char *c = "blue";
return c;
}
/*
Constructor for X
the constructor initialises the cell co-ordinates
X is spread across 5 cells
*
* * *
*
The Numbering of cells is done from bottom-top and left to right
(x[0], y[0]) is the position of bottom most cell
(x[1], y[1]) is the position of left most cell of the 2nd row from bottom
(x[2], y[2]) is the position of the middle cell in the 2nd row from bottom
....
*/
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;
}
/*
This function returns the name of type of object i.e it is a X, or L, or U ...
*/
char X::name() const
{
return 'X';
}
int X::size() const
{
return 5;
}
const char* X::color(void) const
{
const char *c = "orange";
return c;
}
// Constructor for U
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';
}
int U::size() const
{
return 7;
}
const char* U::color(void) const
{
const char *c = "red";
return c;
}
void Shape::print() const
{
//get the size of the object i.e no of cells across which this is spread
int sz = size();
// get the type of object i.e O, L, X...
char n = name();
cout<<n<<" at ";
//Print all the cell co-ordinates for this object
for(int i = 0 ; i < sz ; i++)
{
cout<<"("<<x[i]<<","<<y[i]<<")";
if(i != sz-1)
cout<<" ";
}
cout<<std::endl;
}
//this function moves the object by (dx, dy)
// In this method, the cell co-ordinates become x+dx, y+dy
void Shape::move(int dx, int dy)
{
int sz = size();
for(int i = 0 ; i < sz ; i++)
{
x[i] += dx;
y[i] += dy;
}
}
/*
This function checks if the object(this) and t overlap
* First add all the cells of t to a set
* the iterate over all the cells of (this) and check
if they are already present in the set
* If any of the cell is already present , objects overlap
and return true
*/
bool Shape::overlap(const Shape &t) const
{
set<pair<int,int> > st;
int sz1 = t.size();
int sz2 = size();
for(int i = 0 ; i < sz1 ; i++)
{
st.insert(make_pair(t.x[i], t.y[i]));
}
for(int i = 0 ; i < sz2 ; i++)
{
if(st.find(make_pair(x[i], y[i]))!= st.end())
return true;
}
return false;
}
/*
This function creates a new object of type ch
*/
Shape * Shape::makeShape(char ch, int posx, int posy)
{
if(ch == 'O')
return new O(posx, posy);
else if(ch == 'I')
return new I(posx, posy);
else if(ch == 'L')
return new L(posx, posy);
else if(ch == 'S')
return new S(posx, posy);
else if(ch == 'X')
return new X(posx, posy);
else if(ch == 'U')
return new U(posx, posy);
else
throw std::invalid_argument("invalid type:");
}
int Shape::getX(int i) const
{
return x[i];
}
int Shape::getY(int i) const
{
return y[i];
}
void Shape::draw(void) const
{
}
// base class virtual destructor
Shape::~Shape()
{
delete [] x;
delete [] y;
}
#endif
Explanation / Answer
Hi Could you please give us some brief about the issue which you are facing because the code looks fine to us.
May the the scenario you might be testing is creating soem problem. Please share the same. Thanks!