#include #include #include using namespace std; #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) { cell *maze; int rows, cols; int r, c, index, i, j; int basecolor, cellcolor; int expand; string line, word; vector fields; int linenum=0; 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); } } maze = NULL; // Read in the maze file. while (getline(cin, line)) { //read each line of input linenum++; fields.clear(); i=0; while (i < line.length()) { //put fields of line into a vector of strings while (i 0) fields.push_back(word); } if (fields.size() > 0) { if (fields[0] == "MAZE") { if (fields.size() != 4 || fields[2] != "X") { fprintf(stderr, "Line %d: MAZE line should be 'MAZE rows X cols'\n", linenum); exit(1); } if (sscanf(fields[1].c_str(), "%d", &rows) != 1 || rows <= 0) { fprintf(stderr, "Line %d: MAZE line should be 'MAZE rows X cols'\n", linenum); exit(1); } if (sscanf(fields[3].c_str(), "%d", &cols) != 1 || rows <= 0) { fprintf(stderr, "Line %d: MAZE line should be 'MAZE rows X cols'\n", linenum); exit(1); } if (maze != NULL) { fprintf(stderr, "Line %d: file should have only one MAZE line\n", linenum); 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 (fields[0] == "CELL") { if (maze == NULL) { fprintf(stderr, "Line %d: No MAZE line.\n", linenum); exit(1); } if (fields.size() < 3 || fields.size() > 7) { fprintf(stderr, "Line %d: CELL line should be 'CELL r c [T B L R]'\n", linenum); exit(1); } if (sscanf(fields[1].c_str(), "%d", &r) != 1 || sscanf(fields[2].c_str(), "%d", &c) != 1) { fprintf(stderr, "Line %d: CELL line should be 'CELL r c [T B L R]'\n", linenum); exit(1); } if (r < 0 || r >= rows) { fprintf(stderr, "Line %d: bad row number\n", linenum); exit(1); } if (c < 0 || c >= cols) { fprintf(stderr, "Line %d: bad column number\n", linenum); exit(1); } index = r * cols + c; for (i = 3; i < fields.size(); i++) { if (fields[i] == "L") { maze[index].left = 1; } else if (fields[i] == "R") { maze[index].right = 1; } else if (fields[i] == "T") { maze[index].top = 1; } else if (fields[i] == "B") { maze[index].bottom = 1; } else { fprintf(stderr, "Line %d: CELL line should be 'CELL r c [T B L R]'\n", linenum); 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 (fields[0] == "PATH") { if (maze == NULL) { fprintf(stderr, "Line %d: No MAZE line.\n", linenum); exit(1); } if (fields.size() != 3) { fprintf(stderr, "Line %d: PATH line should be 'PATH r c'\n", linenum); exit(1); } else if (sscanf(fields[1].c_str(), "%d", &r) != 1 || sscanf(fields[2].c_str(), "%d", &c) != 1) { fprintf(stderr, "Line %d: PATH line should be 'PATH r c'\n", linenum); exit(1); } if (r < 0 || r >= rows) { fprintf(stderr, "Line %d: bad row number\n", linenum); exit(1); } if (c < 0 || c >= cols) { fprintf(stderr, "Line %d: bad column number\n", linenum); exit(1); } maze[r*cols+c].on = 1; } else if (fields[0][0] == '#') { } else { fprintf(stderr, "Line %d: Lines should be MAZE or CELL\n", linenum); exit(1); } } } //end while loop that reads lines of input 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); }