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;
}