#include #include #include #include #include #include #include #include /* * Beam test */ START_TEST(test_beam) { XImage *xi; /* Load level1 image dump */ FILE *f = fopen("level1.dump", "rb"); fail_if(f == NULL, "Unable to open level1.dump"); xi = x_imagedump_load(f); fail_if(xi == NULL, "Unable to load level1.dump"); fclose(f); position_t pos = {11, 35}; pixel_t pill_color = x_pixel_from_rgb(222, 222, 222); pixel_t wall_color = x_pixel_from_rgb(255, 0, 0); beam_result_t res; position_t expected; /* Try to beam down (next pixel is still of the color of "color") */ res = send_beam(xi, pos, DIR_DOWN); fail_unless(res.dst == 1, "Wrong distance"); fail_unless(res.pixel == pill_color, "Wrong pixel color"); expected.x = 11; expected.y = 36; fail_unless(res.pos.x == expected.x && res.pos.y == expected.y, "Wrong position"); /* Try to beam up (should be a red wall) */ res = send_beam(xi, pos, DIR_UP); fail_unless(res.dst == 8, "Wrong distance"); fail_unless(res.pixel == wall_color, "Wrong pixel color"); expected.x = 11; expected.y = 27; fail_unless(res.pos.x == expected.x && res.pos.y == expected.y, "Wrong position"); /* Try to beam left (should be a red wall) */ res = send_beam(xi, pos, DIR_LEFT); fail_unless(res.dst == 8, "Wrong distance"); fail_unless(res.pixel == wall_color, "Wrong pixel color"); expected.x = 3; expected.y = 35; fail_unless(res.pos.x == expected.x && res.pos.y == expected.y, "Wrong position"); /* Try to beam right (pill) */ res = send_beam(xi, pos, DIR_RIGHT); fail_unless(res.dst == 1, "Wrong distance"); fail_unless(res.pixel == pill_color, "Wrong pixel color"); expected.x = 12; expected.y = 35; fail_unless(res.pos.x == expected.x && res.pos.y == expected.y, "Wrong position"); XDestroyImage(xi); } END_TEST /* * Here we try to go the 4 edges of the pill */ START_TEST(test_goto_edge) { XImage *xi; /* Load level1 image dump */ FILE *f = fopen("level1.dump", "r"); xi = x_imagedump_load(f); fclose(f); position_t pos = {11, 35}; /* We are at top/left of the pill */ position_t res; /* Try up */ res = pill_goto_edge(xi, pos, DIR_UP); fail_unless(res.x == pos.x && res.y == pos.y, "Bad move (UP)"); /* Try left */ res = pill_goto_edge(xi, pos, DIR_LEFT); fail_unless(res.x == pos.x && res.y == pos.y, "Bad move (LEFT)"); /* Try down */ res = pill_goto_edge(xi, pos, DIR_DOWN); fail_unless(res.x == pos.x && res.y == pos.y+1, "Bad move (DOWN)"); /* Try right */ res = pill_goto_edge(xi, pos, DIR_RIGHT); fail_unless(res.x == pos.x+1 && res.y == pos.y, "Bad move (RIGHT) : result : (%d, %d), expected (%d, %d)", res.x, res.y, pos.x+1, pos.y); /* We are at top/left, goto : top/right, bottom/right, bottom/left, * then come back to top/left */ /* -> top/right */ res = pill_goto_edge(xi, pos, DIR_RIGHT); fail_unless(res.x == pos.x+1 && res.y == pos.y, "Bad move (TOP/RIGHT) : result : (%d, %d), expected (%d, %d)", res.x, res.y, pos.x+1, pos.y); pos = res; /* -> bottom/right */ res = pill_goto_edge(xi, pos, DIR_DOWN); fail_unless(res.x == pos.x && res.y == pos.y+1, "Bad move (BOTTOM/RIGHT) : result : (%d, %d), expected (%d, %d)", res.x, res.y, pos.x, pos.y+1); pos = res; /* -> bottom/left */ res = pill_goto_edge(xi, pos, DIR_LEFT); fail_unless(res.x == pos.x-1 && res.y == pos.y, "Bad move (BOTTOM/LEFT) : result : (%d, %d), expected (%d, %d)", res.x-1, res.y, pos.x, pos.y); pos = res; /* -> top/left */ res = pill_goto_edge(xi, pos, DIR_UP); fail_unless(res.x == pos.x && res.y == pos.y-1, "Bad move (TOP/LEFT) : result : (%d, %d), expected (%d, %d)", res.x-1, res.y, pos.x, pos.y-1); pos = res; fail_unless(pos.x == 11 && pos.y == 35, "Cycle wasn't well done"); XDestroyImage(xi); } END_TEST //C++ SUCKS (no nested functions) gdImagePtr im; FILE *dot; int white; int red; void draw_nodes(graph_t *g, node_t *n) { position_t *p = (position_t*)n->data; gdImageSetPixel(im, p->x, p->y, white); } void draw_edges(graph_t *g, edge_t *e) { position_t *p1 = (position_t*)(e->n1->data); position_t *p2 = (position_t*)(e->n2->data); gdImageLine(im, p1->x, p1->y, p2->x, p2->y, red); } void graph_edges(graph_t *g, edge_t *e) { position_t *p1 = (position_t*)(e->n1->data); position_t *p2 = (position_t*)(e->n2->data); fprintf(dot, "\"%d-%d\" -- \"%d-%d\";\n", p1->x, p1->y, p2->x, p2->y); } void do_it(char *dump_file, char *picture, char *dotfile, pixel_t pill_color, pixel_t wall_color, unsigned int exp_nodes, unsigned int exp_edges) { XImage *xi; /* Load level1 image dump */ FILE *f = fopen(dump_file, "r"); xi = x_imagedump_load(f); fclose(f); position_t pos = {0, 20}; level_t *lev = level_create(xi, pill_color, wall_color, pos); fail_if(lev == NULL, "Unable to guess level"); fail_if(lev->graph->edge_count != exp_edges, "Edge count is wrong : %d (expected = %d)", lev->graph->edge_count, exp_edges); fail_if(lev->graph->node_count != exp_nodes, "Edge count is wrong : %d (expected = %d)", lev->graph->node_count, exp_nodes); /* Create a picture to test result */ FILE *pngout; im = gdImageCreate(xi->width, xi->height); /* Free XDump picture */ XDestroyImage(xi); int black = gdImageColorAllocate(im, 0, 0, 0); white = gdImageColorAllocate(im, 255, 255, 255); red = gdImageColorAllocate(im, 255, 0, 0); graph_edge_visit(lev->graph, draw_edges); graph_node_visit(lev->graph, draw_nodes); pngout = fopen(picture, "wb"); gdImagePng(im, pngout); fclose(pngout); gdImageDestroy(im); /* Generate a DOT file */ dot = fopen(dotfile, "w"); fprintf(dot, "graph Level {\n"); graph_edge_visit(lev->graph, graph_edges); fprintf(dot, "}"); fclose(dot); } START_TEST(test_guess) { printf("Testing level1..."); do_it("level1.dump", "level1.png", "level1.dot", x_pixel_from_rgb(222, 222, 222), x_pixel_from_rgb(255, 0, 0), 66, 88 ); printf("ok!\n"); printf("Testing level2..."); do_it("level2.dump", "level2.png", "level2.dot", x_pixel_from_rgb(255, 255, 0), x_pixel_from_rgb(222, 222, 222), 72, 92); printf("ok!\n"); printf("Testing level3..."); do_it("level3.dump", "level3.png", "level3.dot", x_pixel_from_rgb(255, 0, 0), x_pixel_from_rgb(222, 222, 222), 82, 105); printf("ok!\n"); } END_TEST /* Test suite for "Check" */ Suite *level_suite() { Suite *s = suite_create("level"); TCase *tc_core = tcase_create("Core"); /* Add tests here */ tcase_add_test(tc_core, test_guess); //tcase_add_test(tc_core, test_beam); //tcase_add_test(tc_core, test_goto_edge); suite_add_tcase(s, tc_core); } int main() { int number_failed; Suite *s = level_suite (); SRunner *sr = srunner_create (s); srunner_run_all (sr, CK_NORMAL); number_failed = srunner_ntests_failed (sr); srunner_free (sr); return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; }