Talk:Wireworld/C
Code replacement
Proposing to replace C code with new code below, depending on if there are objections. Reason: new code is more functional.
This is still using OpenGL and glut. Hotkeys: "+"/"-" zoom, arrow keys: pan, ">" and "<": increase/decrease speed; space: pause; "q"/Esc: quit. <lang C>#include <stdio.h>
- include <stdlib.h>
- include <unistd.h>
- include <string.h>
- include <math.h>
- include <sys/stat.h>
- include <fcntl.h>
- include <GL/glut.h>
enum { empty = 0, head, tail, conductor, };
int gwin, width = 0, height = 0; int win_w, win_h; int off_x = 0, off_y = 0; int paused = 1; long sleep_time = 1L << 18;
unsigned char **cells, **cell_bak; unsigned long non_empty = 0; unsigned long zoom = 1;
int clamp(int x, int min, int max) { if (x < min) x = min; if (x >= max) x = max - 1; return x; }
void render() { int i, j; double x0, x1, y0, y1; double cx, cy; if (zoom <= 0) zoom = 1; if (win_w > width * zoom) off_x = 0; cx = off_x + width / 2.; if (win_h > height* zoom) off_y = 0; cy = off_y + height/ 2.; double ex0 = cx - win_w / 2. / zoom, ex1 = cx + win_w / 2. / zoom; double ey0 = cy - win_h / 2. / zoom, ey1 = cy + win_h / 2. / zoom; int i0 = floor(ex0), i1 = floor(ex1), j0 = floor(ey0), j1 = floor(ey1); i0 = clamp(i0, 1, width - 1); i1 = clamp(i1, 1, width - 1); j0 = clamp(j0, 1, height - 1); j1 = clamp(j1, 1, height - 1);
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity(); glOrtho(ex0, ex1, ey1, ey0, -1, 1); for (i = i0; i <= i1; i++) { x0 = i; if (x0 > win_w) continue; x1 = (i + 1); if (x1 < 0) continue; for (j = j0; j <= j1; j++) { if (cells[j][i] == empty) continue;
y0 = j; if (y0 >= win_h) continue; y1 = (j + 1); if (y1 < 0) continue;
switch(cells[j][i]) { case head: glColor3ub(255, 0, 0); break; case tail: glColor3ub(0, 128, 255); break; default: glColor3ub(40, 80, 0); break; } glRectd(x0, y0, x1, y1); } } glFlush(); }
void evolve() { int i, j, l, cnt; int offsets[][2] = {{1, 1}, {1, -1}, {-1, 1}, {-1, -1}, {0, 1}, {0, -1}, {1, 0}, {-1, 0}}; if (paused) goto skip; memcpy(cell_bak[0], cells[0], sizeof(unsigned char) * width * height); for (i = 1; i < height - 1; i++) { for (j = 1; j < width - 1; j++) { switch(cell_bak[i][j]) { case tail: cells[i][j] = conductor; break; case head: cells[i][j] = tail; break; case conductor: cnt = 0; for (l = 0; l < 8; l++) { cnt += (cell_bak[i + offsets[l][0]][j + offsets[l][1]] == head); if (cnt > 2) break; } if (cnt ==1 || cnt == 2) cells[i][j] = head; } } } render(); skip: if (sleep_time) usleep(sleep_time); }
void resize(int w, int h) { win_w = w; win_h = h; glViewport(0, 0, w, h); render(); }
void handle_key(unsigned char key, int x, int y) { switch(key) { case 'q': case '\033': glFinish(); glutDestroyWindow(gwin); return; case '+': case '=': zoom ++; break; case '-': case '_': zoom --; break; case ' ': paused = !paused; break; case '>': case '.': sleep_time /= 2; break; case '<': case ',': sleep_time *= 2; if (!sleep_time) sleep_time = 1; break; } render(); }
void handle_special(int key, int x, int y) { switch(key) { case GLUT_KEY_LEFT: off_x -= 1; break; case GLUT_KEY_RIGHT: off_x += 1; break; case GLUT_KEY_UP: off_y -= 1; break; case GLUT_KEY_DOWN: off_y += 1; break; } render(); }
int read_file(char * fn) { struct stat st; char *buf, *ptr; int i, j, line_len;
int fd = open(fn, O_RDONLY); if (fd == -1) return 0; fstat(fd, &st);
ptr = buf = malloc(st.st_size + 1); read(fd, buf, st.st_size); buf[st.st_size] = '\0'; close(fd);
height = width = line_len = 0; while (*ptr != '\0') { switch(*ptr) { case '\n': if (width < line_len) width = line_len; line_len = 0; height ++; break; case 't': case 'H': case ' ': case '.': non_empty++; line_len++; break; default: fprintf(stderr, "bad char %d at line %d, %d\n", *ptr, height + 1, line_len); } ptr++; } printf("%lu non empty cells\n", non_empty); height += 2; width += 2; cells = malloc(sizeof(unsigned char*) * height); cell_bak = malloc(sizeof(unsigned char*) * height); cells[0] = calloc(sizeof(unsigned char), width * height); cell_bak[0] = calloc(sizeof(unsigned char), width * height); for (i = 1; i < height; i++) { cells[i] = cells[i - 1] + width; cell_bak[i] = cell_bak[i - 1] + width; }
ptr = buf; i = j = 1; while (*ptr != '\0') { switch(*(ptr++)) { case '\n': i++; j = 1; continue; case 't': cells[i][j++] = tail; continue; case 'H': cells[i][j++] = head; continue; case '.': cells[i][j++] = conductor; continue; default: j++; } }
return 1; }
int main(int c, char **v) { glutInit(&c, v); if (c <= 1) { fprintf(stderr, "usage: %s filename\n", v[0]); return 0; }
if (!read_file(v[1])) exit(1);
glutInitWindowPosition(-1, -1);
win_w = width; win_h = height; if (win_w < 300) win_w = 300; if (win_h < 200) win_h = 200; glutInitWindowSize(win_w, win_h); glutInitDisplayMode(GLUT_RGB|GLUT_DEPTH); gwin = glutCreateWindow("Wireworld"); glutKeyboardUpFunc(handle_key); glutSpecialFunc(handle_special); glutDisplayFunc(render); glutReshapeFunc(resize); glutIdleFunc(evolve); glLoadIdentity(); glutMainLoop(); return 0; }</lang>
Replace or not, here are some more test files:
.................. ......................... . . . . ................ . ... ...... .......... . . . . . . ................ ... . . . .......... . . . . . . ..Ht................ . .. . .. . ........ . . ... . . . .................... . . . . . . . ..... . . . ... . . . . . . . .................... . . . . . . . . . . . . . . . . .... . . . . ... ... . . . .. . . . . . . .. ... . ................... ... .... . . . .. . . . . . . . . . . ........................... . ... . . . . . . . . ............................. .. . . . . . . . . . ......................tH....tH . . ... ... . . . . . ...................tH..........tH. .. ... . . . . . ......................................... . . . . . . . . . ........ ....... ........ . . . . . . . . . . . . . ... tH . ... ........ . . . . . . . . . . . . . . . . . .. .. . . ... . . . . . . . . . .... . . . . . . . . .... . . . . . . . . . . . . ... . . . . . .... . . . . . . . . ... ... . .... . . . . . . . . .. .. . . . . . . . . . . . ..... . . ... . . . . . . . . . . . ... . . . . . . . . . . . . . . ... . . ... . . . . . . . .. .. . . . .. . . . . .... . . . . . . . . . . . . . ... .. . . . .... . . . . .t ... . . . . ..... . . . . . . H. . . . . . .... . . . .. .. . . . . . . . . . ......... .............. . . . .....................................
and one from a gif file from WP:
......................... ........................... . . . ........................... . .... ................................. . . . . . ................................. . . . . . ........................... . . . . .. .. . . .. .. . . . . . ........................... . . . . . . .. .. . ......................... . .. .. . . .. .. .. .. .. .. .. .. . .. .. .. .. .. .. .. .. . .. .. .. .. .. .. .. .. . .. .. .. .. .. .. .. .. . .. .. .. .. .. .. .. .. . .. .. .. .. .. .. .. .. . .. .. .. .. .. .. .. .. . .. .. .. .. .. .. .. .. . .. .. .. .. .. .. .. .. . .. .. .. .. .. .. .. .. . .. .. .. .. .. .. .. .. . .. .. .. .. .. .. .. .. . .. .. .. .. .. .. .. .. . .. .. .. .. .. .. .. .. . .. .. .. .. .. .. .. .. . .. .. .. .. .. .. .. .. . .. .. .. .. .. .. .. .. . .. .. .. .. .. .. .. .. . .. .. .. .. .. .. .. .. . .. .. .. .. .. .. .. .. . .. .. .. .. .. .. .. .. . .. .. .. .. .. .. .. .. . .. .. .. .. .. .. .. .. . .. .. .. .. .. .. .. .. . .. .. .. .. .. .. .. .. . . .. .. . ......................... . .. .. . . . . . . ........................... . . . . . . . . . . ...... . . ........................... . . . . . . ................................. .. . . ....... . ... ... . . ....... ................................. .. . . . .... . . ........................... . . ... . . . . . . . . . . . . . . . . ........................... . . . . . . . . . .. .. . ......................... . .. .. . . . . . .. .. .. .. .. .. .. .. . . . . .. .. .. .. .. .. .. .. . . . . .. .. .. .. .. .. .. .. . . . . .. .. .. .. .. .. .. .. . . . . .. .. .. .. .. .. .. .. . . . . .. .. .. .. .. .. .. .. . . . . .. .. .. .. .. .. .. .. . . . . .. .. .. .. .. .. .. .. . . . . .. .. .. .. .. .. .. .. . . . . .. .. .. .. .. .. .. .. . . . . .. .. .. .. .. .. .. .. . . . . .. .. .. .. .. .. .. .. . . . . .. .. .. .. .. .. .. .. . . . . .. .. .. .. .. .. .. .. . . . . .. .. .. .. .. .. .. .. . . . . .. .. .. .. .. .. .. .. . . . . .. .. .. .. .. .. .. .. . . . . .. .. .. .. .. .. .. .. . . . . .. .. .. .. .. .. .. .. . . . . .. .. .. .. .. .. .. .. . . . . .. .. .. .. .. .. .. .. . . . . .. .. .. .. .. .. .. .. . . . . .. .. .. .. .. .. .. .. . . . . .. .. .. .. .. .. .. .. . . . . .. .. .. .. .. .. .. .. . . . . . .. .. . ......................... . .. .. . . . . . . . . . ........................... . . . . . . . . .. .. . . .. .. . . . . . . . ........................... . . . . . . . . ................................. . . . . . . . . . . . . . . ................................. . . . . . . . . ........................... . . . . . . . . . . . . . . . . . ........................... . . . . . . . ......................... . . . . . . . . . . . . . ....... . . . . . . . . . . . . . .. . .. .. . . . . . . . . . . . . . .. . . . . ... . ... . . ... . . . ... . . . . . . . . . . . . ... ... ... . . . . . . . . . . . .... . . . .. . . . ... . . . . . . . . . . . . . ... . . . . . . . . . . . .... . . . ... . . . . . . . . .. . . .. .. . . . . . . . . . ... . . . . . . ... . . . . . . . . . . . .... .... . . . ... . . . . . . . . . .. . .. .. .. .. . . . . . . . . ... . . ... . . . . . . ... . . . . . . . . . . . .... .... ..... . . . ... . . . . . . . . . . .. .. .. .. .. .. . . . . . ... . . ... . . ... . . . . . . . . . . . . . . . . .... ..... . .... .... . . . . . . . . . . . . . . .. .. .. .. .. .. .. .. . . . . ... . . ... . . ... . . ... . . . . . . . . . . . . . . . . .... .... ..... .... .... . . . . . . . . . . . . . . .. .. .. .. .. .. .. .. .. .. . . . ... . . ... . . ... . . ... . . ... . . . . . . . . . . . . . . . . ..... .... .... ..... .... .... . . . . . . . . . . . . . . . .. .. .. .. .. .. .. .. .. .. .. .. . . . . ... . . ... . . ... . . ... . . ... . . ... . . . . . . . . . . . . . . . . . . . . . .... .... ..... .... .... .... .... . ... . . . . . . . . . . . . . . . ... . .. .. .. .. .. .. .. .. .. .. .. .. .. ... . . . . ... . . ... . . ... . . ... . . ... . . ... . . ... . . . . . . . . . . . . . . . . . . . . . . . . .... ..... ..... .... .... ..... .... . ... . . . . . . . . . . . . . . . . . ... . . . .. .. .. .. .. .. .. .. .. .. .. .. .. ... . . . . . ... . . ... . . ... . . ... . . ... . . ... . . ... . . . . . ... . . . . . . . . . . . . . . . . . . . H ..... ..... ..... ..... .... .... .... . ... . . t . . . . . . . . . . . . . . . ... . . . . .. .. .. .. .. .. .. .. .. .. .. .. .. ... . . . . . . ... . . ... . . ... . . ... . . ... . . ... . . ... . . . . . ... . . . . . . . . . . . . . . . . . . . . . . .... ..... .... .... .... .... ..... . ... . . H H . . . . . . . . . . . . . . . ... . . . t .. .. .. .. .. .. .. .. .. .. .. .. .. ... . . . . . ... . . ... . . ... . . ... . . ... . . ... . . ... . . . . . ... . . . . . . . . . . . . . . . . . . . . .... ..... .... .... .... ..... . ... . . . . . . . . . . . . . . . . . ... . . . H .. .. .. .. .. .. .. .. .. .. .. ... . . . . t ... . . ... . . ... . . ... . . ... . . ... . . . . . ... . . . . . . . . . . . . . . . . . . .... ..... ..... .... .... . ... . . . . . . . . . . . . . . . ... . . . . .. .. .. .. .. .. .. .. .. ... . . . . H ... . . ... . . ... . . ... . . ... . . . . . ttt t . . . . . . . . . . . . . . . .... .... .... .... . ... . . . . . . . . . . . . . ... . . . . .. .. .. .. .. .. .. ... . . . . . ... . . ... . . ... . . ... . . . . . HHH H . . . . . . . . . . . t t .... ..... .... . ... . . . . . . . . . . . ... . . . . .. .. .. .. .. ... . . . . . ... . . ... . . ... . . . . . ... . . . . . . . . . . H H ..... .... . ... . . t t . . . . . ... . . . . .. .. .. ... . . . . . ... . . ... . . . . . ... . . . . . . . . . . .... . ... . . H H . . t ttt . . . t .. ..H . . . . . ... . t . . ... . . H . . . . ... ... . . . . . . . . . H . . . . . t ... . ... . . . .. . . . . . H . . . . t . . . .. .. H . . . t . . . HHH .. . . . . . .... . . . . . . . . . . . . . . . . . . . ................................................... . ....................................................
- I'd recommend having both, for side-by-side comparison of programming in C in a functional style vs (whatever is there) --Michael Mol 15:01, 6 July 2011 (UTC)
- Er no, "functional" as in "usable", not as in "like Haskell or whatever". I'm not happy withe the existing code because it missed quite some easily implemented functionalities. --Ledrug 15:08, 6 July 2011 (UTC)