CS253 HW6: More classes!
Changes
Somehow there were blank lines (from << "\n\n"
) missing in
two places in the sample output. They’re there, now.
                
Description
For this assignment, you will take your work from HW4, and create
two classes, Board
and Rule
. You will provide Board.h
,
Rule.h
, and the library libhw6.a
.
                
The Board
class holds the grid of cells. The Rule
class is
concerned with the rule for birth/survival, and is used by the Board
class to determine the contents of the next generation.
                
Methods
Rule
must have the following public methods:
- Default ctor
-
Constructs.
- Destructor
-
Destroys.
-
.conway()
-
From now on, when
.eval()
is called, use Conway’s rule, as used in
HW2. This is the default, if neither .conway()
nor
.golly()
have been called to set the rule.
-
.golly(string)
-
From now on, when
.eval()
is called, use the given
Golly rule. For example,
.golly("B234/S018")
. If the argument is invalid, as described in
HW4, throw a runtime_error, which must contain the entire
argument.
-
.golly()
-
Return the Golly string currently in effect. If
.conway()
is in
effect, return a Golly string that describes Conway’s rule.
-
.eval(nw,n,ne,w,me,e,sw,s,se)
-
Evaluate the current rule, Conway or Golly, for the given arguments.
Return true if a cell should be here next time (via birth or
survival), and false if no cell should be here next time. The nine
bool arguments represent the immediate neighborhood of the cell in
question, including the cell itself (true for alive, false for
dead):
Board
must have the following public methods:
-
Board(
string filename, Rule
rule, char
live, char
dead)
-
-
Board(
string filename, char
live, char
dead, Rule
rule)
-
-
Board(
string filename, char
live, char
dead)
-
-
Board(
string filename, Rule
rule)
-
-
Board(
string filename)
-
Read a board from filename, using live and dead as the
alive & dead chars for both input & output, and associate rule
with it. Any problems with reading (bad filename, bad contents, lines
of different lengths, etc.) result in throwing a runtime_error,
including the filename, that describes the problem.
If rule isn’t given, use a default-constructed
Rule
. Changing
a rule after it’s been given to a Board
has no effect on that
Board
. This is true even if the given Rule
falls out of scope
and is destroyed.
If the live and dead arguments are not given, assume 'O'
for a live cell and '.'
for a dead one.
- Destructor
-
Destroys.
- Preincrement
-
Replace the current contents with the next generation, according to
the associated
Rule
. Returns the board after incrementing.
Non-methods:
-
ostream << Board
-
Write the current board, using its live and dead chars.
Const-correctness, for arguments, operands, methods, and operators, is
your job. For example, it must be possible to call .golly()
with no
arguments on a const Rule
, or display a const Board
.
                
You may define other methods or data, public or private, as you see fit.
You may define other classes, as you see fit. However, to use the
Board
class, the user need only #include "Board.h"
.
To use the Rule
class, the user need only #include "Rule.h"
.
We may test them separately.
                
Input/output format
- Use the same input format as HW4, taking any given live and
dead chars into account.
- Each row ends with a newline, including the last one.
Therefore, reading or writing a 2×2 board transmits exactly 6 bytes.
Errors
- Attempting to read a
Board
with fewer than two rows or columns
must result in throwing a runtime_error that mentions the
filename.
- All errors are indicated by throwing a runtime_error
with an explanatory message. The exact string thrown is up to you,
but should be descriptive and understandable by the TA.
- No method should call exit(), or produce any output.
Hints
- Nobody said that you have to write the default ctor & dtor.
If the default methods work for you, great!
- Use default arguments and constructor forwarding.
Remember that Java is different.
- The foolish student will put main() in
Board.cc
,
and try to remember to remove it before turning in the homework.
Good luck with that. Just put it in a separate file.
Debugging
If you encounter “STACK FRAME LINK OVERFLOW”, then try this:
export STACK_FRAME_LINK_OVERRIDE=ffff-ad921d60486366258809553a3db49a4a
Libraries
libhw6.a
is a library file. It contains a number of
*.o
(object) files. It must contain Board.o
& Rule.o
, but
it may also contain whatever other *.o
files you need. The
CMakeLists.txt
shown creates libhw6.a
. It does not
contain main().
                
Testing
You will have to write a main() function to test your code. Put it
in a separate file, and do not make it part of libhw6.a
.
We will test your program by doing something like this:
                
mkdir a-new-directory
cd
the-new-directory
tar -x <
/some/where/else/hw6.tar
cmake . && make
cp /some/other/place/test-program.cc .
g++ -Wall test-program.cc libhw6.a
./a.out
We will supply a main program to do the testing that we want.
You should do something similar.
                
Sample Run
Here is a sample run, where %
is my shell prompt:
                
% cmake .
… cmake output appears here …
% make
… make output appears here …
% cat CS253
``@@@```@@@`@@@``@@@@``@@@```
`@```@`@```````@`@````@```@``
`@``````@@```@@``@@@`````@```
`@```@````@`@```````@`@```@``
``@@@``@@@``@@@@`@@@```@@@```
% cat blinker
....
.O..
.O..
.O..
....
% cat test.cc
#include "Board.h"
#include "Rule.h"
#include "Board.h"
#include "Rule.h"
#include <iostream>
#include <cassert>
using namespace std;
int main() {
Rule r;
assert(r.golly() == "B3/S23");
r.golly("B1357/S2468");
assert(r.golly() == "B1357/S2468");
Board g1("CS253", r, '@', '`');
cout << g1 << '\n';
cout << ++g1 << '\n';
cout << ++g1 << "\n\n";
r.conway();
assert(r.golly() == "B3/S23");
Board g2("blinker", r);
cout << g2 << '\n';
cout << ++g2 << '\n';
cout << ++g2 << "\n\n";
Board g3("/s/bach/a/class/cs253/pub/Life/r");
for (int i=0; i<500; i++)
++g3;
cout << g3;
}
% ./test
``@@@```@@@`@@@``@@@@``@@@```
`@```@`@```````@`@````@```@``
`@``````@@```@@``@@@`````@```
`@```@````@`@```````@`@```@``
``@@@``@@@``@@@@`@@@```@@@```
@@@`@@@``@@@````@@@@@`@@`@@@`
`@`@@``@@@@`@@@@`@@@@``@``@@`
@@@```@`@@```@@`@@`@`@``@@@``
`@`@@``@@@@@``@@@``@@``@``@@`
@@@`@@`@@``@@@@@@````@@@`@@@`
@@````@@````````````@@`@@@``@
@@`@`@`@`@```@@@`@`@````@`@@`
`@`@`@@```````@@`@```@@@`@`@@
@@`@````@`@`@`@```@@@`@`@`@@`
@@````@@``@`@`@@`@`@@@`@@@``@
....
.O..
.O..
.O..
....
....
....
OOO.
....
....
....
.O..
.O..
.O..
....
......O..O.......................................O...........................
.......OO.......................................OO......OO...................
...............................................OO......O..O..................
..................................................OO...O.O...................
...................................................O....O....................
.............................................OO.O..O.........................
............................................OO.OO.O..........................
...............................O.............OO.O.............OOO............
............................OOO.O..............O......OO.....O.O.............
...............................OO.....................OO......OO.............
...........................OOOO...............................O..............
.........................OOO.OO................................OO............
.........................OO...OO...OO.........OO..........OO..O.OO...........
................OO........O.OO.OO..OO........O..O...OO.....O..O..............
................OO..........OO.OO.............O.O..O.......O..O..O...........
.............................OO.O..............O....O......OO..OOO...........
...........OO.................O.OO.OOO.................OO.O....O.............
...........OO.................O.OO.OOOO............O.....O.O.O...............
.....................................O.O................OOO.O................
..............................O..................OO.OO.......................
...............O...................OOO...........O.O.........................
...............O...............OO..OO.......OOO.OO...........................
.......OO......O................................OO.OO........................
Requirements
- You may not use any external programs via system(),
fork(), popen(), execl(), execv(), …
- You may not use C-style I/O facilities
such as printf(), scanf(), fopen(), getchar(), getc(), etc.
- You may not use dynamic memory via new, delete,
malloc(), calloc(), realloc(), free(), strdup(), etc.
- It’s ok to implicitly use dynamic memory via containers
such as string or vector.
- No global variables.
- For readability, don’t use ASCII int constants (
65
) instead of
char constants ('A'
) for printable characters.
- We will compile your code like this:
cmake . && make
- If that generates warnings, you will lose a point.
- If that generates errors, you will lose all points.
- There is no automated testing/pre-grading/re-grading.
- Test your code yourself. It’s your job.
- Even if you only change it a little bit.
- Even if all you do is add a comment.
If you have any questions about the requirements, ask.
In the real world, your programming tasks will almost always be
vague and incompletely specified. Same here.
                
Tar file
- The tar file for this assignment must be called:
hw6.tar
- It must contain:
- source files (
*.cc
), including Board.cc
& Rule.cc
- header files (
*.h
), including Board.h
& Rule.h
CMakeLists.txt
, which will create the library file
libhw6.a
.
- These commands must produce the library lib
hw6.a
:
cmake . && make
- Your
CMakeLists.txt
must use at least -Wall
when compiling.
How to submit your work:
In Canvas, check in the
file
hw6.tar
to the assignment
“HW6”.
                
How to receive negative points:
Turn in someone else’s work.