// Piece energy/capacity void test_piece_energy(ErrorContext &ec, unsigned int numRuns) { bool pass; // Run at least once!! assert(numRuns > 0); ec.DESC("--- Test - Piece - Energy/capacity ---"); for (int run = 0; run < numRuns; run++) { ec.DESC("getting agent energy and resource capacities"); { Game g; Simple s(g, Position(0, 0), Game::STARTING_AGENT_ENERGY); Food f(g, Position(1, 1), Game::STARTING_RESOURCE_CAPACITY); Advantage a(g, Position(2, 2), Game::STARTING_RESOURCE_CAPACITY); Agent *agent = &s; Resource *r0 = &f, *r1 = &a; pass = (agent->getEnergy() == Game::STARTING_AGENT_ENERGY) && (r0->getCapacity() == Game::STARTING_RESOURCE_CAPACITY) && (r1->getCapacity() == Game::STARTING_RESOURCE_CAPACITY * Advantage::ADVANTAGE_MULT_FACTOR); ec.result(pass); } } }
// operator>>, operator<< (incl. exceptions) void test_point_IO(ErrorContext &ec, unsigned int numRuns) { bool pass; // Run at least once!! assert(numRuns > 0); ec.DESC("--- Test - Point - Stream IO ---"); for (int run = 0; run < numRuns; run++) { ec.DESC("stream between two points"); { Point p1(50); for (int i = 0; i < 50; i++) p1[i] = 6.12 * i * i + 5.17 * i + 4.19; Point p2(50); std::stringstream iostr; iostr << std::setprecision(20) << p1; // Avoid truncation iostr >> p2; pass = true; for (int i = 0; i < 50; i++) pass = pass && (p2[i] == p1[i]); if (!pass) { std::cout << p1 << std::endl; std::cout << p2 << std::endl; } ec.result(pass); } } }
// operator==, operator!= void test_point_equality(ErrorContext &ec, unsigned int numRuns) { bool pass; // Run at least once!! assert(numRuns > 0); ec.DESC("--- Test - Point - Equal ---"); for (int run = 0; run < numRuns; run++) { ec.DESC("compare equal"); { Point p1(50); for (int i = 0; i < 50; i++) p1[i] = 44.56 * i * i + 23.45 * i + 12.34; Point p2(p1); pass = (p2 == p1); ec.result(pass); } ec.DESC("ensure operator== is not a dummy"); { Point p1(50); for (int i = 0; i < 50; i++) p1[i] = 44.56 * i * i + 23.45 * i + 12.34; Point p2(p1); p2[1] = p2[1] + 1.0; pass = !(p2 == p1); ec.result(pass); } ec.DESC("compare not equal"); { Point p1(50); for (int i = 0; i < 50; i++) p1[i] = 44.56 * i * i + 23.45 * i + 12.34; Point p2(p1); p1[49] = p1[49] + 100.0; pass = (p2 != p1); ec.result(pass); } } }
void test_piece_print(ErrorContext &ec, unsigned int numRuns) { bool pass; // Run at least once!! assert(numRuns > 0); ec.DESC("--- Test - Piece - Id-s, names, printing ---"); for (int run = 0; run < numRuns; run ++) { ec.DESC("piece id-s, names, and printing"); { Game g; // note: Game smoke test is needed first Position p0(0, 0); Simple s(g, p0, 10); Position p1(1, 0); Strategic t(g, p1, 20); Position p2(2, 2); Food f(g, p2, 5); Position p3(0, 2); Advantage a(g, p3, 3); std::stringstream ss; ss << s << ' ' << t << ' ' << f << ' ' << a; int id = 0; std::regex re("S[[:d:]]{1,}[ ]"); // ECMAScript, by default std::smatch m; std::string search_str(ss.str()); // convert string to lvalue // std::regex_search(ss.str(), m, re); std::regex_search(search_str, m, re); if (m.size() != 1) { // parse problem pass = false; } else { std::string matchStr(m[0]); std::regex r("[[:d:]]{1,}"); std::regex_search(matchStr, m, r); id = stoi(m[0]); pass = true; } std::stringstream compare; compare << 'S' << id << " T" << (id+1) << " F" << (id+2) << " D" << (id+3); pass = pass && (ss.str() == compare.str()); ec.result(pass); } } }
// operator>>, operator<< void test_cluster_IO(ErrorContext &ec, unsigned int numRuns) { bool pass; // Run at least once!! assert(numRuns > 0); ec.DESC("--- Test - Cluster - Stream IO ---"); for (int run = 0; run < numRuns; run++) { ec.DESC("read from a file"); { std::ifstream csv("points.csv"); Cluster c; if (csv.is_open()) { csv >> c; csv.close(); } pass = (c.getSize() == 4); ec.result(pass); } ec.DESC("read, write, and read again"); { std::ifstream csv("points.csv"); Cluster c; if (csv.is_open()) { csv >> c; csv.close(); } pass = (c.getSize() == 4); // add a point c.add(Point(5)); std::ofstream csv1("points1.csv", std::ofstream::out); csv1 << c; csv1.close(); std::ifstream csv2("points1.csv"); Cluster c2; if (csv2.is_open()) { csv2 >> c2; csv2.close(); }
// Smoketest: constructor, copy constructor, destructor void test_point_smoketest(ErrorContext &ec) { bool pass; ec.DESC("--- Test - Point - Smoketest ---"); ec.DESC("constructor, dimensionality, destructor"); pass = true; for (int i = 0; i < 10; i ++) { // Construct a Point // At the end of the block, destructor will be called Point p(10); pass = (p.getDims() == 10); if (!pass) break; } ec.result(pass); ec.DESC("constructor, large size"); pass = true; for (int i = 0; i < 10; i ++) { // Construct a Point // At the end of the block, destructor will be called Point p(1000000); pass = (p.getDims() == 1000000); if (!pass) break; } ec.result(pass); ec.DESC("copy constructor"); pass = true; for (int i = 0; i < 10; i ++) { // Construct a Point // At the end of the block, destructor will be called Point p1(10); Point p2(p1); pass = (p1.getDims() == 10 && p2.getDims() == 10); if (!pass) break; } ec.result(pass); }
// operator= void test_point_assignment(ErrorContext &ec, unsigned int numRuns) { bool pass; // Run at least once!! assert(numRuns > 0); ec.DESC("--- Test - Point - Assign ---"); for (int run = 0; run < numRuns; run++) { ec.DESC("simple assignment"); { Point p1(50); for (int i = 0; i < 50; i++) p1[i] = 44.56 * i * i + 23.45 * i + 12.34; Point p2 = p1; pass = true; for (int i = 0; i < 50; i++) pass = pass && (p1[i] == p2[i]); ec.result(pass); } ec.DESC("chained assignment"); { Point p1(50); for (int i = 0; i < 50; i++) p1[i] = 44.56 * i * i + 23.45 * i + 12.34; Point p2(50), p3(50), p4(50), p5(50); p2 = p3 = p4 = p5 = p1; pass = true; for (int i = 0; i < 50; i++) pass = pass && (p1[i] == p2[i]); ec.result(pass); } } }
// subscript (operator[]) void test_cluster_subscript(ErrorContext &ec, unsigned int numRuns) { bool pass; // Run at least once!! assert(numRuns > 0); ec.DESC("--- Test - Cluster - Subscript ---"); for (int run = 0; run < numRuns; run++) { ec.DESC("cluster with one point"); { Cluster c; Point p(10); p[5] = 3.14; c.add(p); Point p1 = c[0]; pass = p1[5] == 3.14; ec.result(pass); } ec.DESC("cluster with several point"); { Cluster c; for (int i = 0; i < 10; i ++) { Point p(10); p[5] = 3.14; c.add(p); } pass = true; for (int i = 0; i < 10; i ++) { Point p1 = c[i]; pass = pass && (p1[5] == 3.14); } ec.result(pass); } } }
// Containment void test_cluster_contain(ErrorContext &ec, unsigned int numRuns) { bool pass; // Run at least once!! assert(numRuns > 0); ec.DESC("--- Test - Cluster - Containment ---"); for (int run = 0; run < numRuns; run++) { ec.DESC("cluster with one point"); { Point p(10); p[0] = p[2] = p[4] = p[8] = 6.705; Cluster c; c.add(p); pass = c.contains(p); ec.result(pass); } ec.DESC("cluster with several points"); { Point p(10); p[0] = p[2] = p[4] = p[8] = 6.705; Cluster c; for (int i = 0; i < 10; i ++) { Point pp(10); for (int j = 0; j < 10; j ++) { pp[i] = 3.4 + i * 2.1 + i * i; } c.add(pp); } c.add(p); pass = c.contains(p); ec.result(pass); } } }
// Copy constructor void test_point_copying(ErrorContext &ec, unsigned int numRuns) { bool pass; // Run at least once!! assert(numRuns > 0); ec.DESC("--- Test - Point - Copy ---"); for (int run = 0; run < numRuns; run ++) { ec.DESC("simple copy"); { Point p1(50); for (int i = 0; i < 50; i ++) p1[i] = 44.56 * i * i + 23.45 * i + 12.34; Point p2(p1); pass = true; for (int i = 0; i < 50; i ++) pass = pass && (p1[i] == p2[i]); ec.result(pass); } ec.DESC("pass and return by value"); { Point p1(50); for (int i = 0; i < 50; i ++) p1[i] = 44.56 * i * i + 23.45 * i + 12.34; Point p2 = point_in_and_out(p1); pass = true; for (int i = 0; i < 50; i ++) pass = pass && (p1[i] == p2[i]); ec.result(pass); } } }
// Copy constructor void test_cluster_copying(ErrorContext &ec, unsigned int numRuns) { bool pass; // Run at least once!! assert(numRuns > 0); ec.DESC("--- Test - Cluster - Copy ---"); for (int run = 0; run < numRuns; run++) { ec.DESC("simple copy"); { Point p1(10), p2(10), p3(10); Cluster c1; c1.add(p1); c1.add(p2); c1.add(p3); Cluster c2(c1); pass = (c1 == c2); ec.result(pass); } ec.DESC("chained copy"); { Point p1(10), p2(10), p3(10); Cluster c1; c1.add(p1); c1.add(p2); c1.add(p3); Cluster c2(c1), c3(c2), c4(c3); pass = (c1 == c4); ec.result(pass); } } }
// Smoketest: constructor, copy constructor, destructor, number of pieces void test_game_smoketest(ErrorContext &ec) { bool pass; ec.DESC("--- Test - Game - Smoketest ---"); ec.DESC("constructor, empty game, default grid size, destructor"); pass = true; for (int i = 0; i < 10; i ++) { Game g; pass = (g.getWidth() == 3 && g.getHeight() == 3 && g.getNumPieces() == 0); } ec.result(pass); ec.DESC("constructor with dimensions"); pass = true; for (int i = 0; i < 10; i ++) { Game g(4, 5); pass = (g.getWidth() == 4 && g.getHeight() == 5 && g.getNumPieces() == 0); } ec.result(pass); ec.DESC("insufficient dimensions (exception generated)"); pass = true; for (int i = 0; i < 10; i ++) { try { Game g(Game::MIN_WIDTH-1, 5); pass = false; } catch (InsufficientDimensionsEx &ex) { std::cerr << "Exception generated: " << ex << std::endl; pass = (ex.getName() == "InsufficientDimensionsEx"); } } ec.result(pass); }
// Smoketest: constructor, copy constructor, destructor void test_cluster_smoketest(ErrorContext &ec) { bool pass; ec.DESC("--- Test - Cluster - Smoketest ---"); ec.DESC("constructor, destructor"); pass = true; for (int i = 0; i < 10; i ++) { Cluster c; } ec.result(pass); ec.DESC("size getter - implement if you haven't"); pass = true; for (int i = 0; i < 10; i ++) { // Construct a Point // At the end of the block, destructor will be called Cluster c; pass = (c.getSize() == 0); if (!pass) break; } ec.result(pass); ec.DESC("copy constructor"); pass = true; for (int i = 0; i < 10; i ++) { Cluster c1, c2(c1); pass = (c1 == c2); if (!pass) break; } ec.result(pass); }
// id void test_point_id(ErrorContext &ec, unsigned int numRuns) { bool pass; // Run at least once!! assert(numRuns > 0); ec.DESC("--- Test - Point - Point ID ---"); for (int run = 0; run < numRuns; run ++) { ec.DESC("get a point's id"); { Point p(15); pass = (p.getId() >= 0); ec.result(pass); } ec.DESC("sequential id-s"); { Point **points = new Point*[100]; for (int i=0; i<100; i++) points[i] = new Point(15); pass = true; int firstId = points[0]->getId(); for (int i=0; i<100; i++) pass = pass && (points[i]->getId() == (firstId + i)); for (int i=0; i<100; i++) delete points[i]; delete [] points; ec.result(pass); } } }
// operator==, operator!= void test_cluster_equality(ErrorContext &ec, unsigned int numRuns) { bool pass; // Run at least once!! assert(numRuns > 0); ec.DESC("--- Test - Cluster - Equal ---"); for (int run = 0; run < numRuns; run++) { ec.DESC("check operator== is not a dummy"); { // The requirements don't provide for many other methods that // can be used for testing, so operator== is checked first Cluster c1, c2; c1.add(Point(100)); pass = !(c1 == c2); ec.result(pass); } ec.DESC("check inequality"); { // The requirements don't provide for many other methods that // can be used for testing, so operator== is checked first Cluster c1, c2; c1.add(Point(100)); pass = (c1 != c2); ec.result(pass); } } }
void empty(ErrorContext &ec) { ec.DESC("--- Empty matrices (0 by 0) ---"); // If this test fails, it means that getrows returned a non-zero value // when called on an "empty" (0x0) matrix created with the default // constructor. ec.DESC("default constructor and getrows"); // Construct an empty matrix using the default constructor. const Matrix a; // Make sure 'getrows' method returns zero for this matrix. ec.result(a.getrows() == 0); // Same as above, for getcols instead of getrows. ec.DESC("default constructor and getcols"); ec.result(a.getcols() == 0); // If this test fails, it means that getrows returned a non-zero value // when called on an "empty" (0x0) matrix created with the 2-argument // constructor. ec.DESC("two-argument constructor and getrows"); // Construct an empty matrix using the two-argument constructor. const Matrix b(0, 0); // Make sure 'getrows' method returns zero for this matrix. ec.result(b.getrows() == 0); // Same as above, for getcols instead of getrows. ec.DESC("two-argument constructor and getcols"); ec.result(b.getcols() == 0); }
// Smoketest: constructor, copy constructor, destructor, resources void test_piece_smoketest(ErrorContext &ec) { bool pass; ec.DESC("--- Test - Unit - Smoketest ---"); ec.DESC("constructor, destructor for leaf classes from Piece hierarchy"); pass = true; for (int i = 0; i < 10; i++) { Game g; // note: Game smoke test is needed first Position p0(0, 0); Simple s(g, p0, 10); Position p1(1, 0); Strategic t(g, p1, 20); Position p2(2, 2); Food f(g, p2, 5); Position p3(0, 2); Advantage a(g, p3, 3); } ec.result(pass); }
// Surroundings (vector of enums of type PieceType) smoke test void test_surroundings_smoketest(ErrorContext &ec) { bool pass; ec.DESC("--- Test - Surroundings - Smoketest ---"); ec.DESC("printing PieceTypes"); pass = true; for (int i = 0; i < 10; i ++) { std::stringstream ss; ss << PieceType::SIMPLE << ' ' << PieceType::STRATEGIC << ' ' << PieceType::FOOD << ' ' << PieceType::ADVANTAGE << ' ' << PieceType::INACCESSIBLE << ' ' << PieceType::SELF << ' ' << PieceType::EMPTY; pass = (ss.str() == "0 1 2 3 4 5 6"); // if (! pass) std::cout << ss.str() << std::endl; } ec.result(pass); ec.DESC("3x3 grid, manual, surroundings of agents"); pass = true; for (int i = 0; i < 10; i ++) { Game g; // note: Game smoke test required first Position p0(0, 0); g.addSimple(p0); Position p1(1, 0); g.addStrategic(p1); Position p2(2, 2); g.addFood(p2); Position p3(0, 2); g.addAdvantage(p3); // The surroundings of the simple agent Surroundings surr = g.getSurroundings(p0); std::stringstream ss0; for (int i = 0; i < 9; i++) ss0 << surr.array[i] << ' '; pass = (ss0.str() == "4 4 4 4 5 6 4 1 6 "); if (! pass) std::cout << ss0.str() << std::endl; // The surroundings of the strategic agent surr = g.getSurroundings(p1); std::stringstream ss1; for (int i = 0; i < 9; i++) ss1 << surr.array[i] << ' '; pass = pass && (ss1.str() == "4 0 6 4 5 6 4 6 6 "); if (! pass) std::cout << ss1.str() << std::endl; } ec.result(pass); ec.DESC("4x5 grid, manual, surroundings of agents"); pass = true; for (int i = 0; i < 10; i ++) { Game g(4, 5); // note: Game smoke test required first // std::cout << g << std::endl; g.addSimple(0, 1); Position p0(0, 1); g.addAdvantage(1, 0); g.addAdvantage(1, 1); g.addFood(1, 3); g.addStrategic(2, 2); Position p1(2, 2); g.addFood(3, 1); g.addSimple(3, 2); Position p2(3, 2); g.addStrategic(4, 3); Position p3(4, 3); // The surroundings of the simple agent at p0 Surroundings surr = g.getSurroundings(p0); std::stringstream ss0; for (int i = 0; i < 9; i++) ss0 << surr.array[i] << ' '; pass = (ss0.str() == "4 4 4 6 5 6 3 3 6 "); if (! pass) std::cout << ss0.str() << std::endl; // The surroundings of the strategic agent at p1 surr = g.getSurroundings(p1); std::stringstream ss1; for (int i = 0; i < 9; i++) ss1 << surr.array[i] << ' '; pass = pass && (ss1.str() == "3 6 2 6 5 6 2 0 6 "); if (! pass) std::cout << ss1.str() << std::endl; // The surroundings of the simple agent at p2 surr = g.getSurroundings(p2); std::stringstream ss2; for (int i = 0; i < 9; i++) ss2 << surr.array[i] << ' '; pass = pass && (ss2.str() == "6 1 6 2 5 6 6 6 1 "); if (! pass) std::cout << ss2.str() << std::endl; // The surroundings of the strategic agent at p3 surr = g.getSurroundings(p3); std::stringstream ss3; for (int i = 0; i < 9; i++) ss3 << surr.array[i] << ' '; pass = pass && (ss3.str() == "0 6 4 6 5 4 4 4 4 "); if (! pass) std::cout << ss3.str() << std::endl; } ec.result(pass); }
// add, remove void test_cluster_addremove(ErrorContext &ec, unsigned int numRuns) { bool pass; // Run at least once!! assert(numRuns > 0); ec.DESC("--- Test - Cluster - Add/remove points ---"); for (int run = 0; run < numRuns; run++) { ec.DESC("add and check with size getter"); { Cluster c1; c1.add(Point(50)); c1.add(Point(50)); c1.add(Point(50)); pass = (c1.getSize() == 3); ec.result(pass); } // by default, points will get released here ec.DESC("add, remove, and check with size getter"); { Point p1(10), p2(10), p3(10); Cluster c1; c1.add(p1); c1.add(p2); c1.add(p3); c1.remove(p1); c1.remove(p2); c1.remove(p3); pass = (c1.getSize() == 0); if (!pass) { std::cout << std::endl; std::cout << c1 << std::endl; std::cout << std::endl; } ec.result(pass); } // by default, points will get released here ec.DESC("add, check with cluster equality, remove"); { Point p1(10), p2(10), p3(10); Cluster c1, c2; c1.add(p1); c1.add(p2); c1.add(p3); c2.add(p1); c2.add(p2); c2.add(p3); pass = (c1 == c2); // don't forget to remove the points from one // of the clusters to avoid the "double delete" c2.remove(p1); c2.remove(p2); c2.remove(p3); ec.result(pass); } ec.DESC("check point after add and remove"); { Point p1(10); for (int i = 0; i < 10; i++) p1[i] = 5.4 * i * i + 3.4 * i + 1.6; Cluster c1; c1.add(p1); Point p2 = c1.remove(p1); pass = (p1 == p2); ec.result(pass); } } }
// Action smoke test void test_action_smoketest(ErrorContext &ec) { bool pass; ec.DESC("--- Test - Action - Smoketest ---"); ec.DESC("printing ActionType"); pass = true; for (int i = 0; i < 10; i ++) { std::stringstream ss; ss << ActionType::N << ' ' << ActionType::NE << ' ' << ActionType::NW << ' ' << ActionType::E << ' ' << ActionType::W << ' ' << ActionType::SE << ' ' << ActionType::SW << ' ' << ActionType::S << ' ' << ActionType::STAY; pass = (ss.str() == "0 1 2 3 4 5 6 7 8"); // if (! pass) std::cout << ss.str() << std::endl; } ec.result(pass); ec.DESC("3x3, manual, agent in the middle"); pass = true; for (int i = 0; i < 10; i ++) { Game g; // not actually necessary for the test g.addSimple(1, 1); Position pos(1, 1); pass = g.isLegal(ActionType::N, pos) && g.isLegal(ActionType::NE, pos) && g.isLegal(ActionType::NW, pos) && g.isLegal(ActionType::E, pos) && g.isLegal(ActionType::W, pos) && g.isLegal(ActionType::SE, pos) && g.isLegal(ActionType::SW, pos) && g.isLegal(ActionType::S, pos) && g.isLegal(ActionType::STAY, pos); } ec.result(pass); ec.DESC("7x6, manual, agent in the SW corner"); pass = true; for (int i = 0; i < 10; i ++) { Game g(7, 6); // not actually necessary for the test g.addSimple(5, 6); Position pos(5, 6); pass = g.isLegal(ActionType::N, pos) && (! g.isLegal(ActionType::NE, pos)) && g.isLegal(ActionType::NW, pos) && (! g.isLegal(ActionType::E, pos)) && g.isLegal(ActionType::W, pos) && (! g.isLegal(ActionType::SE, pos)) && (! g.isLegal(ActionType::SW, pos)) && (! g.isLegal(ActionType::S, pos)) && g.isLegal(ActionType::STAY, pos); } ec.result(pass); ec.DESC("7x6, movement from position to position"); pass = true; for (int i = 0; i < 10; i ++) { Game g(13, 9); // width - y, height - x g.addSimple(0, 12); Position ne(0, 12); Position p0 = (g.isLegal(ActionType::NE, ne)) ? g.move(ne, ActionType::NE) : ne; pass = (p0.x == ne.x) && (p0.y == ne.y); p0 = (g.isLegal(ActionType::S, ne)) ? g.move(ne, ActionType::S) : ne; pass = pass && (p0.x == ne.x+1) && (p0.y == ne.y); p0 = (g.isLegal(ActionType::W, ne)) ? g.move(ne, ActionType::W) : ne; pass = pass && (p0.x == ne.x) && (p0.y == ne.y-1); p0 = (g.isLegal(ActionType::SE, ne)) ? g.move(ne, ActionType::SE) : ne; pass = pass && (p0.x == ne.x) && (p0.y == ne.y); } ec.result(pass); ec.DESC("7x6, action needed to reach one position from another"); pass = true; for (int i = 0; i < 10; i ++) { Game g(5, 5); g.addSimple(1, 1); Position simpos(1, 1); g.addFood(1, 2); Position foodpos(1, 2); pass = (Game::reachSurroundings(simpos, foodpos) == ActionType::E); g.addAdvantage(0, 1); Position adpos(0, 1); pass = pass && (Game::reachSurroundings(simpos, adpos) == ActionType::N); Position newpos(2, 0); pass = pass && (Game::reachSurroundings(simpos, newpos) == ActionType::SW); } ec.result(pass); }
// distanceTo void test_point_distance(ErrorContext &ec, unsigned int numRuns) { bool pass; // Run at least once!! assert(numRuns > 0); ec.DESC("--- Test - Point - Distance ---"); for (int run = 0; run < numRuns; run++) { ec.DESC("same point"); { Point p1(50); for (int i = 0; i < 50; i++) p1[i] = 2.4 * i * i + 1.3 * i + 6.7; Point p2(p1); pass = (p1.distanceTo(p2) == 0); ec.result(pass); } ec.DESC("5 units away"); { Point p1(50); for (int i = 0; i < 50; i++) p1[i] = i; Point p2(p1); p2[1] += 5; pass = (p1.distanceTo(p2) == 5); if (!pass) std::cout << p1.distanceTo(p2) << " "; ec.result(pass); } // Integer sequence A180442 ec.DESC("distance 1612 from origin"); { Point p1(169); // 198 - 29 unsigned int start = 30; for (int i = 0; i < 169; i++) { p1[i] = start; start++; } Point origin(169); // relies on initialization to zeros pass = (p1.distanceTo(origin) == 1612); if (!pass) std::cout << p1.distanceTo(origin) << " "; ec.result(pass); } } }
//operator+, operator-, operator*, operator/ void test_point_SAO(ErrorContext &ec, unsigned int numRuns) { bool pass; // Run at least once!! assert(numRuns > 0); ec.DESC("--- Test - Point - Simple arithmetic ---"); for (int run = 0; run < numRuns; run++) { ec.DESC("plus (two points)"); { Point p1(50), p2(50); for (int i = 0; i < 50; i++) { p1[i] = i; p2[i] = i + 1; } Point p3 = p1 + p2; pass = true; for (int i = 0; i < 50; i++) { pass = pass && (p3[i] == 2 * i + 1); } ec.result(pass); } ec.DESC("minus (two points)"); { Point p1(50), p2(50); for (int i = 0; i < 50; i++) { p1[i] = i + 1; p2[i] = 2 * i - 1; } Point p3 = p2 - p1; pass = true; for (int i = 0; i < 50; i++) { pass = pass && (p3[i] == i - 2); } ec.result(pass); } ec.DESC("times (point and double)"); { Point p1(50); for (int i = 0; i < 50; i++) { p1[i] = i; } Point p2 = p1 * 3.14; pass = true; for (int i = 0; i < 50; i++) { pass = pass && (p2[i] == 3.14 * i); } ec.result(pass); } ec.DESC("divide (point and double)"); { Point p1(50); for (int i = 0; i < 50; i++) { p1[i] = 100.0 * i; } Point p2 = p1 / 3.14; pass = true; for (int i = 0; i < 50; i++) { pass = pass && (p2[i] == 100.0 * i / 3.14); } ec.result(pass); } } }
// operator+, operator-, different rhs void test_cluster_SAO(ErrorContext &ec, unsigned int numRuns) { bool pass; // Run at least once!! assert(numRuns > 0); ec.DESC("--- Test - Cluster - Simple arithmetic ---"); for (int run = 0; run < numRuns; run++) { ec.DESC("plus (Cluster and Point)"); { Cluster c1, c2; Point p1(50), p2(50), p3(50), p4(50); c1.add(p1); c1.add(p2); c1.add(p3); c2 = c1; c2.add(p4); Cluster c3 = c1 + p4; pass = (c3 == c2); ec.result(pass); } ec.DESC("minus (Cluster and Point)"); { Cluster c1, c2; Point p1(50), p2(50), p3(50), p4(50); c1.add(p1); c1.add(p2); c1.add(p3); c1.add(p4); c2 = c1; c2.remove(p4); Cluster c3 = c1 - p4; pass = (c3 == c2); ec.result(pass); } ec.DESC("plus (Cluster union)"); { Cluster c1, c2; Point p1(50), p2(50), p3(50), p4(50), p5(50); c1.add(p1); c1.add(p2); c1.add(p3); c2.add(p4); c2.add(p5); Cluster c3; c3.add(p1); c3.add(p2); c3.add(p3); c3.add(p4); c3.add(p5); Cluster c4 = c1 + c2; pass = (c4 == c3); ec.result(pass); } ec.DESC("minus (Cluster difference)"); { Cluster c1, c2; Point p1(50), p2(50), p3(50), p4(50), p5(50); c1.add(p1); c1.add(p2); c1.add(p3); c2.add(p3); c2.add(p4); c2.add(p5); Cluster c3; c3.add(p1); c3.add(p2); Cluster c4 = c1 - c2; pass = (c4 == c3); ec.result(pass); } } }
// operator<, operator<=, operator>, operator>= // (pseudo-lexicographic comparison) void test_point_comparison(ErrorContext &ec, unsigned int numRuns) { bool pass; // Run at least once!! assert(numRuns > 0); ec.DESC("--- Test - Point - Compare ---"); for (int run = 0; run < numRuns; run++) { ec.DESC("compare pseudo-lexicographic order"); { Point p1(50), p2(50), p3(50); for (int i = 0; i < 50; i ++) { p1[i] = i; p2[i] = i + 1.0; p3[i] = i + 2.0; } pass = (p1 < p2) && (p2 < p3) && (p1 < p3); ec.result(pass); } ec.DESC("less than, one different value, leading"); { Point p1(50), p2(50), p3(50); for (int i = 0; i < 50; i ++) { p1[i] = p2[i] = p3[i] = i; } p2[1] = p1[1] + std::numeric_limits<double>::epsilon(); p3[1] = p2[1] + std::numeric_limits<double>::epsilon(); pass = (p1 < p2) && (p2 < p3) && (p1 < p3); ec.result(pass); } ec.DESC("less than, one different value, middle"); { Point p1(50), p2(50), p3(50); for (int i = 0; i < 50; i ++) { p1[i] = p2[i] = p3[i] = i; } p2[30] = p1[30] + 0.00000001; p3[30] = p2[30] + 0.00000001; pass = (p1 < p2) && (p2 < p3) && (p1 < p3); ec.result(pass); } ec.DESC("less than, one different value, trailing"); { Point p1(50), p2(50), p3(50); for (int i = 0; i < 50; i ++) { p1[i] = p2[i] = p3[i] = i; } p2[49] = p1[49] + 0.00000001; p3[49] = p2[49] + 0.00000001; pass = (p1 < p2) && (p2 < p3) && (p1 < p3); ec.result(pass); } ec.DESC("less than or equal, equal values"); { Point p1(50), p2(50), p3(50); for (int i = 0; i < 50; i ++) { p1[i] = p2[i] = p3[i] = i; } pass = (p1 <= p2) && (p2 <= p3) && (p1 <= p3); ec.result(pass); } ec.DESC("less than or equal, one different value, trailing"); { Point p1(50), p2(50), p3(50); for (int i = 0; i < 50; i ++) { p1[i] = p2[i] = p3[i] = i; } p2[49] = p1[49] + 0.00000001; p3[49] = p2[49] + 0.00000001; pass = (p1 <= p2) && (p2 <= p3) && (p1 <= p3); ec.result(pass); } ec.DESC("more than or equal, equal values"); { Point p1(50), p2(50), p3(50); for (int i = 0; i < 50; i ++) { p1[i] = p2[i] = p3[i] = i; } pass = (p1 >= p2) && (p2 >= p3) && (p1 >= p3); ec.result(pass); } ec.DESC("more than or equal, one different value, middle"); { Point p1(50), p2(50), p3(50); for (int i = 0; i < 50; i ++) { p1[i] = p2[i] = p3[i] = i; } p2[30] = p3[30] + 0.00000001; p1[30] = p2[30] + 0.00000001; pass = (p1 >= p2) && (p2 >= p3) && (p1 >= p3); ec.result(pass); } ec.DESC("more than, one different value, middle"); { Point p1(50), p2(50), p3(50); for (int i = 0; i < 50; i ++) { p1[i] = p2[i] = p3[i] = i; } p2[30] = p3[30] + 0.00000001; p1[30] = p2[30] + 0.00000001; pass = (p1 > p2) && (p2 > p3) && (p1 > p3); ec.result(pass); } } }
// populate the game grid void test_game_populate(ErrorContext &ec, unsigned int numRuns) { bool pass; // Run at least once!! assert(numRuns > 0); ec.DESC("--- Test - Game - Populate ---"); // note: piece smoke test needed first for (int run = 0; run < numRuns; run ++) { ec.DESC("3x3 grid, manual population"); { Game g; g.addSimple(0, 0); g.addStrategic(1, 1); g.addFood(0, 2); g.addFood(2, 1); g.addAdvantage(2, 2); pass = (g.getNumPieces() == 5) && (g.getNumAgents() == 2) && (g.getNumResources() == 3); ec.result(pass); } ec.DESC("4x5 grid, manual population"); { Game g(4, 5); g.addSimple(0, 0); g.addStrategic(1, 1); g.addFood(0, 2); g.addFood(2, 1); g.addAdvantage(2, 2); g.addSimple(4, 3); g.addAdvantage(2, 3); try { g.addFood(4, 3); pass = false; } catch (PositionNonemptyEx &ex) { std::cerr << "Exception generated: " << ex << std::endl; pass = (ex.getName() == "PositionNonemptyEx"); } try { g.addStrategic(0, 2); pass = false; } catch (PositionNonemptyEx &ex) { std::cerr << "Exception generated: " << ex << std::endl; pass = (ex.getName() == "PositionNonemptyEx"); } pass = pass && (g.getNumPieces() == 7) && (g.getNumAgents() == 3) && (g.getNumResources() == 4); ec.result(pass); } ec.DESC("4x5 grid, manual, out of bounds (exception generated)"); { Game g(4, 5); g.addSimple(0, 0); g.addStrategic(1, 1); g.addFood(0, 2); try { g.addAdvantage(4, 5); pass = false; } catch (OutOfBoundsEx &ex) { std::cerr << "Exception generated: " << ex << std::endl; pass = pass && (ex.getName() == "OutOfBoundsEx"); } try { Position pos(6, 10); g.addStrategic(pos); pass = false; } catch (OutOfBoundsEx &ex) { std::cerr << "Exception generated: " << ex << std::endl; pass = pass && (ex.getName() == "OutOfBoundsEx"); } ec.result(pass); } ec.DESC("3x3 grid, auto population"); { Game g(3, 3, false); pass = (g.getNumAgents() == 2) && (g.getNumResources() == 4); ec.result(pass); } ec.DESC("4x5 grid, auto population"); { Game g(4, 5, false); pass = (g.getNumAgents() == 5) && (g.getNumResources() == 10); ec.result(pass); } ec.DESC("9x9 grid, auto population"); { Game g(9, 9, false); pass = (g.getNumAgents() == 20) && (g.getNumResources() == 40); if (! pass) std::cout << g.getNumAgents() << ' ' << g.getNumResources() << ' ' << std::endl << g << ' '; ec.result(pass); } } }
// ascending pseudo-lexicographic order void test_cluster_order(ErrorContext &ec, unsigned int numRuns) { bool pass; // Run at least once!! assert(numRuns > 0); ec.DESC("--- Test - Cluster - Order ---"); for (int run = 0; run < numRuns; run++) { ec.DESC("points in a cluster are sorted"); { Point p1(5), p2(5), p3(5), p4(5), p5(5); p1[0] = 1; p2[1] = 1; p3[2] = 1; p4[3] = 1; p5[4] = 1; Cluster c; c.add(p1); c.add(p2); c.add(p4); c.add(p3); c.add(p5); pass = (c[0] == p5) && (c[1] == p4) && (c[2] == p3) && (c[3] == p2) && (c[4] == p1); if (!pass) { std::cout << std::endl; std::cout << c << std::endl; std::cout << std::endl; } ec.result(pass); } ec.DESC("ascending pseudo-lexicographic order"); { Point p1(5), p2(5), p3(5), p4(5), p5(5); p1[0] = 1; p2[1] = 1; p3[2] = -1; p4[3] = 1; p5[4] = -1; Cluster c; c.add(p1); c.add(p2); c.add(p4); c.add(p3); c.add(p5); pass = (c[0] == p3) && (c[1] == p5) && (c[2] == p4) && (c[3] == p2) && (c[4] == p1); if (!pass) { std::cout << std::endl; std::cout << c << std::endl; std::cout << std::endl; } ec.result(pass); } } }
// operator+=, operator-=, different rhs void test_cluster_CAO(ErrorContext &ec, unsigned int numRuns) { bool pass; // Run at least once!! assert(numRuns > 0); ec.DESC("--- Test - Cluster - Compound arithmetic ---"); for (int run = 0; run < numRuns; run++) { ec.DESC("plus equals (Cluster and Point) check with non-equality"); { Cluster c1, c2; Point p1(50); for (int i = 0; i < 50; i++) p1[i] = 6.75 * i * i + 5.45 * i + 1.15; c1 += p1; pass = !(c1 == c2); ec.result(pass); } ec.DESC("plus equals (Cluster and Point) check with size getter"); { Cluster c1; Point p1(50); for (int i = 0; i < 50; i++) p1[i] = 6.75 * i * i + 5.45 * i + 1.15; c1 += p1; pass = (c1.getSize() == 1); ec.result(pass); } ec.DESC("minus equals (Cluster and Point) check with non-equality"); { Cluster c1, c2; Point p1(50); for (int i = 0; i < 50; i++) p1[i] = 6.75 * i * i + 5.45 * i + 1.15; c1 += p1; pass = !(c1 == c2); c1 -= p1; pass = (c1 == c2); ec.result(pass); } ec.DESC("minus equals (Cluster and Point) check with size getter"); { Cluster c1; Point p1(50); for (int i = 0; i < 50; i++) p1[i] = 6.75 * i * i + 5.45 * i + 1.15; c1 += p1; pass = (c1.getSize() == 1); c1 -= p1; pass = (c1.getSize() == 0); ec.result(pass); } ec.DESC("plus equals (Cluster union) no common points"); { Cluster c1, c2, c3; Point p1(50), p2(50), p3(50), p4(50), p5(50); c1.add(p1); c1.add(p2); c1.add(p3); c2.add(p4); c2.add(p5); // create a union to compare to c3.add(p1); c3.add(p2); c3.add(p3); c3.add(p4); c3.add(p5); c1 += c2; pass = (c1 == c3); ec.result(pass); } ec.DESC("plus equals (Cluster union) one common point"); { Cluster c1, c2, c3; Point p1(50), p2(50), p3(50), p4(50), p5(50); c1.add(p1); c1.add(p2); c1.add(p3); c2.add(p3); c2.add(p4); c2.add(p5); // create a union to compare to c3.add(p1); c3.add(p2); c3.add(p3); c3.add(p4); c3.add(p5); c1 += c2; pass = (c1 == c3); ec.result(pass); } ec.DESC("plus equals (Cluster union) two equal clusters"); { Cluster c1, c2; Point p1(50), p2(50), p3(50), p4(50), p5(50); c1.add(p1); c1.add(p2); c1.add(p3); c1.add(p4); c1.add(p5); c2.add(p1); c2.add(p2); c2.add(p3); c2.add(p4); c2.add(p5); c1 += c2; pass = (c1 == c2); ec.result(pass); } ec.DESC("minus equals (asymmetric Cluster difference) no common points"); { Cluster c1, c2, c3; Point p1(50), p2(50), p3(50), p4(50), p5(50); c1.add(p1); c1.add(p2); c1.add(p3); c2.add(p4); c2.add(p5); c3 = c1; c1 -= c2; pass = (c1 == c3); ec.result(pass); } ec.DESC("minus equals (asymmetric Cluster difference) one common point"); { Cluster c1, c2, c3; Point p1(50), p2(50), p3(50), p4(50), p5(50); c1.add(p1); c1.add(p2); c1.add(p3); c2.add(p3); c2.add(p4); c2.add(p5); // Prepare a difference to compare to c3.add(p1); c3.add(p2); c1 -= c2; pass = (c1 == c3); ec.result(pass); } ec.DESC("minus equals (asymmetric Cluster difference) two equal clusters"); { Cluster c1, c2, c3; Point p1(50), p2(50), p3(50), p4(50), p5(50); c1.add(p1); c1.add(p2); c1.add(p3); c1.add(p4); c1.add(p5); c2.add(p1); c2.add(p2); c2.add(p3); c2.add(p4); c2.add(p5); c1 -= c2; pass = (c1 == c3); // c1 should be empty ec.result(pass); } } }
//operator+=, operator-=, operator*=, operator/= void test_point_CAO(ErrorContext &ec, unsigned int numRuns) { bool pass; // Run at least once!! assert(numRuns > 0); ec.DESC("--- Test - Point - Compound arithmetic ---"); for (int run = 0; run < numRuns; run++) { ec.DESC("plus equals (two points)"); { Point p1(50), p2(50); for (int i = 0; i < 50; i++) { p1[i] = i; p2[i] = i + 1; } Point p3(50); p3 += p1 += p2; pass = true; for (int i = 0; i < 50; i++) { pass = pass && (p3[i] == 2 * i + 1); } ec.result(pass); } ec.DESC("minus equals (two points)"); { Point p1(50), p2(50), p3(50); for (int i = 0; i < 50; i++) { p1[i] = i; p2[i] = i + 1; p3[i] = 3 * i + 1; } p3 -= p2 -= p1; pass = true; for (int i = 0; i < 50; i++) { pass = pass && (p3[i] == 3 * i); } ec.result(pass); } ec.DESC("times equals (point and double)"); { Point p1(50); for (int i = 0; i < 50; i++) { p1[i] = i; } p1 *= 3.14; pass = true; for (int i = 0; i < 50; i++) { pass = pass && (p1[i] == 3.14 * i); } ec.result(pass); } ec.DESC("divide equals (point and double)"); { Point p1(50); for (int i = 0; i < 50; i++) { p1[i] = 100.0 * i; } p1 /= 3.14; pass = true; for (int i = 0; i < 50; i++) { pass = pass && (p1[i] == 100.0 * i / 3.14); } ec.result(pass); } } }
//// operator= void test_cluster_assignment(ErrorContext &ec, unsigned int numRuns) { bool pass; // Run at least once!! assert(numRuns > 0); ec.DESC("--- Test - Cluster - Assign ---"); for (int run = 0; run < numRuns; run++) { ec.DESC("simple assignment"); { Point p1(10), p2(10), p3(10); Cluster c1; c1.add(p1); c1.add(p2); c1.add(p3); Cluster c2 = c1; pass = (c1 == c2); ec.result(pass); } ec.DESC("assignment causing deletion"); { Point p1(10), p2(10), p3(10); Cluster c1; c1.add(p1); c1.add(p2); c1.add(p3); Cluster c2; // add some other points c2.add(Point(10)); c2.add(Point(10)); c2.add(Point(10)); c2 = c1; pass = (c1 == c2); ec.result(pass); } ec.DESC("chained assignment"); { Point p1(10), p2(10), p3(10); Cluster c1; c1.add(p1); c1.add(p2); c1.add(p3); Cluster c2 = c1; Cluster c3 = c2; Cluster c4 = c3; pass = (c1 == c4); ec.result(pass); } } }
// setValue, getValue, operator[] void test_point_getsetelem(ErrorContext &ec, unsigned int numRuns) { bool pass; // Run at least once!! assert(numRuns > 0); ec.DESC("--- Test - Point - Get/set element ---"); for (int run = 0; run < numRuns; run ++) { ec.DESC("values default to zero"); { Point p(50); // Check zeros pass = true; for (int i = 0; i < 50; i ++) { pass = pass && (p.getValue(i) == 0.0) && (p[i] == 0.0); } ec.result(pass); } ec.DESC("setValue, getValue (0-indexed)"); { Point p(20); // Set values for (int i = 0; i < 20; i ++) p.setValue(i, 13.43 * i * i + 4.567 * i + 1.234567); // Check values pass = true; for (int i = 0; i < 20; i ++) pass = pass && (p.getValue(i) == (13.43 * i * i + 4.567 * i + 1.234567)) && (p[i] == (13.43 * i * i + 4.567 * i + 1.234567)); ec.result(pass); } ec.DESC("operator[] (0-indexed)"); { Point p(5); // Set values for (int i = 0; i < 5; i ++) p[i] = 1000000.43 * i * i + 400000.567 * i + 10000.234567; // Check values pass = true; for (int i = 0; i < 5; i ++) pass = pass && (p.getValue(i) == (1000000.43 * i * i + 400000.567 * i + 10000.234567)) && (p[i] == (1000000.43 * i * i + 400000.567 * i + 10000.234567)); ec.result(pass); } } }