A different version of the 1999 APCS Quilt Question

This is a problem about quilts and blocks. A quilt is a two-dimensional grid of blocks. A block is a rectangular pattern. In this problem the block pattern will be made up of characters like 'x' and '.', and the block will be a two-dimensional array of characters.

A quilt is formed from a block, called the main block. Copies of the main block are alternated with flipped copies to make a quilt. A flipped copy is created by reflecting the block about a horizontal line through the block's center.

The example below shows a 3 x 3 quilt made from blocks that are each a 4 x 5 pattern (4 rows and 5 columns). The main block is in the upper-left corner of the quilt.

The class Quilt below represents a quilt. A Quilt object can be constructed from the number of rows and columns in the quilt and a file/stream that stores the pattern of the main block. Once constructed, a Quilt object can be converted into an apmatrix of characters by the member function QuiltToMat.

The main block is stored in myBlock and the number of rows and columns of the quilt are stored in myRowsOfBlocks and myColsOfBlocks, respectively.

class Quilt { public: Quilt(istream & inFile, int rowsOfBlocks, int colsOfBlocks); // constructor, given number of blocks in each row and column apmatrix<char> QuiltToMat(); // returns a matrix with the entire quilt stored in it private: apmatrix<char> myBlock; // stores pattern for one block int myRowsOfBlocks; // number of rows of blocks in the quilt int myColsOfBlocks; // number of columns of blocks in the quilt void PlaceBlock(int startRow, int startCol, apmatrix<char> & qmat); void PlaceFlipped(int startRow, int startCol, apmatrix<char> & qmat); };

Part (A)

Wite the code for the constructor that initializes a quilt. For example, the statements: ifstream input("pattern"); Quilt Q(input,3,3); Makes Q represent the quilt whose diagram is shown above where the file named "pattern" is shown below.
   4 5
   x...x
   .x.x.
   ..x..
   ..x..
You may assume the stream passed to the constructor is open, and that it contains two integers representing the number of rows and columns in the block pattern followed by the characters in the block pattern as the file shown above does. Quilt::Quilt(istream & inFile, int rowsOfBlocks, int colsOfBlocks) : myBlock(0,0), myRowsOfBlocks(rowsOfBlocks), myColsOfBlocks(colsOfBlocks) // pre: inFile is open, rowsOfBlocks > 0, colsOfBlocks > 0 // post: myRowsOfBlocks and myColsOfBlocks are initialized to // the number of rows and columns of blocks that make up // the quilt; myBlock has been resized and initialized to the // block pattern from the stream inFile

Part (B)

Write the private member function PlaceFlipped which place a flipped (upside-down) version of the main block into the matrix qmat parameter of PlaceFlipped. The flipped block is copied into qmat starting at qmat[startRow][startCol].

For example, if quilt Q contains the block shown in part(A) and if M is a matrix large enough to hold the characters in the whole quilt, then the call

Q.PlaceFlipped(4,10,M); creates the shaded block in the diagram below (the third block in the second row of M.) The circled location is M[startRow][startCol].

You may adapt the code of the private member function PlaceBlock, given below, which places the main block (not inverted) into the matrix qmat starting at qmat[startRow][startCol]

void Quilt::PlaceBlock(int startRow, int startCol, apmatrix<char> & qmat) // pre: startRow >= 0; startCol >= 0; // startRow + myBlock.numrows() <= qmat.numrows(); // startCol + myBlock.numcols() <= qmat.numcols(); // post: myBlock has been copied into the matrix // qmat with its upper-left corner at the position // startRow, startCol { int r,c; for(r=0; r < myBlock.numrows(); r++) { for(c=0; c < myBlock.numcols(); c++) { qmat[startRow + r][startCol + c] = myBlock[r][c]; } } } Complete the member function PlaceFlipped below. Assume that PlaceFlipped is called only with parameters that satisfy its precondition. void Quilt::PlaceFlipped(int startRow, int startCol, apmatrix<char> & qmat) // pre: startRow >= 0; startCol >= 0; // startRow + myBlock.numrows() <= qmat.numrows(); // startCol + myBlock.numcols() <= qmat.numcols(); // post: a flipped version of myBlock has been copied into the // matrix qmat with its upper-left corner at the position // startRow, startCol { int r,c; for(r=0; r < myBlock.numrows(); r++) { for(c=0; c < myBlock.numcols(); c++) { } } }

Part (C)

Write the member function QuiltToMat which returns a matrix representing the whole quilt in such a way that the main block alternates with the flipped version of the main block, as shown in the original example. In that example, the main block begins at positions (0,0), (0,10), and so on; while the flipped block begins at positions (0,5), (4,0), and so on.

In writing QuiltToMat, you may call functions PlaceBlock, and PlaceFlipped specified in part (b). Assume that PlaceBlock and PlaceFlipped work as specified, regardless of what you wrote in part (b).

Complete the member function QuiltToMat below.

apmatrix<char> Quilt::QuiltToMat()
Owen L. Astrachan
Last modified: Wed Jun 2 19:25:38 PDT 1999