Project 7 Test Data

There were 40 test cases. The first twenty were worth 2 points each, while the last twenty were worth 3 points each. Each test case is represented by an assertion that must be true for you to pass that test. Each test case was run independently. We ignored any output that was written to the screen (especially by Valley::display) other than the final Passed for a passed test. We renamed your main routine to something harmless, replaced the body of the implementation of clearScreen with {} (an empty function body), and appended this code to your program:

#include <iostream> #include <sstream> #include <streambuf> #include <string> #include <map> #include <algorithm> #include <cstdlib> #include <cassert> using namespace std; class StreambufSwitcher { public: StreambufSwitcher(ios& dest, streambuf* sb, ios::iostate exceptions = ios::goodbit) : dest_stream(dest), oldsb(dest.rdbuf(sb)), oldex(dest.exceptions()) { dest_stream.exceptions(exceptions); } StreambufSwitcher(ios& dest, ios& src) : StreambufSwitcher(dest, src.rdbuf(), src.exceptions()) {} ~StreambufSwitcher() { dest_stream.rdbuf(oldsb); dest_stream.exceptions(oldex); } private: ios& dest_stream; streambuf* oldsb; ios::iostate oldex; }; map<void*, size_t> allocMap; bool recordaddrs = false; inline bool isRecordedSize(size_t n) { return n == sizeof(Penguin) || n == sizeof(Player); } void* operator new(size_t n) { void* p = malloc(n); fill_n(static_cast<char*>(p), n, 0xca); if (recordaddrs && isRecordedSize(n)) { recordaddrs = false; allocMap.insert(make_pair(p, n)); recordaddrs = true; } return p; } void unrecordaddr(void* p) { recordaddrs = false; auto it = allocMap.find(p); if (it != allocMap.end()) { fill_n(static_cast<char*>(p), it->second, 0xcb); allocMap.erase(it); } recordaddrs = true; } #if __cplusplus >= 201402L && ! defined(__clang__) // Unless clang is supplied the -fsized-deallocation flag, it will // not call the C++14/17 sized operator delete. void operator delete(void* p) noexcept { free(p); } void operator delete(void* p, size_t n) noexcept { if (recordaddrs && isRecordedSize(n)) unrecordaddr(p); operator delete(p); } #else void operator delete(void* p) noexcept { if (recordaddrs) unrecordaddr(p); free(p); } #endif bool recommendMove(const Valley& v, int r, int c, int& bestDir); void testone(int n) { StreambufSwitcher sso(cout, cerr); switch (n) { default: { cout << "Bad argument" << endl; } break; case 1: { Valley v(10, 18); v.addPlayer(2, 2); Penguin p(&v, 5, 17, 'K'); assert(p.row() == 5 && p.col() == 17 && p.species() == 'K'); } break; case 2: { Valley v(10, 18); v.addPlayer(2, 2); Penguin p(&v, 5, 17, 'M'); assert(!p.isDead()); } break; case 3: { Valley v(20, 20); v.addPlayer(1, 1); Penguin p(&v, 12, 12, 'K'); for (int k = 0; k < 8; k++) { int oldr = p.row(); int oldc = p.col(); p.move(); assert((p.row() == oldr && abs(p.col() - oldc) == 1) || (p.col() == oldc && abs(p.row() - oldr) == 1)); } } break; case 4: { Valley v(20, 20); v.placeProtrusionAt(11, 15); v.placeProtrusionAt(11, 16); v.placeProtrusionAt(13, 15); v.placeProtrusionAt(13, 16); v.placeProtrusionAt(12, 14); v.placeProtrusionAt(12, 17); v.addPlayer(1, 1); Penguin p(&v, 12, 15, 'K'); bool moved = false; bool stayed = false; for (int k = 0; k < 100; k++) { int oldc = p.col(); p.move(); assert(p.row() == 12 && p.col() >= 15 && p.col() <= 16); if (p.col() == oldc) stayed = true; else moved = true; } assert(moved && stayed); } break; case 5: { Valley v(20, 20); v.placeProtrusionAt(15, 11); v.placeProtrusionAt(16, 11); v.placeProtrusionAt(15, 13); v.placeProtrusionAt(16, 13); v.placeProtrusionAt(14, 12); v.placeProtrusionAt(17, 12); v.addPlayer(1, 1); Penguin p(&v, 15, 12, 'K'); bool moved = false; for (int k = 0; k < 100; k++) { int oldr = p.row(); p.move(); assert(p.col() == 12 && p.row() >= 15 && p.row() <= 16); if (p.row() != oldr) moved = true; } assert(moved && !p.isDead()); } break; case 6: { bool moved = false; for (int k = 0; k < 50; k++) { Valley v(1, 18); v.addPlayer(1, 1); Penguin p(&v, 1, 18, 'K'); for (int m = 0; m < 16 && p.col() > 1; m++) { int oldc = p.col(); p.move(); assert(p.row() == 1 && p.col() <= 18 && abs(p.col() - oldc) <= 1); if (p.col() != oldc) moved = true; } } assert(moved); } break; case 7: { bool moved = false; for (int k = 0; k < 50; k++) { Valley v(18, 1); v.addPlayer(1, 1); Penguin p(&v, 18, 1, 'K'); for (int m = 0; m < 16 && p.row() > 1; m++) { int oldr = p.row(); p.move(); assert(p.col() == 1 && p.row() <= 18 && abs(p.row() - oldr) <= 1); if (p.row() != oldr) moved = true; } } assert(moved); } break; case 8: { bool moved = false; for (int k = 0; k < 50; k++) { Valley v(1, 20); v.addPlayer(1, 20); Penguin p(&v, 1, 1, 'K'); for (int m = 0; m < 17 && p.col() < 20; m++) { int oldc = p.col(); p.move(); assert(p.row() == 1 && p.col() >= 1 && abs(p.col() - oldc) <= 1); if (p.col() != oldc) moved = true; } } assert(moved); } break; case 9: { bool moved = false; for (int k = 0; k < 50; k++) { Valley v(20, 1); v.addPlayer(20, 1); Penguin p(&v, 1, 1, 'K'); for (int m = 0; m < 17 && p.row() < 20 ; m++) { int oldr = p.row(); p.move(); assert(p.col() == 1 && p.row() >= 1 && abs(p.row() - oldr) <= 1); if (p.row() != oldr) moved = true; } } assert(moved); } break; case 10: { Valley v(10, 20); v.placeProtrusionAt(5, 12); v.placeProtrusionAt(6, 11); v.placeProtrusionAt(6, 13); v.addPlayer(2, 2); Penguin p(&v, 6, 12, 'K'); p.forceMove(NORTH); assert(p.row() == 6 && p.col() == 12 && !p.isDead()); } break; case 11: { Valley v(10, 20); v.placeProtrusionAt(5, 12); v.placeProtrusionAt(6, 11); v.placeProtrusionAt(6, 13); v.addPlayer(2, 2); Penguin p(&v, 6, 12, 'K'); p.forceMove(NORTH); assert(p.row() == 6 && p.col() == 12 && !p.isDead()); p.forceMove(NORTH); assert(p.row() == 6 && p.col() == 12 && !p.isDead()); p.forceMove(NORTH); assert(p.row() == 6 && p.col() == 12 && p.isDead()); } break; case 12: { Valley v(10, 20); v.addPlayer(2, 2); Penguin p(&v, 1, 12, 'K'); p.forceMove(NORTH); assert(p.row() == 1 && p.col() == 12 && !p.isDead()); p.forceMove(NORTH); assert(p.row() == 1 && p.col() == 12 && !p.isDead()); p.forceMove(NORTH); assert(p.row() == 1 && p.col() == 12 && p.isDead()); } break; case 13: { Valley v(10, 20); v.addPlayer(2, 2); Penguin p(&v, 1, 12, 'K'); p.forceMove(SOUTH); assert(p.row() == 2 && p.col() == 12 && !p.isDead()); p.forceMove(SOUTH); assert(p.row() == 3 && p.col() == 12 && !p.isDead()); p.forceMove(SOUTH); assert(p.row() == 4 && p.col() == 12 && !p.isDead()); } break; case 14: { Valley v(10, 20); Player p(&v, 2, 3); assert(p.row() == 2 && p.col() == 3 && !p.isDead()); } break; case 15: { Valley v(10, 20); Player p(&v, 2, 3); p.setDead(); assert(p.isDead()); } break; case 16: { Valley v(10, 18); v.addPlayer(5, 18); Player* pp = v.player(); pp->move(EAST); pp->move(EAST); pp->move(EAST); assert(pp->row() == 5 && pp->col() == 18 && !pp->isDead()); } break; case 17: { Valley v(10, 20); v.placeProtrusionAt(3, 3); v.addPlayer(4, 3); Player* pp = v.player(); pp->move(NORTH); pp->move(NORTH); pp->move(NORTH); assert(pp->row() == 4 && pp->col() == 3 && !pp->isDead()); } break; case 18: { Valley v(10, 20); v.placeProtrusionAt(3, 3); v.addPlayer(4, 3); Player* pp = v.player(); string s = pp->move(NORTH); assert(s.find("couldn") != string::npos && s.find("stands") != string::npos); } break; case 19: { Valley v(10, 20); v.addPlayer(4, 3); Player* pp = v.player(); pp->move(NORTH); assert(pp->row() == 3 && pp->col() == 3); } break; case 20: { Valley v(10, 20); v.addPlayer(4, 3); Player* pp = v.player(); string s = pp->move(NORTH); assert(s.find("move") != string::npos && s.find("north") != string::npos); } break; case 21: { Valley v(10, 20); v.addPlayer(4, 3); v.addPenguin(4, 2, 'K'); Player* pp = v.player(); assert(!pp->isDead()); string s = pp->move(WEST); assert(pp->isDead()); } break; case 22: { Valley v(10, 20); v.addPlayer(4, 3); v.addPenguin(4, 2, 'K'); Player* pp = v.player(); string s = pp->move(WEST); assert(s.find("penguin") != string::npos && s.find("died") != string::npos); } break; case 23: { Valley v(10, 20); assert(v.rows() == 10 && v.cols() == 20 && v.penguinCount() == 0); } break; case 24: { Valley v(10, 20); v.addPlayer(4, 3); v.addPenguin(5, 2, 'K'); v.addPenguin(5, 3, 'M'); v.addPenguin(5, 4, 'G'); assert(v.penguinCount() == 3); } break; case 25: { Valley v(10, 20); v.addPlayer(4, 3); v.addPenguin(5, 2, 'K'); v.addPenguin(5, 3, 'M'); v.addPenguin(5, 4, 'G'); assert(v.numberOfPenguinsAt(5, 3) == 1 && v.numberOfPenguinsAt(5, 5) == 0); } break; case 26: { Valley v(10, 20); v.addPlayer(4, 3); v.addPenguin(5, 3, 'K'); v.addPenguin(5, 3, 'M'); v.addPenguin(5, 3, 'K'); assert(v.numberOfPenguinsAt(5, 3) == 3 && v.penguinCount() == 3); } break; case 27: { Valley v(2, 3); v.addPlayer(1, 2); v.addPenguin(1, 3, 'G'); v.addPenguin(2, 2, 'M'); ostringstream oss; streambuf *sb = cout.rdbuf(oss.rdbuf()); v.display(""); cout.rdbuf(sb); string s = oss.str(); assert(s.find(".@G") != string::npos && s.find(".M.") != string::npos); } break; case 28: { Valley v(2, 3); v.addPlayer(1, 2); v.player()->setDead(); ostringstream oss; streambuf *sb = cout.rdbuf(oss.rdbuf()); v.display(""); cout.rdbuf(sb); string s = oss.str(); assert(s.find(".X.") != string::npos); } break; case 29: { recordaddrs = true; int oldn = allocMap.size(); { Valley v(10, 20); int oldn2 = allocMap.size(); assert(oldn2 >= oldn); v.addPlayer(4, 3); v.addPenguin(5, 6, 'K'); v.addPenguin(5, 7, 'K'); v.addPenguin(5, 8, 'K'); assert(allocMap.size() == oldn2 + 4); } assert(allocMap.size() == oldn); recordaddrs = false; } break; case 30: { Valley v(10, 20); v.addPlayer(3, 4); for (int r = 2; r <= 10; r += 2) for (int c = 1; c <= 20; c++) assert(v.addPenguin(r, c, 'K')); assert(!v.addPenguin(2, 3, 'K')); } break; case 31: { Valley v(20, 20); v.addPlayer(20, 20); v.addPenguin(1, 1, 'G'); int k; for (k = 0; k < 100; k++) { v.movePenguins('G', EAST); int count = 0; for (int r = 1; r <= 20; r++) count += v.numberOfPenguinsAt(r, 20); if (count == 1) break; } assert(k < 100); } break; case 32: { Valley v(20, 20); v.addPlayer(20, 20); v.addPenguin(1, 1, 'G'); int k; for (k = 0; k < 100; k++) { v.movePenguins('M', EAST); int count = 0; for (int r = 1; r <= 20; r++) count += v.numberOfPenguinsAt(r, 20); if (count == 1) break; } assert(k == 100); } break; case 33: { Valley v(10, 20); v.placeProtrusionAt(1, 4); v.placeProtrusionAt(1, 5); v.placeProtrusionAt(3, 4); v.placeProtrusionAt(3, 5); v.placeProtrusionAt(2, 3); v.placeProtrusionAt(2, 6); v.addPlayer(7, 7); v.addPenguin(2, 4, 'K'); for (int k = 0; k < 100 && v.penguinCount() == 1; k++) v.movePenguins('M', EAST); assert(v.penguinCount() == 1); assert(v.numberOfPenguinsAt(2, 4) == 1 || v.numberOfPenguinsAt(2, 5) == 1); } break; case 34: { Valley v(10, 20); v.placeProtrusionAt(1, 4); v.placeProtrusionAt(1, 5); v.placeProtrusionAt(3, 4); v.placeProtrusionAt(3, 5); v.placeProtrusionAt(2, 3); v.placeProtrusionAt(2, 6); v.addPlayer(7, 7); v.addPenguin(2, 4, 'K'); for (int k = 0; k < 100 && v.penguinCount() == 1; k++) v.movePenguins('K', EAST); assert(v.penguinCount() == 0); assert(v.numberOfPenguinsAt(2, 4) == 0 && v.numberOfPenguinsAt(2, 5) == 0); } break; case 35: { Valley v(10, 20); v.addPlayer(7, 7); for (int k = 0; k < MAXPENGUINS/4; k++) { v.addPenguin(6, 7, 'M'); v.addPenguin(8, 7, 'M'); v.addPenguin(7, 6, 'M'); v.addPenguin(7, 8, 'M'); } assert(! v.player()->isDead()); v.movePenguins('G', NORTH); assert(v.player()->isDead()); } break; case 36: { Valley v(10, 20); for (int c = 2; c <= 20; c += 2) for (int r = 1; r <= 10; r++) v.placeProtrusionAt(r, c); v.addPlayer(1,1); for (int c = 3; c <= 19; c += 2) for (int r = 1; r <= 10; r++) v.addPenguin(r, c, 'K'); for (int k = 0; k < 100 && v.penguinCount() > 0; k++) v.movePenguins('K', EAST); assert(v.penguinCount() == 0); for (int c = 3; c <= 19; c += 2) for (int r = 1; r <= 10; r++) assert(v.addPenguin(r, c, 'M')); assert(v.penguinCount() == 90); } break; case 37: { Valley v(2, 3); v.placeProtrusionAt(1, 3); v.placeProtrusionAt(2, 3); v.addPlayer(1, 2); v.addPenguin(2, 1, 'G'); int d; assert(!recommendMove(v, 1, 2, d)); } break; case 38: { Valley v(2, 3); v.placeProtrusionAt(1, 3); v.placeProtrusionAt(2, 3); v.addPlayer(1, 2); v.addPenguin(1, 1, 'K'); int d; assert(recommendMove(v, 1, 2, d) && d == SOUTH); } break; case 39: { Valley v(2, 3); v.addPlayer(1, 2); for (char s : { 'G', 'M', 'K' }) { v.addPenguin(1, 1, s); for (int k = 0; k < 10; k++) v.addPenguin(2, 3, s); } int d; assert(!recommendMove(v, 1, 2, d)); } break; case 40: { Valley v(2, 3); v.addPlayer(1, 3); for (char s : { 'G', 'M', 'K' }) { v.addPenguin(1, 1, s); for (int k = 0; k < 10; k++) v.addPenguin(2, 3, s); } int d; assert(recommendMove(v, 1, 3, d) && d == WEST); } break; } } int main() { cout << "Enter test number (1-40): "; int n; cin >> n; testone(n); cout << "Passed!" << endl; }