CS253: Software Development with C++

Fall 2020

HW 6

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):
nwnne
wmee
swsse

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

Errors

Hints

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

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

    cmake . && make

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.