#include <u.h>
#include <libc.h>
#include <thread.h>
#include <chan.h>
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;
}
|