#include #include "Fields.h" #define EXPAND (10) class cell { public: int left; int right; int top; int bottom; int on; }; #define WHITE (0) #define BLACK (1) #define CYAN (2) #define YELLOW (3) unsigned char *Pixmap; int PixI = 0; void addpix(int color) { int r, g, b; if (color == WHITE) { r = 255; b = 255; g = 255; } else if (color == BLACK) { r = 0; b = 0; g = 0; } else if (color == CYAN) { r = 0; b = 255; g = 255; } else if (color == YELLOW) { r = 255; g = 255; b = 0; } else { fprintf(stderr, "Bad color: %d\n", color); exit(1); } Pixmap[PixI++] = r; Pixmap[PixI++] = g; Pixmap[PixI++] = b; } main(int argc, char **argv) { Fields *f; cell *maze; int rows, cols; int r, c, index, i, j; int basecolor, cellcolor; int expand; if (argc > 2) { fprintf(stderr, "usage: maztoppm [expansion]\n"); exit(1); } if (argc == 1) { expand = EXPAND; } else if (argc == 2) { i = sscanf(argv[1], "%d", &expand); if (i == 0 || expand < 3) { fprintf(stderr, "usage: maztoppm [expansion]\n"); fprintf(stderr, " expansion must be >= 3\n"); exit(1); } } f = new Fields(); maze = NULL; // Read in the maze file. while (f->get_line() >= 0) { if (f->get_NF() > 0) { if (f->get_field(0) == "MAZE") { if (f->get_NF() != 4 || f->get_field(2) != "X") { fprintf(stderr, "Line %d: MAZE line should be 'MAZE rows X cols'\n", f->get_line_number()); exit(1); } if (sscanf(f->get_field(1).c_str(), "%d", &rows) != 1 || rows <= 0) { fprintf(stderr, "Line %d: MAZE line should be 'MAZE rows X cols'\n", f->get_line_number()); exit(1); } if (sscanf(f->get_field(3).c_str(), "%d", &cols) != 1 || rows <= 0) { fprintf(stderr, "Line %d: MAZE line should be 'MAZE rows X cols'\n", f->get_line_number()); exit(1); } if (maze != NULL) { fprintf(stderr, "Line %d: file should have only one MAZE line\n", f->get_line_number()); exit(1); } maze = new cell[rows*cols]; for (i = 0; i < rows*cols; i++) { maze[i].left = 0; maze[i].right = 0; maze[i].top = 0; maze[i].bottom = 0; maze[i].on = 0; } } else if (f->get_field(0) == "CELL") { if (maze == NULL) { fprintf(stderr, "Line %d: No MAZE line.\n", f->get_line_number()); exit(1); } if (f->get_NF() < 3 || f->get_NF() > 7) { fprintf(stderr, "Line %d: CELL line should be 'CELL r c [T B L R]'\n", f->get_line_number()); exit(1); } if (sscanf(f->get_field(1).c_str(), "%d", &r) != 1 || sscanf(f->get_field(2).c_str(), "%d", &c) != 1) { fprintf(stderr, "Line %d: CELL line should be 'CELL r c [T B L R]'\n", f->get_line_number()); exit(1); } if (r < 0 || r >= rows) { fprintf(stderr, "Line %d: bad row number\n", f->get_line_number()); exit(1); } if (c < 0 || c >= cols) { fprintf(stderr, "Line %d: bad column number\n", f->get_line_number()); exit(1); } index = r * cols + c; for (i = 3; i < f->get_NF(); i++) { if (f->get_field(i) == "L") { maze[index].left = 1; } else if (f->get_field(i) == "R") { maze[index].right = 1; } else if (f->get_field(i) == "T") { maze[index].top = 1; } else if (f->get_field(i) == "B") { maze[index].bottom = 1; } else { fprintf(stderr, "Line %d: CELL line should be 'CELL r c [T B L R]'\n", f->get_line_number()); exit(1); } } /* printf("%d %d %d %d %d %d\n", r, c, maze[index].left, maze[index].right, maze[index].top, maze[index].bottom); */ } else if (f->get_field(0) == "PATH") { if (maze == NULL) { fprintf(stderr, "Line %d: No MAZE line.\n", f->get_line_number()); exit(1); } if (f->get_NF() != 3) { fprintf(stderr, "Line %d: PATH line should be 'PATH r c'\n", f->get_line_number()); exit(1); } else if (sscanf(f->get_field(1).c_str(), "%d", &r) != 1 || sscanf(f->get_field(2).c_str(), "%d", &c) != 1) { fprintf(stderr, "Line %d: PATH line should be 'PATH r c'\n", f->get_line_number()); exit(1); } if (r < 0 || r >= rows) { fprintf(stderr, "Line %d: bad row number\n", f->get_line_number()); exit(1); } if (c < 0 || c >= cols) { fprintf(stderr, "Line %d: bad column number\n", f->get_line_number()); exit(1); } maze[r*cols+c].on = 1; } else if (f->get_field(0)[0] == '#') { } else { fprintf(stderr, "Line %d: Lines should be MAZE or CELL\n", f->get_line_number()); exit(1); } } } if (maze == NULL) return 0; // Double check to make sure that all cells with shared walls are // correct. index = 0; for (r = 0; r < rows; r++) { for (c = 0; c < cols; c++) { // Check top/bottom if (r > 0 && maze[index-cols].bottom != maze[index].top) { fprintf(stderr, "Cell (%d,%d) top does not match (%d,%d) bottom\n", r, c, r-1, c); exit(1); } // Check left/right if (c > 0 && maze[index].left != maze[index-1].right) { fprintf(stderr, "Cell (%d,%d) left does not match (%d,%d) right\n", r, c, r, c-1); exit(1); } index++; } } // Print it out. printf("P6\n%d %d\n255\n", (cols+2)*expand, (rows+2)*expand); Pixmap = (unsigned char *) malloc(sizeof(unsigned char) * 3*(cols+2)*expand*(rows+2)*expand); index = 0; for (r = -1; r <= rows; r++) { for (i = 0; i < expand; i++) { for (c = -1; c <= cols; c++) { if (r < 0 || r == rows || c < 0 || c == cols) { for (j = 0; j < expand; j++) addpix(YELLOW); } else { cellcolor = (maze[r*cols+c].on) ? CYAN : WHITE; basecolor = ((i == 0 && maze[r*cols+c].top) || (i == (expand-1) && maze[r*cols+c].bottom)) ? BLACK : cellcolor; addpix((maze[r*cols+c].left) ? BLACK : basecolor); for (j = 1; j < expand-1; j++) addpix(basecolor); addpix((maze[r*cols+c].right) ? BLACK : basecolor); } } } } fwrite(Pixmap, sizeof(unsigned char), 3*(cols+2)*expand*(rows+2)*expand, stdout); }