/* * Turing -- A simple two-dimensional turing machine. * * Written by Steven T. McClure @ University of New Hampshire, 1989 * * This program can be distributed freely in any non-commercial * environment, and can be used in no way for a profit by anyone * (except me, of course :) ), and can be modified in any way that * you like. I take no responsibility for the readablness of this * code (or this comment, for that matter :) ), the correctness of * this code, or any damages occuring from the use of this code. * Have fun with it, I know I did. */ /* * This program uses the screen as a 'tape' for a two-dimensional * turing machine. Instructions for use are in 'turing.inf'. */ /* * 4 colors in 320X200 mode (0x04), 2 colors in 640X400 mode (0x42) * This was developed on an AT&T6300, so these were the only two * choices in set_scr. To set a different video mode, just replace * RUN_VID with your choice of video, as the program makes no check * of screen boundaries. */ #include #include #define RUN_VID 0x04 /* Video to use during run-time */ #define END_VID 0x02 /* Video to reset to after run */ #define BLACK 0 /* GUESSES FOR THESE */ #define GREEN 1 /* These are probably different */ #define BLUE 2 /* for their real color, but on a */ #define RED 3 /* monochrome monitor, it doesn't */ /* matter. If the real values are */ /* discovered and changed for the */ /* system being used, the values in */ /* 'turing.doc' should be changed */ /* also. */ /* Also, other colors can be added */ /* eaisly by just defining them */ /* here, as they are used nowhere */ /* in the program, just as a guide */ /* to actual colors. */ #define UP 0 /* Physical directions to move */ #define RGT 2 #define DOWN 4 #define LFT 6 #define LEFT 10 /* Turn and move directions */ #define RIGHT 20 #define FORWARD 30 #define STAY 40 #define BACKUP 50 struct tape { int t_lin; int t_col; int t_dir; int t_state; int t_color; } tp; struct state { int s_got; int s_paint; int s_dirgo; int s_sgo; struct state *s_prev; struct state *s_next; }; struct list { int l_state; struct state *l_first; struct state *l_last; struct list *l_prev; struct list *l_next; }; struct list *firstlist; struct list *lastlist; struct tape t; typedef union REGS REGS; main(argc, argv) int argc; char *argv[]; { REGS r; REGS or; char c; int tmp; if (argc < 2) { printf("Usage: turing [ file ] ...\n"); exit(0); } read_tuples(argv[1]); set_scr(2); putdot(tp.t_lin, tp.t_col, tp.t_color); do { do_turing(); c = getch(); } while (c == 'r' || c == 'R'); set_scr(1); } do_turing() { struct list *l; struct state *s; int color; while (!kbhit()) { color = getdot(tp.t_lin, tp.t_col); for (l = firstlist; l; l = l->l_next) if (l->l_state == tp.t_state) break; if (!l) break; for (s = l->l_first; s; s = s->s_next) if (color == s->s_got) break; if (!s) break; putdot(tp.t_lin, tp.t_col, s->s_paint); if (s->s_dirgo == RIGHT) tp.t_dir = (tp.t_dir + 2 > 6 ? 0 : tp.t_dir + 2); else if (s->s_dirgo == LEFT) tp.t_dir = (tp.t_dir - 2 < 0 ? tp.t_dir + 6 : tp.t_dir - 2); else if (s->s_dirgo == BACKUP) tp.t_dir = (tp.t_dir - 4 < 0 ? tp.t_dir + 4 : tp.t_dir - 4); if (s->s_dirgo != STAY) { if (tp.t_dir == UP) tp.t_lin = (tp.t_lin - 1 < 0 ? 0 : tp.t_lin - 1); else if (tp.t_dir == DOWN) tp.t_lin = (tp.t_lin + 1 > 199 ? 199 : tp.t_lin + 1); else if (tp.t_dir == LFT) tp.t_col = (tp.t_col - 1 < 0 ? 0 : tp.t_col - 1); else if (tp.t_dir == RGT) tp.t_col = (tp.t_col + 1 > 319 ? 319 : tp.t_col + 1); else break; } if (s->s_dirgo == BACKUP) tp.t_dir = (tp.t_dir - 4 < 0 ? tp.t_dir + 4 : tp.t_dir - 4); tp.t_state = s->s_sgo; } getch(); } read_tuples(str) char *str; { struct state *s; struct list *l; FILE *fp; int cstate; int godir; int gotcol; int paint; int gostate; if ((fp = fopen(str, "r")) == NULL) { printf("Cannot open '%s' for reading.\n", str); exit(-1); } fscanf(fp, "%d %d %d %d %d\n", &tp.t_state, &tp.t_lin, &tp.t_col, &tp.t_dir, &tp.t_color); while (!feof(fp)) { fscanf(fp, "%d %d %d %d %d\n", &cstate, &gotcol, &paint, &godir, &gostate); for (l = firstlist; l; l = l->l_next) if (cstate == l->l_state) break; if (!l) { l = malloc(sizeof(struct list)); l->l_prev = firstlist; l->l_next = 0; if (!firstlist) firstlist = l; if (lastlist) lastlist->l_next = l; lastlist = l; l->l_first = 0; l->l_last = 0; l->l_state = cstate; } s = malloc(sizeof(struct state)); s->s_prev = l->l_first; s->s_next = 0; if (!l->l_first) l->l_first = s; if (l->l_last) l->l_last->s_next = s; l->l_last = s; s->s_got = gotcol; s->s_paint = paint; s->s_dirgo = godir; s->s_sgo = gostate; } fclose(fp); } int getdot(x, y) int x; int y; { REGS r; REGS or; r.h.ah = 0x0D; r.h.bh = 0; r.x.cx = y; r.x.dx = x; int86(0x10, &r, &or); return (int)or.h.al; } putdot(x, y, color) int x; int y; int color; { REGS r; REGS or; r.h.ah = 0x0C; r.h.al = color; r.h.bh = 0; r.x.cx = y; r.x.dx = x; int86(0x10, &r, &or); } set_scr(x) int x; { REGS r; REGS or; if (x == 1) { r.h.ah = 0x00; r.h.al = END_VID; int86(0x10, &r, &or); } else if (x == 2) { r.h.ah = 0x00; r.h.al = RUN_VID; int86(0x10, &r, &or); } }