CS 32 Readiness Assessment Basic Tests

If you precede your main routine with the declaration void doBasicTests();, add the following as the first two lines of main:

    doBasicTests(); // Remove this line after completing test.
    return 0;       // Remove this line after completing test.
append the following to your witches.cpp file, and build and run your program, you will test a number of basic aspects of your code.

#include <type_traits>
#include <cassert>
#undef NDEBUG

#define CHECKTYPE(c, f, r, a)  \
    static_assert(std::is_same<decltype(&c::f), r (c::*)a>::value, \
       "FAILED: You changed the type of " #c "::" #f);  \
    [[gnu::unused]] auto xxx##c##_##f = static_cast<r(c::*)a>(&c::f)

void thisFunctionWillNeverBeCalled()
{
      // If the student deleted or changed the interfaces to the public
      // functions, this won't compile.  (This uses magic beyond the scope
      // of CS 31.)

    Witch(static_cast<City*>(0), 1, 1);
    CHECKTYPE(Witch, row, int, () const);
    CHECKTYPE(Witch, col, int, () const);
    CHECKTYPE(Witch, move, void, ());

    Player(static_cast<City*>(0), 1, 1);
    CHECKTYPE(Player, row, int, () const);
    CHECKTYPE(Player, col, int, () const);
    CHECKTYPE(Player, age, int, () const);
    CHECKTYPE(Player, isDead, bool, () const);
    CHECKTYPE(Player, stand, void, ());
    CHECKTYPE(Player, move, void, (int));
    CHECKTYPE(Player, tossBalloon, bool, (int));
    CHECKTYPE(Player, setDead, void, ());

    City(1, 1);
    CHECKTYPE(City, rows, int, () const);
    CHECKTYPE(City, cols, int, () const);
    CHECKTYPE(City, player, Player*, () const);
    CHECKTYPE(City, witchCount, int, () const);
    CHECKTYPE(City, numWitchesAt, int, (int,int) const);
    CHECKTYPE(City, display, void, (string) const);
    CHECKTYPE(City, addWitch, bool, (int,int));
    CHECKTYPE(City, addPlayer, bool, (int,int));
    CHECKTYPE(City, meltWitch, bool, (int,int));
    CHECKTYPE(City, moveWitches, bool, ());

    Game(1, 1, 1);
    CHECKTYPE(Game, play, void, ());
}

void doBasicTests()
{
    {
        City walk(10, 20);
        assert(walk.addPlayer(2, 6));
        Player* pp = walk.player();
        assert(pp->row() == 2  &&  pp->col() == 6  && ! pp->isDead());
        pp->move(UP);
        assert(pp->row() == 1  &&  pp->col() == 6  && ! pp->isDead());
        pp->move(UP);
        assert(pp->row() == 1  &&  pp->col() == 6  && ! pp->isDead());
        pp->setDead();
        assert(pp->row() == 1  &&  pp->col() == 6  && pp->isDead());
    }
    {
        City ofAngels(2, 2);
        assert(ofAngels.addPlayer(1, 1));
        assert(ofAngels.addWitch(2, 2));
        Player* pp = ofAngels.player();
        assert(ofAngels.moveWitches());
        assert( ! pp->isDead());
        for (int k = 0; k < 1000  && ofAngels.moveWitches(); k++)
            assert(ofAngels.numWitchesAt(1, 1) == 0);
        assert(pp->isDead()  &&  ofAngels.numWitchesAt(1, 1) == 1);
    }
    {
        City ousDarth(1, 40);
        assert(ousDarth.addPlayer(1, 1));
        assert(ousDarth.addWitch(1, 37));
        assert(ousDarth.addWitch(1, 40));
        assert(ousDarth.addWitch(1, 39));
        assert(ousDarth.addWitch(1, 36));
        assert(ousDarth.addWitch(1, 40));
        assert(ousDarth.addWitch(1, 38));
        assert(ousDarth.witchCount() == 6  &&  ousDarth.numWitchesAt(1, 40) == 2);
        Player* pp = ousDarth.player();
        for (int k = 0; k < 1000  &&  ousDarth.witchCount() != 0; k++)
            pp->tossBalloon(RIGHT);
        assert(ousDarth.witchCount() == 0);
        assert(ousDarth.addWitch(1, 40));
        for (int k = 0; k < 38; k++)
        {
            ousDarth.moveWitches();
            pp->stand();
        }
        assert(ousDarth.witchCount() == 1);
          // If the program crashes after leaving this compound statement, you
          // are probably messing something up when you delete a melted Witch
          // (or you have mis-coded the destructor).
          //
          // Draw a picture of your m_witches array before tossing any balloons
          // and also note the values of m_nWitches or any other variables you
          // might have that are involved with the number of Witches.  Trace
          // through your code step by step as the Witches are melted and
          // removed, updating the picture according to what the code says, not
          // what you want it to do.  If you don't see a problem then, try
          // tracing through the destruction of the city.
          //
          // If you execute the code, use the debugger to check on the values
          // of key variables at various points.  If you didn't try to learn
          // to use the debugger, insert statements that write the values of
          // key variables to cerr so you can trace the execution of your code
          // and see the first place where something has gone amiss.  (Comment
          // out the call to clearScreen in City::display so that your output
          // doesn't disappear.)
    }
    cout << "Passed all basic tests" << endl;
}