#include #include #include #include typedef struct Point Point; /* eschew igo.h */ typedef struct Move Move; struct Point { int x; int y; }; struct Move { Point; char type; }; Move* parsepos(char *s) { Move *pos; char *coord[2]; char *end, *cs; int i; if(getfields(s, coord, 2, 0, ",") < 2) return nil; for(i=0; i<2; i++){ cs = coord[i]; strtoul(cs, &end, 10); /* thanks Tim */ if(end == cs || (*end != 0 && *end != '\n')) return nil; } pos = malloc(sizeof *pos); pos->x = atoi(coord[0]); pos->y = atoi(coord[1]); return pos; } int readop(char t, int fd, char *s, int nb, Channel *c) { Move *pos; int ret; ret = read(fd, s, nb); if(filectl->ev){ /* don't redraw if hand-placed */ filectl->ev=0; return ret; } pos = parsepos(s); if(!pos) return ret; pos->type = t; send(c, &pos); return ret; } void /* thanks Uriel */ readproc(void *a) { Filectl *fc; Channel *c; char *s; int nb; int n=1, i=1; threadsetname("readproc"); fc = a; c = fc->c; nb = 10*(sizeof *s); s = mallocz(nb, 1); while(n > 0){ if(i){ if(fc->self || fc->ro){ fc->p = 'B'; fc->op = 'W'; } fc->r = 'B'; n = readop(fc->r, fc->B, s, nb, c); i = 0; continue; } if(fc->self){ fc->p = 'W'; fc->op = 'B'; } fc->r = 'W'; n = readop(fc->r, fc->W, s, nb, c); i = 1; } close(fc->B); close(fc->W); free(s); free(fc); } Filectl* initfile(char *file, char *player, int ro) { Filectl *fc; char p, op; int self; int fd, ofd; int n; n = strlen(file); p = 'B'; self=0; if(!player) self=1; else p=player[0]; /* already checked */ op = (p=='B') ? 'W' : 'B'; file[n-1] = p; if(ro) fd = open(file, OREAD); else fd = open(file, ORDWR); file[n-1] = op; if(self && !ro) ofd = open(file, ORDWR); else ofd = open(file, OREAD); if(fd < 0 || ofd < 0) sysfatal("open: %r"); fc = malloc(sizeof *fc); fc->ro = ro; fc->self = self; fc->p = p; fc->op = op; fc->B = (p=='B') ? fd : ofd; fc->W = (p=='B') ? ofd : fd; fc->c = chancreate(sizeof(Move*), 0); proccreate(readproc, fc, Stacksz); return fc; }